zhuang@linux:~/reading/programming-windows/03-windows-and-messages/$ less
Windows and Messages
This post extracts some knowledge from Programming Windows Chapter 3 – Windows and Messages.
Windows Program Basic Framework
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HelloWin") ;
HWND hwnd;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("The Hello Program"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;
switch (message)
{
case WM_CREATE:
PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}CreateWindow declarition as follows:
HWND CreateWindowW(
[in, optional] LPCWSTR lpClassName,
[in, optional] LPCWSTR lpWindowName,
[in] DWORD dwStyle,
[in] int x,
[in] int y,
[in] int nWidth,
[in] int nHeight,
[in, optional] HWND hWndParent,
[in, optional] HMENU hMenu,
[in, optional] HINSTANCE hInstance,
[in, optional] LPVOID lpParam
);Hungarian Notation
Many Windows programmers use Hungarian notation as a variable naming convention. This is in honor of the legendary Microsoft programmer Charles Simonyi. This notation is very simple: variable names begin with a lowercase letter indicating the data type of the variable.
When naming structure variables, you can use the lowercase form of the structure name (or an abbreviation of the structure name) as a prefix or the entire variable name. For example, in the WinMain function of HELLOWIN, the variable msg is a structure of type MSG, and wndclass is a structure of type WNDCLASS. In the WndProc function, ps is a structure of type PAINTSTRUCT, and rect is a structure of type RECT.
Common variables name prefix as follows:
| prefix | data type |
|---|---|
| c | char or WCHAR or TCHAR |
| by | BYTE(unsigned char) |
| n | short |
| i | int |
| x, y | int used as x-coordinate or y-coordinate |
| cx, cy | int used as x or y length; c stands for “count” |
| B or f | BOOL(int); f stands for “flag” |
| w | WORD(unsigned short) |
| l | LONG(long) |
| dw | DWORD(unsigned long) |
| fn | function |
| s | string |
| sz | string terminated by 0 character |
| h | handle |
| p | pointer |
Queued Messages and Non-queued Messages
Messages can be either “queued messages” or “unqueued messages.” Queued messages are those placed in a program’s message queue by Windows. In the program’s message loop, messages are retrieved and then delivered to the window procedure. Unqueued messages are generated by direct calls to the window procedure by Windows. Generally, queued messages are “posted” to the message queue, while unqueued messages are “sent” to the window procedure. In either case, the window procedure retrieves all messages for the window—whether queued or unqueued. Therefore, the window procedure is essentially the window’s “message center.”
Queued messages are primarily generated by user input, mainly in the form of keystroke messages (such as WM_KEYDOWN and WM_KEYUP messages), character messages generated by keystrokes WM_CHAR, mouse movement WM MOUSEMOVE, mouse clicks WM_LBUTTONDOWN, etc. In addition, queued messages include timer messages WM_TIMER, repaint messages WM_PAINT, and exit messages WM_QUIT.
Non-queued messages include all other messages besides those in the queue. Non-queued messages are typically caused by calls to specific Windows functions. For example, when WinMain calls the CreateWindow function, Windows creates the window and sends a WM_CREATE message to the window procedure during creation. When WinMain calls the ShowWindow function, Windows sends WM_SIZE and WM_SHOWWINDOW messages to the window procedure. Next, WinMain calls UpdateWindow, which prompts Windows to send a WM_PAINT message to the window procedure.
zhuang@linux:~/reading/programming-windows/03-windows-and-messages/$ comments