源码
1 #include<Windows.h> 2 3 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 4 5 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow) 6 { 7 WNDCLASS WndClass; 8 TCHAR* ClassName = TEXT("MyClass"); 9 HWND hwnd; 10 MSG msg; 11 12 WndClass.cbClsExtra = 0; 13 WndClass.cbWndExtra = 0; 14 WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 15 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 16 WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 17 WndClass.hInstance = hInst; 18 WndClass.lpfnWndProc = WindProc; 19 WndClass.lpszClassName = ClassName; 20 WndClass.lpszMenuName = NULL; 21 WndClass.style = CS_VREDRAW | CS_HREDRAW; 22 23 if (!RegisterClass(&WndClass)) 24 { 25 MessageBox(NULL, TEXT("Gegister Class Fail!!"), TEXT("error"), MB_OK); 26 return 0; 27 } 28 29 hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL); 30 if (hwnd == NULL) 31 { 32 MessageBox(NULL, TEXT("Create Window Fail!!"), TEXT("error"), MB_OK); 33 return 0; 34 } 35 ShowWindow(hwnd, nShow); 36 UpdateWindow(hwnd); 37 38 while (GetMessage(&msg,NULL,0,0)) 39 { 40 TranslateMessage(&msg); 41 DispatchMessage(&msg); 42 } 43 44 return 0; 45 } 46 47 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 48 { 49 switch (message) 50 { 51 case WM_DESTROY: 52 PostQuitMessage(0);//发送WM_QUIT消息 53 return 0; 54 default: 55 break; 56 } 57 58 return DefWindowProc(hwnd, message, wParam, lParam); 59 }
LoadIcon
载入图示供程式使用。
LoadCursor
载入鼠标供程序使用。
GetStockObiect
取得一个图形对象(在这个例子中,是取得绘制视窗背景的画刷物件)。
RegisterClass
为程序视窗注册窗口类。
Create Window
根据窗口类建立一个视窗。
ShowWindow
在萤幕上显示窗口。
UpdateWindow
更新窗口。
GetMessage
从程序消息队列获取消息。
TranslateMessage
将虚拟密钥消息转换为字符消息。字符消息被发布到调用线程的消息队列,以便在线程下次调用GetMessage或PeekMessage函数时读取。
DispatchMessage
将消息发送到窗口过程。它通常用于分派由GetMessage函数检索的消息。
PostQuitMessage
向系统指示线程已发出终止请求(退出)。它通常用于响应WM_DESTROY消息。
LoadCursor
从与应用程序实例关联的可执行文件(.EXE)加载指定的游标资源。
注意此函数已被LoadImage函数取代。
LoadIcon
从与应用程序实例关联的可执行文件(.EXE)加载指定的游标资源。
注意此函数已被LoadImage函数取代。
CreateWindow
HWND WINAPI CreateWindow( _In_opt_ LPCTSTR lpClassName, _In_opt_ LPCTSTR lpWindowName, _In_ DWORD dwStyle, _In_ int x, _In_ int y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam );
DispatchMessage这里调用的是我们自定义的消息处理函数WindProc
PostQuitMessage(0)发送WM_QUIT消息,使GetMessage函数返回值为零,从而退出while循环。
WIndows窗体程序的一生 ,大部分时间都在消息循环中度过。
下面代码创建一个空白窗口程序,没有关闭按钮,只能Alt+F4关闭
GetSystemMetrics是一个计算机函数,该函数只有一个参数,称之为「索引」,这个索引有75个标识符,通过设置不同的标识符就可以获取系统分辨率、窗体显示区域的宽度和高度、滚动条的宽度和高度。
1 #include<Windows.h> 2 3 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 4 5 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow) 6 { 7 WNDCLASS WndClass; 8 TCHAR* ClassName = TEXT("MyClass"); 9 HWND hwnd; 10 MSG msg; 11 12 WndClass.cbClsExtra = 0; 13 WndClass.cbWndExtra = 0; 14 WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 15 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 16 WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 17 WndClass.hInstance = hInst; 18 WndClass.lpfnWndProc = WindProc; 19 WndClass.lpszClassName = ClassName; 20 WndClass.lpszMenuName = NULL; 21 WndClass.style = CS_VREDRAW | CS_HREDRAW; 22 23 if (!RegisterClass(&WndClass)) 24 { 25 MessageBox(NULL, TEXT("Gegister Class Fail!!"), TEXT("error"), MB_OK); 26 return 0; 27 } 28 29 hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInst, NULL); 30 if (hwnd == NULL) 31 { 32 MessageBox(NULL, TEXT("Create Window Fail!!"), TEXT("error"), MB_OK); 33 return 0; 34 } 35 ShowWindow(hwnd, nShow); 36 UpdateWindow(hwnd); 37 38 while (GetMessage(&msg,NULL,0,0)) 39 { 40 TranslateMessage(&msg); 41 DispatchMessage(&msg); 42 } 43 44 return 0; 45 } 46 47 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 48 { 49 switch (message) 50 { 51 case WM_DESTROY: 52 PostQuitMessage(0);//发送WM_QUIT消息 53 return 0; 54 default: 55 break; 56 } 57 58 return DefWindowProc(hwnd, message, wParam, lParam); 59 }
窗口过程
LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
hwnd:窗口过程可以为基于同一窗口类创建的多个窗口处理消息。通过hwnd 参数,窗口过程就可获知到底是哪一个窗口正在接收消息。
message:具体某一Windows消息,例如VM_SIZE
wParam、lParam提供消息相关的附加参数。以message为VM_SIZE为例,
wParam 参数取值可为SIZE RESTORED、SIZE_MINIMIZED、SIZE MAXIMIZED、SIZE_MAXSHOW 或 SIZE MAXHIDE
IParam参数中包含该窗口的新尺寸,窗口的新宽度(一个16位的值)和新高度(也是一个16位的值)被组合在32位的IParam参数中。头文件WINDEFH中定义了一些宏便于从IParam中提取这两个值。
消息从何而来:
消息来自于用户的输入;消息来自于系统;
消息被存放在那里:
消息被存放在每个线程的消息队列中。
消息如何被线程取出:
GetMessage函数,PeekMessage.
GetMessage在取消息的时候,如果消息队列是空的。GetMessage函数将阻塞线程,知道消息队列有一个消息,GetMessage才返回
PeekMessage如果消息队列里面有消息,其行为和GetMessage一样。如果消息队列为空,PeekMessage立即返回
消息队列是否先进先出,Fl-FO
对大多数消息而言,是FIFO
但是消息队列会对特殊满息进行处理,例如WM_PAINT,WM_TIMER,WM_QUIT。
消息是否必须经过消息队列:
否,有些消息被直接发送给窗口,不经过消息队列,例如,激活窗口的消息。
命名约定
lpfn 指向函数的长指针
cb 字节数
lpsz 指向以零结束的字符串的长指针