![](/img/trans.png)
[英]How to get the size and position of a button control of a dialog in a resource file?
[英]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
互換,包括調用上述兩個函數時),則可以僅調用Width
和Height
成員函數。
至於您的特定用例,由於您是在子窗口本身上調用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.