Global Sublassing Example

#include <windows.h> #define BUTTON1 1 #define BUTTON2 2 WNDPROC OldWndProc; HWND hiddenButton; HWND button; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK SubClassProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; MSG msg; 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 = TEXT("myWindowClass"); wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wc); CreateWindowEx( WS_EX_CLIENTEDGE, TEXT("myWindowClass"), TEXT("Global Subclass"), WS_VISIBLE | WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 180, NULL, NULL, hInstance, NULL); while(GetMessage(&msg,NULL,0,0)>0) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: { /* Create hidden BUTTON window. This gives us the BUTTON class information. */ hiddenButton = CreateWindow( TEXT("BUTTON"), TEXT("Hidden"), WS_CHILD, 0, 0, 0, 0, hwnd, (HMENU)BUTTON1, GetModuleHandle(NULL), NULL); /* Replace the BUTTON class procedure. All buttons created afterwards will use SubClassProc. */ OldWndProc = (WNDPROC)SetClassLong( hiddenButton, GCL_WNDPROC, (LONG)SubClassProc); /* This button is created after the class procedure has been changed. It will use SubClassProc. */ button = CreateWindow( TEXT("BUTTON"), TEXT("Button 1"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 100, 50, hwnd, (HMENU)BUTTON2, GetModuleHandle(NULL), NULL); break; } case WM_DESTROY: { /* Restore original BUTTON procedure. Important because BUTTON is a system class. */ SetClassLong( hiddenButton, GCL_WNDPROC, (LONG)OldWndProc); PostQuitMessage(0); break; } } return DefWindowProc(hwnd,msg,wParam,lParam); } LRESULT CALLBACK SubClassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_LBUTTONDOWN: MessageBeep(MB_ICONEXCLAMATION); break; } // send message to original BUTTON procedure return CallWindowProc( OldWndProc, hwnd, uMsg, wParam, lParam); }