簡體   English   中英

C ++獲取對話框控件的位置和大小

[英]C++ Get the position and size of a dialog control

我正在使用Visual Studio 2015 C ++,並在.rc文件中定義了一個對話框:

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

我感興趣的控件是圖片框“ IDC_SENSOR”(最后一個條目),其定義為41,62,256,76。 但是在屏幕上,比例可能有所不同,這可能是由於“動態對話框布局”所致。 因此,我想知道對話框中該框的確切位置和大小,但是我無法獲取這些參數。

它用於以下過程:

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應該設置為圖片框的寬度。

如何獲得這些尺寸?

我希望這是足夠的信息(?)。

問候,CJ。

我感興趣的控件是圖片框“ IDC_SENSOR”(最后一個條目),其定義為41,62,256,76。 但是在屏幕上,比例可能有所不同,這可能是由於“動態對話框布局”所致。

對,那是正確的。 對話框資源中的坐標以DLU(對話單位)指定。 您可以通過調用MapDialogRect函數將對話框單位轉換為像素。

但這並不是您真正想要的,因為您不想在代碼中對對話框坐標進行硬編碼。 如果更改資源文件,則希望代碼繼續工作。

我想知道對話框中該框的確切位置和大小

您真正需要的是獲取屏幕上控件的坐標(以像素為單位)。 為此專門設計了兩個功能:

  • GetClientRect告訴您客戶端坐標中窗口的矩形。 對於子窗口(例如控件),左上角始終為(0,0),而右下角將告訴您寬度和高度。
  • GetWindowRect告訴您屏幕坐標中的窗口矩形。 這些是相對於虛擬屏幕的“絕對”坐標。 與客戶矩形不同,窗口矩形還包括窗口非客戶區域的大小。

您可能已經知道這一點,但是此矩形的寬度是通過從其右邊界減去其左邊界來確定的。 類似地,通過從其底部邊界減去其頂部邊界來確定高度。 或者,如果使用MFC包裝器類CRect (可在所有地方與RECT互換,包括調用上述兩個函數時),則可以僅調用WidthHeight成員函數。

至於您的特定用例,由於您是在子窗口本身上調用GetDC ,因此您將獲得一個客戶端DC,並且需要客戶端坐標,因此您將調用GetClientRect 簡單。 除了您的代碼是錯誤的。 您將在WM_PAINT消息處理程序之外獲得DC和繪畫,這意味着您繪畫的任何內容都會以任意間隔被擦除。 應響應WM_PAINT消息完成所有繪圖。

在您的情況下,完成此操作的一種簡單方法是為IDC_SENSOR控件設置SS_OWNERDRAW樣式。 這使父對話框負責繪制控件的內容。 當需要繪制子控件時,它將接收WM_DRAWITEM消息。 添加一個OnDrawItem處理程序並在其中進行繪圖。 作為參數傳遞的DRAWITEMSTRUCT將告訴您應繪制到的矩形( rcItem )。

最后,我應該注意SetPixelV相當慢。 如果速度足夠快,請忽略此注釋的其余部分。 但是,如果在屏幕上繪制的速度確實很慢,則應考慮創建並緩存位圖對象。 繪制到該位圖中,設置其單個像素,然后只需將該位圖blit到控件的設備上下文中即可。 訪問和處理屏幕外位圖的各個像素快得多。

我設法用GetClientRect檢索詳細信息:

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));
            }

        }
    }

因此,我將此問題標記為已回答!

我不太確定這是否是“正確”的方法,我缺乏經驗。 但這有效,然后應該還可以:)

與其(直接)畫入圖片框,不如我建議使用位圖。 那確實更好,更容易使用。

我現在需要發現的是如何使用該位圖以正確的方式更新對話框。 正如科迪所說,這種繪制不應在此例程中完成,而應作為單獨的OnDrawItem指令進行處理。 嗯,還有更多要學習的。

Thanx和greetins,CJ

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM