如何设置对话框的所有者(或父级)?
How do I set the owner (or parent) of a Dialog Box?
我有六个windows都可以生成对话框。对话框需要知道它是由六个 windows 中的哪一个生成的。我相信我应该能够从对话框中调用 GetParent(hWnd) 或 GetWindow(hWnd, GW_OWNER),但是这两个调用 return 整个项目 window,而不是我传递给 DialogBox() 的第三个参数。
这是生成对话框的代码(所有六个 windows 共享相同的 wndproc 函数),以及一些 printf 调试:
case ID_SETTINGS_BUTTON:
OutputDebugStringA("hWnd from Caller to DialogBox: ");
char buffer[128];
GetClassNameA(hWnd, buffer, 128);
OutputDebugStringA(buffer);
OutputDebugStringA("\n");
DialogBox(hInst, MAKEINTRESOURCE(IDD_PORTSETTINGS), hWnd, portSettingsProc);
break;
这是对话框过程开始处的代码:
INT_PTR CALLBACK portSettingsProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_INITDIALOG:
for (int k = 0; k < PaneInfo::BAUDRATE_I_COUNT; k++)
SendDlgItemMessage(hWnd, IDC_PORTSETTINGS_BAUDRATE, CB_ADDSTRING, 0, (LPARAM)PaneInfo::BAUDRATE_NAME_ARR[k]);
for (int k = 0; k < PaneInfo::DATABITS_I_COUNT; k++)
SendDlgItemMessage(hWnd, IDC_PORTSETTINGS_DATABITS, CB_ADDSTRING, 0, (LPARAM)PaneInfo::DATABITS_NAME_ARR[k]);
for (int k = 0; k < PaneInfo::STOPBITS_I_COUNT; k++)
SendDlgItemMessage(hWnd, IDC_PORTSETTINGS_STOPBITS, CB_ADDSTRING, 0, (LPARAM)PaneInfo::STOPBITS_NAME_ARR[k]);
for (int k = 0; k < PaneInfo::PARITY_I_COUNT; k++)
SendDlgItemMessage(hWnd, IDC_PORTSETTINGS_PARITY, CB_ADDSTRING, 0, (LPARAM)PaneInfo::PARITY_NAME_ARR[k]);
OutputDebugStringA("GetParent(hWnd): ");
char buffer[128];
GetClassNameA(GetParent(hWnd), buffer, 128);
OutputDebugStringA(buffer);
OutputDebugStringA("\n");
OutputDebugStringA("GetWindow(hWnd, GW_OWNER): ");
GetClassNameA(GetWindow(hWnd, GW_OWNER), buffer, 128);
OutputDebugStringA(buffer);
OutputDebugStringA("\n");
...
下面是定义对话框的代码:
IDD_PORTSETTINGS DIALOGEX DISCARDABLE 0, 0, 200, 200
STYLE DS_CENTER | DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Port Settings"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "BaudRate:", IDC_STATIC, 10, 6, 100, 14
COMBOBOX IDC_PORTSETTINGS_BAUDRATE, 10, 20, 180, 60, CBS_DROPDOWNLIST
LTEXT "DataBits:", IDC_STATIC, 10, 40, 100, 14
COMBOBOX IDC_PORTSETTINGS_DATABITS, 10, 54, 180, 60, CBS_DROPDOWNLIST
LTEXT "StopBits:", IDC_STATIC, 10, 74, 100, 14
COMBOBOX IDC_PORTSETTINGS_STOPBITS, 10, 88, 180, 60, CBS_DROPDOWNLIST
LTEXT "Parity:", IDC_STATIC, 10, 108, 100, 14
COMBOBOX IDC_PORTSETTINGS_PARITY, 10, 122, 180, 60, CBS_DROPDOWNLIST
DEFPUSHBUTTON "OK", IDOK, 80, 180, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 140, 180, 50, 14
END
这是我的 printf 语句的输出:
hWnd from Caller to DialogBox: PaneClass
GetParent(hWnd): WINDOWSPROJECT2
GetWindow(hWnd, GW_OWNER): WINDOWSPROJECT2
both calls return the overall project window, instead of the third arg I passed into DialogBox
对话框的所有者必须是重叠的或 pop-up window。如果 OP 的六个 windows 是 child windows,那么传递给 DialogBox
的 hWnd
将用于定位一个合格的祖先以用作所有者,而不是,大概是主要的 window.
来自 Owned Windows 文档:
Only an overlapped or pop-up window can be an owner window; a child window cannot be an owner window. [...] The hwndParent parameter must identify an overlapped or pop-up window. If hwndParent identifies a child window, the system assigns ownership to the top-level parent window of the child window.
Dialog boxes and message boxes are owned windows by default
如果对话必须知道调用 DialogBox
的发起者 window,则必须以其他方式单独传递该信息。
我有六个windows都可以生成对话框。对话框需要知道它是由六个 windows 中的哪一个生成的。我相信我应该能够从对话框中调用 GetParent(hWnd) 或 GetWindow(hWnd, GW_OWNER),但是这两个调用 return 整个项目 window,而不是我传递给 DialogBox() 的第三个参数。
这是生成对话框的代码(所有六个 windows 共享相同的 wndproc 函数),以及一些 printf 调试:
case ID_SETTINGS_BUTTON:
OutputDebugStringA("hWnd from Caller to DialogBox: ");
char buffer[128];
GetClassNameA(hWnd, buffer, 128);
OutputDebugStringA(buffer);
OutputDebugStringA("\n");
DialogBox(hInst, MAKEINTRESOURCE(IDD_PORTSETTINGS), hWnd, portSettingsProc);
break;
这是对话框过程开始处的代码:
INT_PTR CALLBACK portSettingsProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_INITDIALOG:
for (int k = 0; k < PaneInfo::BAUDRATE_I_COUNT; k++)
SendDlgItemMessage(hWnd, IDC_PORTSETTINGS_BAUDRATE, CB_ADDSTRING, 0, (LPARAM)PaneInfo::BAUDRATE_NAME_ARR[k]);
for (int k = 0; k < PaneInfo::DATABITS_I_COUNT; k++)
SendDlgItemMessage(hWnd, IDC_PORTSETTINGS_DATABITS, CB_ADDSTRING, 0, (LPARAM)PaneInfo::DATABITS_NAME_ARR[k]);
for (int k = 0; k < PaneInfo::STOPBITS_I_COUNT; k++)
SendDlgItemMessage(hWnd, IDC_PORTSETTINGS_STOPBITS, CB_ADDSTRING, 0, (LPARAM)PaneInfo::STOPBITS_NAME_ARR[k]);
for (int k = 0; k < PaneInfo::PARITY_I_COUNT; k++)
SendDlgItemMessage(hWnd, IDC_PORTSETTINGS_PARITY, CB_ADDSTRING, 0, (LPARAM)PaneInfo::PARITY_NAME_ARR[k]);
OutputDebugStringA("GetParent(hWnd): ");
char buffer[128];
GetClassNameA(GetParent(hWnd), buffer, 128);
OutputDebugStringA(buffer);
OutputDebugStringA("\n");
OutputDebugStringA("GetWindow(hWnd, GW_OWNER): ");
GetClassNameA(GetWindow(hWnd, GW_OWNER), buffer, 128);
OutputDebugStringA(buffer);
OutputDebugStringA("\n");
...
下面是定义对话框的代码:
IDD_PORTSETTINGS DIALOGEX DISCARDABLE 0, 0, 200, 200
STYLE DS_CENTER | DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "Port Settings"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "BaudRate:", IDC_STATIC, 10, 6, 100, 14
COMBOBOX IDC_PORTSETTINGS_BAUDRATE, 10, 20, 180, 60, CBS_DROPDOWNLIST
LTEXT "DataBits:", IDC_STATIC, 10, 40, 100, 14
COMBOBOX IDC_PORTSETTINGS_DATABITS, 10, 54, 180, 60, CBS_DROPDOWNLIST
LTEXT "StopBits:", IDC_STATIC, 10, 74, 100, 14
COMBOBOX IDC_PORTSETTINGS_STOPBITS, 10, 88, 180, 60, CBS_DROPDOWNLIST
LTEXT "Parity:", IDC_STATIC, 10, 108, 100, 14
COMBOBOX IDC_PORTSETTINGS_PARITY, 10, 122, 180, 60, CBS_DROPDOWNLIST
DEFPUSHBUTTON "OK", IDOK, 80, 180, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 140, 180, 50, 14
END
这是我的 printf 语句的输出:
hWnd from Caller to DialogBox: PaneClass
GetParent(hWnd): WINDOWSPROJECT2
GetWindow(hWnd, GW_OWNER): WINDOWSPROJECT2
both calls return the overall project window, instead of the third arg I passed into DialogBox
对话框的所有者必须是重叠的或 pop-up window。如果 OP 的六个 windows 是 child windows,那么传递给 DialogBox
的 hWnd
将用于定位一个合格的祖先以用作所有者,而不是,大概是主要的 window.
来自 Owned Windows 文档:
Only an overlapped or pop-up window can be an owner window; a child window cannot be an owner window. [...] The hwndParent parameter must identify an overlapped or pop-up window. If hwndParent identifies a child window, the system assigns ownership to the top-level parent window of the child window.
Dialog boxes and message boxes are owned windows by default
如果对话必须知道调用 DialogBox
的发起者 window,则必须以其他方式单独传递该信息。