首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++获取对话框控件的位置和大小

C++获取对话框控件的位置和大小
EN

Stack Overflow用户
提问于 2016-06-02 14:54:11
回答 2查看 3K关注 0票数 0

我正在使用Visual 2015 C++,并在..rc文件中定义了一个对话框:

代码语言:javascript
复制
IDD_SERIALCTRLDEMO_DIALOG DIALOGEX 0, 0, 313, 164
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "SerialCtrlDemo"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    LTEXT           "Serial Number:",IDC_STATIC,14,10,48,8
    COMBOBOX        IDC_COMBO_SN,66,8,48,55,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    LTEXT           "Baud Rate:",IDC_STATIC,135,10,37,8
    COMBOBOX        IDC_COMBO_BR,176,8,48,55,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    LTEXT           "Read:",IDC_STATIC,11,51,20,8
    PUSHBUTTON      "Open",IDC_BUTTON_OPEN,242,7,50,14
    LISTBOX         IDC_LIST_READ,11,62,23,76,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
    EDITTEXT        IDC_EDIT_WRITE,11,34,237,14,ES_AUTOHSCROLL
    PUSHBUTTON      "Write",IDC_BUTTON_WR,252,33,46,14
    GROUPBOX        "",IDC_STATIC,7,0,294,25
    GROUPBOX        "",IDC_STATIC,7,26,296,117
    LTEXT           "",IDC_STATIC_INFO,11,150,287,8
    CONTROL         "",IDC_SENSOR,"Static",SS_BLACKRECT,41,62,256,76
END

enter code here

我感兴趣的控件是picturebox "IDC_SENSOR“(最后一项),它被定义为41,62,256,76。但在屏幕上,比例是不同的,可能是由于动态对话框布局。所以我想知道对话框中那个盒子的确切位置和大小,但是我不能得到这些参数。

它所使用的程序:

代码语言:javascript
复制
void CSerialCtrlDemoDlg::OnEventRead(char *inPacket,int inLength)
}
    int x=0;


    m_listboxRead.AddString(inPacket);      // display the incomming data in the 'Read' listbox

    CString str;                    // display the # of data's in 'Info'
    str.Format("%d bytes read",inLength);
    m_staticInfo.SetWindowText(str);

    CWnd *cWndSensor = GetDlgItem(IDC_SENSOR);  // show the fluctuation in the Picturebox 
    CDC *pDC = cWndSensor->GetDC();

    for (x = 0; x < 200; x++)
    {
        pDC->SetPixelV(x, 10, RGB(rand() % 255, 0, 0));
    }
}

应将for-循环中的x<200设置为picturebox的宽度。

我怎样才能得到这些尺寸?

我希望这是足够的信息(?)

你好,CJ。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-02 15:46:58

我感兴趣的控件是picturebox "IDC_SENSOR“(最后一项),它被定义为41,62,256,76。但在屏幕上,比例是不同的,可能是由于动态对话框布局。

是的,没错。对话框资源中的坐标在DLU(对话单元)中指定。您可以通过调用MapDialogRect函数将对话框单元转换为像素。

但这并不是你想要做的,因为你不想硬编码你的代码中的对话框坐标。如果更改资源文件,则希望代码继续工作。

我想知道对话框中那个盒子的确切位置和大小。

真正需要的是获取屏幕上控件的坐标(以像素为单位)。有两个专门为此目的设计的功能:

  • GetClientRect以客户端坐标告诉您窗口的矩形。对于子窗口(如控件),左上角总是(0,0),右下角将告诉您宽度和高度。
  • GetWindowRect以屏幕坐标告诉您窗口的矩形。这些是相对于虚拟屏幕的“绝对”坐标。与客户端矩形不同,窗口矩形还包括窗口的非工作区的大小.

您可能已经知道了,但是这个矩形的宽度是通过从它的右界减去它的左界来确定的。同样,高度是通过从其下界减去其上界来确定的。或者,如果使用MFC包装类CRect (它在任何地方都可以与RECT互换,包括在调用上述两个函数时),则只需调用WidthHeight成员函数即可。

至于您的特殊用例,由于您是在子窗口本身上调用GetDC,所以您将得到一个客户端DC,并且需要客户端坐标,因此您将调用GetClientRect。很简单。只是你的代码错了。您正在获得一个DC并在WM_PAINT消息处理程序之外绘制,这意味着您所绘制的任何内容都会在任意时间间隔内被擦除。所有绘图都应响应WM_PAINT消息。

在您的情况下,实现这一点的一个简单方法是为您的SS_OWNERDRAW控件设置IDC_SENSOR样式。这使父对话框负责绘制控件的内容。当需要绘制子控件时,它将接收WM_DRAWITEM消息。添加一个OnDrawItem处理程序并在其中进行绘图。作为参数传递的DRAWITEMSTRUCT将告诉您应该在其中绘制的矩形(rcItem)。

最后,我应该指出,SetPixelV是相当慢的。如果它对你来说够快的话,就忽略其余的评论吧。但是,如果在屏幕上绘图非常慢,那么您应该考虑创建和缓存位图对象。绘制到该位图中,设置其各个像素,然后将该位图简单地删除到控件的设备上下文中。访问和操作屏幕外位图的单个像素要快得多。

票数 0
EN

Stack Overflow用户

发布于 2016-06-06 09:13:31

我用GetClientRect检索了详细信息:

代码语言:javascript
复制
void CSerialCtrlDemoDlg::OnEventRead(char *inPacket,int inLength)

    {
        int i = 0;
        int j = 0;
        int x = 0;
        int y = 0;
        int w = 100;
        int h = 50;

        RECT sensorRect;

        CWnd *cWndSensor = GetDlgItem(IDC_SENSOR);
        CDC *pDC = cWndSensor->GetDC();

        cWndSensor->GetClientRect(&sensorRect);

        x = sensorRect.left;
        y = sensorRect.top;
        w = sensorRect.right - x;
        h = sensorRect.bottom - y;


        for (i = 0; i < w; i++)    // this fills the picturebox (for test only)
        {
            for (j = 0; j < h; j++)
            {
                pDC->SetPixelV(i, j, RGB(rand() % 255, 0, 0));
            }

        }
    }

所以我把这个问题记下来!

我不太确定这是不是‘正确’的方式,我缺乏经验。但是它可以工作,然后它应该是相当好的:)

我将按照建议使用位图,而不是(直接)绘制到picturebox中。这确实更好,也更容易使用。

我现在需要发现的是,如何用位图正确地更新对话框。正如科迪所说,这种绘图不应该在这个例程中完成,而是作为一个单独的OnDrawItem指令来处理。嗯,要学的更多了。

Thanx和greetins,CJ

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37595306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档