Code:
#include <windows.h>
#include <iostream>
#include <string>
#include <map>
typedef LRESULT (MessageCallbackPtr)(WPARAM, LPARAM);
std::map<int, MessageCallbackPtr*> mCallback;
const char g_szClassName[] = "myWindowClass";
LRESULT MyClickHandler(WPARAM wParam, LPARAM lParam)
{
MessageBox(NULL, "Got it", "Click!", MB_OK);
return 0;
}
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
{
std::map<int, MessageCallbackPtr *>::iterator iFunction;
iFunction = mCallback.find( LOWORD(wParam) );
if ( iFunction != mCallback.end() )
return iFunction->second(wParam, lParam);
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd, hWndButton;
MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc)) {
return 0;
}
// Step 2: Creating the Window
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName,
"Win32 Practice",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL) {
return 0;
}
hWndButton = CreateWindowEx(NULL, "button", "Click Me",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 50, 50, 100, 24, hwnd,
(HMENU)(100), hInstance, NULL);
if (hWndButton == NULL)
return false;
mCallback[/* Control ID here, as is sent by the low word of the wParam */] = &MyClickHandler;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Step 3: The Message Loop
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return (int) Msg.wParam;
}
If you use the control identifier instead, it should only react for that control. Or you could use the window handle instead. But I don't know if the control's handle is sent via the hwnd argument in the window proc when a control notifies its window.