Reputation: 115
I'm trying to receive a message from a button when clicked. But instead of receiving it from the main window, I would like to receive it from a tab control, which is a child of the main window. But I'm not sure how to go about this.
This is the creation of the button:
deAll = CreateWindowEx(0, "BUTTON", "Disable All", WS_CHILD | BS_PUSHBUTTON, 135, 49, 95, 26, tabs, (HMENU)204, instance, NULL);
Obviously, tabs is a tab control.
This is the creation of the tab control:
tabs = CreateWindowEx(0, WC_TABCONTROL, 0, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 0, 0, rc.right + 2, rc.bottom - 22, hwnd, NULL, instance, NULL);
And hwnd is the main window.
Any ideas? Or do I have to make every control a child of the main window? This was made using the Win32 API in C++.
Upvotes: 1
Views: 2385
Reputation: 597941
The tabs
window is the parent window of the button, so the button will send a WM_COMMAND/BN_CLICKED
notification to the tabs
window when the button is clicked. You will have to subclass the tabs
window via either SetWindowLongPtr(GWL_WNDPROC)
or SetWindowSubClass()
to receive that message. For example:
WNDPROC prevWndProc;
LRESULT CALLBACK myWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if ((uMsg == WM_COMMAND) && (HIWORD(wParam) == BN_CLICKED))
{
// LOWORD(wParam) is the ID, and lParam is the HWND,
// of the button that was clicked. do something ...
}
return CallWindowProc(prevWndProc, hWnd, uMsg, wParam, lParam);
}
tabs = CreateWindowEx(0, WC_TABCONTROL, 0, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 0, 0, rc.right + 2, rc.bottom - 22, hwnd, NULL, instance, NULL);
prevWndProc = (WNDPROC) SetWindowLongPtr(tabs, GWLP_WNDPROC, (LONG_PTR) &myWndProc);
Or:
LRESULT CALLBACK mySubClassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
if ((uMsg == WM_COMMAND) && (HIWORD(wParam) == BN_CLICKED))
{
// LOWORD(wParam) is the ID, and lParam is the HWND,
// of the button that was clicked. do something ...
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
tabs = CreateWindowEx(0, WC_TABCONTROL, 0, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 0, 0, rc.right + 2, rc.bottom - 22, hwnd, NULL, instance, NULL);
SetWindowSubclass(tabs, &mySubClassProc, 0, 0);
Upvotes: 2
Reputation: 37192
If a control is a child of a tab (or any other control) then it's the tab that will get notification messages like WM_COMMAND
.
It's easiest to make your controls all children of your main window and just fix the z-order to make them appear in front of the tab (you already have WS_CLIPSIBLINGS
set on the tab control, which you would also need). If you leave the controls as children of the tab then the only way to get notification messages is to sub-class the tab.
Or, you can do this the way property sheets do it, and use child dialogs (a dialog with the DS_CONTROL
style set) to host the tab content. Then you can have a separate dialog procedure that handles messages from the child controls, and it makes it easy to show/hide a whole page of controls rather than handling them all individually. The TCM_ADJUSTRECT
message can be used to calculate the size/position that you need to display your child dialog at.
Upvotes: 1