I want to make a panel, which groups buttons by itself:
HWND my_panel = CreateWindow(
"STATIC",
"",
WS_VISIBLE | WS_CHILD | WS_BORDER,
30,
100,
300,
300,
main_window, // main dialog
NULL,
( HINSTANCE ) GetWindowLong( main_window, GWL_HINSTANCE ),
NULL
);
Then I add a button to this panel:
HWND button_in_a_group = CreateWindow(
"BUTTON",
"Hello world",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
20,
20,
50,
50,
my_panel, // as a child for above
NULL,
( HINSTANCE ) GetWindowLong( main_window, GWL_HINSTANCE ),
NULL
);
When I click the button, it doesn't send a WM_COMMAND
but WM_PARENTNOTIFY
to callback function. Then, if I press Enter, it works - WM_COMMAND
is sent by the button.
How to enable mouse click on nested button, and why nested windows doesn't work as expected?
Messages are sent to parent window. In this case the static windows is the button's parent. So the main window is not receiving button messages, except WM_PARENTNOTIFY
.
You can subclass the static window:
SetWindowSubclass(my_panel, ChildProc, 0, 0);
Define a ChildProc
to catch the button messages. See also Subclassing Controls
The button also requires an identifier as follows:
CreateWindow("BUTTON", "Hello world", ... my_panel, HMENU(BUTTON_ID) ...);
WM_COMMAND
message is sent to ChildProc
when button is clicked. The BN_CLICKED
notification carries BUTTON_ID
Note, SetWindowSubclass
needs additional header and library:
#include <CommCtrl.h>
#pragma comment(lib, "Comctl32.lib") //Visual Studio option for adding libraries
...
LRESULT CALLBACK ChildProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam, UINT_PTR, DWORD_PTR)
{
switch(msg) {
case WM_COMMAND:
switch(LOWORD(wParam)) {
case BUTTON_ID:
MessageBox(0, "hello world", 0, 0);
break;
}
break;
case WM_NCDESTROY:
RemoveWindowSubclass(hwnd, ChildProc, 0);
break;
}
return DefSubclassProc(hwnd, msg, wParam, lParam);
}