This will be helpful for implementing own GUI framework
Message | Callback function signature |
---|---|
WM_CREATE |
BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpcs); |
WM_SIZE |
void OnSize(HWND hWnd, UINT state, int x, int y); |
WM_DESTROY |
void OnDestroy(HWND hWnd); |
WM_PAINT |
void OnPaint(HWND hWnd); |
WM_LBUTTONDOWN |
void OnLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT keyFlags); |
WM_LBUTTONUP |
void OnLButtonUp(HWND hWnd, int x, int y, UINT keyFlags); |
WM_COMMAND |
void OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify); |
WM_KEYUP |
void OnKeyUp(HWND hWnd, UINT vk, int cRepeat, UINT flags); |
WM_KEYDOWN |
void OnKeyDown(HWND hWnd, UINT vk, int cRepeat, UINT flags); |
WM_MOUSEMOVE |
void OnMouseMove(HWND hWnd, int x, int y, UINT keyFlags); |
WM_DRAWITEM |
void OnDrawItem(HWND hWnd, LPDRAWITEMSTRUCT lpdis); |
WM_MEASUREITEM |
void OnDrawItem(HWND hWnd, LPDRAWITEMSTRUCT lpdis); |
WM_NOTIFY |
void OnNotify(HWND hWnd, int idFrom, LPNMHDR pnmhdr); |
BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpcs);
Should return the success status of window initialization of type BOOL
. If WM_CREATE
returns FALSE
, window creation will be considered unsuccessful.
Symbol | Argument | Description |
---|---|---|
LPCREATESTRUCT lpcs |
dynamic cast of lParam |
Pointer to window creation data structure |
HANDLE_MSG(hWnd, WM_CREATE, OnCreate);
OnCreate(HWND hWnd, (LPCREATEPARAM)lpcs);
OnCreate(HWND hWnd, reinterpret_cast<LPCREATESTRUCT>(lparam));
void OnSize(HWND hWnd, UINT state, int x, int y);
Symbol | Argument | Description |
---|---|---|
UINT state |
static cast of wParam |
See MSDN |
int x |
LOWORD lParam |
Updated client area width |
int y |
HIWORD lParam |
Updated client area height |
HANDLE_MSG(hWnd, WM_SIZE, OnSize);
OnSize(HWND hWnd, (UINT)wParam, LOWORD(lParam), HIWORD(lParam));
OnSize(HWND hWnd, static_cast<UINT>(wParam), static_cast<int>(LOWORD(lParam)), static_cast<int>(HIWORD(lParam)));
void OnDestroy(HWND hWnd);
None
HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy);
OnDestroy(HWND hWnd);
OnDestroy(HWND hWnd);
void OnPaint(HWND hWnd);
None
HANDLE_MSG(hWnd, WM_PAINT, OnPaint);
OnPaint(HWND hWnd);
OnPaint(HWND hWnd);
void OnDrawItem(HWND hWnd, LPDRAWITEMSTRUCT lpdis);
Symbol | Argument | Description |
---|---|---|
LPDRAWITEMSTRUCT lpdis |
reinterpret cast of lParam |
Pointer to item being drawn |
HANDLE_MSG(hWnd, WM_DRAWITEM, OnDrawItem);
OnDrawItem(HWND hWnd, (LPDRAWITEMSTRUCT)lParam);
OnDrawItem(HWND hWnd, reinterpret_cast<LPDRAWITEMSTRUCT>(lParam));
In dialogs called before WM_INITDIALOG. Make sure you have your handler registered.
void OnMeasureItem(HWND hWnd, LPMEASUREITEMSTRUCT lpMeasureItem);
Symbol | Argument | Description |
---|---|---|
LPMEASUREITEMSTRUCT lpMeasureItem |
reinterpret cast of lParam |
Pointer to structure describing the item being measured |
HANDLE_MSG(hWnd, WM_MEASUREITEM, OnMeasureItem);
OnMeasureItem(HWND hWnd, (LPMEASUREITEMSTRUCT)lParam);
OnMeasureItem(HWND hWnd, reinterpret_cast<LPMEASUREITEMSTRUCT>(lParam));
void OnNotify(HWND hWnd, int idFrom, LPNMHDR pnmhdr);
Symbol | Argument | Description |
---|---|---|
int idFrom |
static cast of wParam |
id |
LPNMHDR pnmhdr |
reinterpret cast of lParam |
id |
HANDLE_MSG(hWnd, WM_NOTIFY, OnNotify);
OnNotify(HWND hWnd, (int)wParam, (LPNMHDR)lParam);
OnNotify(HWND hWnd, static_cast<int>(wParam), reinterpret_cast<LPNMHDR>(lParam));
For unifying the order which message handling follows it might be helpful to order them by message macro values
- WM_CREATE
- WM_SIZE
- WM_PAINT
- ...
- WM_DESTROY
...
BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpcs) {
/* Return TRUE if window initialization succeed, otherwise return FALSE */
return TRUE;
}
void OnPaint(HWND hWnd) {
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
Ellipse(hdc, 0, 0, 50, 50);
EndPaint(hWnd, &ps);
}
void OnDestroy(HWND hWnd) {
/* Quit application if the window destroys */
PostQuitMessage(0);
}
/* Static message handling procedure */
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
HANDLE_MSG(hWnd, WM_CREATE, OnCreate);
HANDLE_MSG(hWnd, WM_PAINT, OnPaint);
HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy);
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
...
class Wnd {
protected:
virtual BOOL OnCreate(LPCREATESTRUCT);
virtual void OnPaint();
virtual void OnDestroy();
virtual LRESULT CALLBACK UserWndProc(UINT message, WPARAM wParam, LPARAM lParam) {
return ::DefWindowProc(hWnd_, message, wParam, lParam);
};
HWND hWnd_;
private:
static LRESULT CALLBACK StaticWndProc(HWND, UINT, WPARAM, LPARAM);
};
/******************
* InheritedWnd *
******************/
// Define a custom message code
#define WM_INHW_CUSTOMMESSAGE WM_USER + 1
// Define a custom data type for the custom message
struct _tagCUSTOMMESSAGE {
int x;
};
typedef struct _tagCUSTOMMESSAGE CUSTOMMESSAGE, *PCUSTOMMESSAGE;
class InheritedWnd : public Wnd {
protected:
void OnCustomMessage(PCUSTOMMESSAGE);
virtual LRESULT CALLBACK UserWndProc(UINT, WPARAM, LPARAM) final override;
};
BOOL Wnd::OnCreate(LPCREATESTRUCT lpcs) {
// Use internal field instead of hWnd parameter
(void)hWnd_;
return TRUE;
}
void Wnd::OnPaint() {
PAINTSTRUCT ps{};
HDC hdc = ::BeginPaint(hWnd_, &ps);
::Ellipse(hdc, 0, 0, 10, 10);
::EndPaint(hWnd_, &ps);
}
void Wnd::OnDestroy() {
::PostQuitMessage(0);
}
LRESULT CALLBACK Wnd::StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
Wnd* wnd = ...; // Somehow obtain the window object pointer
switch (message) {
case WM_CREATE:
return wnd->OnCreate((LPCREATESTRUCT)lParam);
break;
case WM_PAINT:
wnd->OnPaint();
return 0L;
break;
case WM_DESTROY:
wnd->OnDestroy();
return 0L;
break;
}
if (wnd) {
return wnd->UserWndProc(hWnd, message, wParam, lParam);
}
// If its not possible to obtain Wnd*, handle message to system:
return ::DefWindowProc(hWnd, message, wParam, lParam);
}
void InheritedWnd::OnCustomMessage(PCUSTOMMESSAGE pCustMsg) {
(void)(pCustMsg->x);
}
LRESULT CALLBACK InheritedWnd::UserWndProc(UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_INHW_CUSTOMMESSAGE:
OnCustomMessage((PCUSTOMMESSAGE)lParam);
return 0L;
break;
}
return ::DefWindowProc(hWnd, message, wParam, lParam);
}