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
NULLif 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;
//...
