Windows程序设计(第五版)
第三章 窗口与消息
源程序见原书39页
在Visual Studio 2010 C++下测试
//------------------Start-------------------
#include <windows.h>
void ShowMessage(LPCWSTR text)
{
MessageBox(NULL, text, TEXT("ShowMessage"), 0) ;
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Hello World!") ;
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 (GRAY_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName= szAppName ;
RegisterClass(&wndclass);//Register
hwnd = CreateWindow( szAppName, // window class name
TEXT ("Hello World 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
/*
CreateWindow的过程中便会开始调用CALLBACK WndPROC
*/
ShowWindow (hwnd, iCmdShow);
UpdateWindow (hwnd); //好像有没有这个updateWin效果都一样
while (GetMessage (&msg, NULL, 0, 0))
{
//if(msg.message == (UINT)WM_RBUTTONDOWN)//debug
// {MessageBox ( NULL, TEXT ("Right B D"), TEXT("Halo"), 0);}
TranslateMessage (&msg);//注释掉对好像当前程序没有影响[翻译一些键盘消息?]
DispatchMessage (&msg) ;
/*DispatchMessage(...)
[我认为应该是将消息(控制权)返回给Window(附带着将消息发送给窗口过程)]
注释掉之后,右上角的最小最大关闭三个按钮失效.
且注释掉之后对窗口的操作都不会回调给WndProc(...)处理
*/
//if(msg.message == (UINT)WM_RBUTTONDOWN)
// {MessageBox ( NULL, TEXT ("Right B D3"), TEXT("Halo"), 0);}
}
return msg.wParam ;
}
//这个WndProc的调用真是非常诡异
//一般情况下,确实是跟在DispatchMessage之中的
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message)
{
case WM_RBUTTONDOWN:
MessageBox ( NULL, TEXT ("Right B D CALLBACK"), TEXT("Halo"), 0) ;
return 0;
case WM_CREATE:
MessageBox ( NULL, TEXT ("Window is Creating."), TEXT("Halo"), 0) ;
return 0 ;
case WM_PAINT:
/*
在ShowWindow的过程中就会开始Paint,而且这个过程会重复40次左右。为什么会重复这么多次?
*/
//ShowMessage(TEXT("WM_Paint"));//debug
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:
//如果是销毁窗口消息
MessageBox(NULL, TEXT ("Win Destroying..."), TEXT("Halo"), 0) ;
PostQuitMessage (0) ;
return 0;
default:
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
}
//------END------
(1)新建一个窗口。 此过程分3步走
(1.1)声明(并赋初值)WndCLASS wndclass;
(1.2)注册窗口类 RegisterClass(...);//只有注册过的窗口类才会产生回调
(1.3)创建窗口CreateWindow(...);//这期间将会第一次回调WndProc(...)
(2)显示窗口 ShowWindow(...);期间会(多次)回调WndProc(...) ,并发送WM_PAINT消息
(3)UpdateWindow(...);//更新窗口
(4)不断地循环接受各种消息(在窗口成型后)
While(GetMessage(..))
{
TranslateMessage(...);//翻译消息
DispatchMessage(...);//窗口成型之后,所有的回调都来自于他,如果注释掉,在窗口成型之后将不会回调WndProc()
}