Christopher Inokuchi
Christopher Inokuchi

Reputation: 33

How do I set the owner (or parent) of a Dialog Box?

I have six windows that can all generate a dialog box. The dialog box needs to know which of the six windows generated it. I believe I should be able to call GetParent(hWnd), or GetWindow(hWnd, GW_OWNER) from within the dialog box, but both calls return the overall project window, instead of the third arg I passed into DialogBox().

Here's the code that generates the dialog box (all six windows share the same wndproc function), along with some printf debugging:

        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;

Here's the code at the beginning of the dialog box proc:

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");
        ...

And here's the code that defines the dialogbox:

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

Here's the output from my printf statements:

hWnd from Caller to DialogBox: PaneClass
GetParent(hWnd): WINDOWSPROJECT2
GetWindow(hWnd, GW_OWNER): WINDOWSPROJECT2

Upvotes: 2

Views: 577

Answers (1)

dxiv
dxiv

Reputation: 17638

both calls return the overall project window, instead of the third arg I passed into DialogBox

The owner of a dialog box must be an overlapped or pop-up window. If OP's six windows are child windows, then the hWnd passed to DialogBox will be used to locate an eligible ancestor to use as an owner, instead, presumably the main window.

From the Owned Windows documentation:

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

If the originator window that called DialogBox must be known to the dialog, then that information must be passed separately in some other way.

Upvotes: 5

Related Questions