Home > database >  How to receive a message in the parent window from a button created by CreateWindow()?
How to receive a message in the parent window from a button created by CreateWindow()?

Time:12-31

I've created a button with the following code:

  HWND hwndButton = CreateWindow(
        "BUTTON",  // Predefined class;
        "Options",      // Button text 
        WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
        250,         // x position 
        0,         // y position 
        50,        // Button width
        30,        // Button height
        hwnd,     // Parent window
        NULL,       // No menu.
        (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
        NULL);

I'm aware that messages from buttons can be received in the window procedure of the parent window by doing a switch with WM_COMMAND and the name of the control as the case, for example, IDC_BUTTON. However, that's only when I create buttons on dialog boxes graphically using Visual Studio's editor. When I create a button using CreateWindow, as above, there isn't a 'name' for the control to put into a case statement.

What message is sent to the parent window when the button is pressed?

CodePudding user response:

You can specify the button's identifier value (as in the IDC_BUTTON1 control resource ID, for example, in a dialog box) as the hMenu argument in the call to CreateWindow.

Here's a suitably modified version of your code:

  HWND hwndButton = CreateWindow(
        "BUTTON",  // Predefined class;
        "Options",      // Button text 
        WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
        250,       // x position 
        0,         // y position 
        50,        // Button width
        30,        // Button height
        hwnd,      // Parent window
        (HMENU)(IDC_BUTTON1), // With WS_CHILD, this is an ID, not a menu
        (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
        NULL);

From the description of the hMenu parameter in the docs (bold emphasis mine):

A handle to a menu, or specifies a child-window identifier depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.

Then, when the parent receives the WM_COMMAND message, that identifier value will be part (the low word) of the wParam argument (the high word will be the BN_CLICKED notification code). (docs)

So, assuming you have the IDC_BUTTON1 token defined somewhere, and pass that as the hMenu argument as described above, then your parent window can have something along the following lines as part of the message-handler's switch statement:

//...
    case WM_COMMAND:
        if (LOWORD(wParam) == IDC_BUTTON1 && HIWORD(wParam) == BN_CLICKED) {
            MessageBox(NULL, "Clicked My Button!", "Testing...", MB_OK);
            // <Place your actual code here ...>
            return 0; // If handled, we should return zero.
        }
        break;
//...
  • Related