WinAPI详解程序
#include <Windows.h>
//窗口回调函数声明
//LRESULT表明函数返回值类型被宏定义为LONG
//CALLBACK说明的是函数蚕食的进栈顺序(从左到右)
//四个函数参数为message结构体中的前四个参数
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//windows程序入口函数,返回值为int
//WINAPI与CALLBACK作用相同,声明进栈顺序
//HINSTANCE定义执行实体(程序自身)句柄变量(句柄不是指针,句柄是一个数值)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR SZcMDlINE, INT iCmdShow)
{
static TCHAR szAppName[] = TEXT("HelloWin");//定义窗口名称
HWND hwnd; //定义窗口句柄
MSG msg; //定义消息结构体变量
WNDCLASS wndclass; //定义窗口类结构体变量
//在WNDCLASS 结构中最重要的两个字段是第二个和最后一个
//第二个字段(lpfnWndProc) 是依据这个类别来建立的所有窗口所使用的窗口消息处理程序的地址。在此程序中,这个是WndProc 函数。
//最后一个字段是窗口类别的文字名称。程序写作者可以随意定义其名称。在只建立一个窗口的程序中,窗口类别名称通常设定为程序名称。
wndclass.style = CS_HREDRAW | CS_VREDRAW; //设置窗口风格,CS_HREDRAW 为垂直重画 CS_VREDRAW为水平重画,如果你水平或竖直拖动窗口,他将重新显示窗口,即调用WM_PAINT消息!
wndclass.lpfnWndProc = WndProc; //将回调函数的首地址赋值给窗口类中的lpfnWndProc参数
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; //设置菜单,NULL表示此程序无菜单
wndclass.lpszClassName = szAppName; //设置程序窗口名称
if (!RegisterClass(&wndclass)) //向操作系统注册窗口类
{
//如果注册失败,弹出错误提示框,并就结束程序
MessageBox(NULL, TEXT("程序注册失败"), szAppName, MB_ICONERROR);
return 0;
}
//创建窗口
hwnd = CreateWindow(szAppName, //应用程序在操作系统注册表中的名称
TEXT("Hello"), //应用程序标题栏名称
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT, //显示时窗口左上角相对于对于屏幕左上角x坐标
CW_USEDEFAULT, //显示时窗口左上角相对于对于屏幕左上角y坐标
CW_USEDEFAULT, //窗口宽度
CW_USEDEFAULT, //窗口高度
NULL, //父窗口句柄,此程序没有父窗口
NULL, //菜单句柄
hInstance, //程序实例句柄
NULL); //创建参数指针
//CreateWindow 传回被建立的窗口的句柄,该句柄存放在变量hwnd 中,后者被定义为HWND 型态(「窗口句柄型态」)。
//Windows 中的每个窗口都有一个句柄,程序用句柄来使用窗口。许多Windows 函数需要使用hwnd 作为参数,这样,Windows 才能知道函数是针对哪个窗口的。
//如果一个程序建立了许多窗口,则每个窗口均有一个句柄。窗口句柄是Windows 程序所处理最重要的句柄之一
//在CreateWindow()之后,ShowWindow()之前,操作系统第一次调用回调函数WndProc
//此处产生程序的第一个消息,WM_CREATE消息
//显示窗口
ShowWindow(hwnd, iCmdShow);
//刷新窗口
UpdateWindow(hwnd);
//消息循环
while (GetMessage(&msg, NULL, 0, 0)) //从程序消息队列中获取消息,第一个参数为MSG消息结构变量,Windows 用从消息队列中取出的下一个消息来填充消息结构的各个字段
//第二、第三和第四个参数设定为NULL 或者0,表示程序接收它自己建立的所有窗口的所有消息。
{
TranslateMessage(&msg); //翻译键盘消息
DispatchMessage(&msg); //将消息发送给操作系统,然后由操作系统调用WinProc函数
}
return msg.wParam;
}
//窗口回调函数,由操作系统调用,只需要将函数的地址赋值给WNDCLASS中的lpfnWndProc参数即可
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc; //定义设备内容句柄
PAINTSTRUCT ps; //定义绘图结构体变量
RECT rect; //定义矩形结构变量
switch (message)//判断消息类型
{
case WM_CREATE://此消息是应用程序发送的第一个消息,在生命周期内只有一次,表示应用程序创建
MessageBox(NULL, TEXT("触发WM_CREATE消息"), "HelloWin", MB_OK);
return 0;
case WM_PAINT://窗口重绘函数,将窗口重新绘制。当窗口显示区域的一部分显示内容或者全部变为「无效」,以致于必须「更新画面」时,将由这个消息通知程序。
//开始绘制
hdc = BeginPaint(hwnd, &ps);
//获取窗口显示区域大小
GetClientRect(hwnd, &rect);
//在客户区绘制文字,内容为Hello Win
DrawText(hdc, TEXT("Hello Win"), -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);//处理一些闲杂以及一些不可预料的消息
}
/*
Windows消息机制特点呢:主动激励,被动响应
所有的消息先传至操作系统,然后由操作系统分配至应用程序
给一个对象发消息等价于调用一个对象的函数
*/
关于Windows消息的相关知识:
消息能够被分为「队列化的」和「非队列化的」。队列化的消息是由Windows 放入程序消息队列中的。在程序的消息循环中,重新传回并分配给窗口消息处理程序。非队列化的消息在Windows 呼叫窗口时直接送给窗口消息处理程序。也就是说,队列化的消息被「发送」给消息队列,而非队列化的消息则「发送」给窗口消息处理程序。任何情况下,窗口消息处理程序都将获得窗口所有的消息--包括队列化的和非队列化的。窗口消息处理程序是窗口的「消息中心」。
队列化消息基本上是使用者输入的结果,以击键(如WM_KEYDOWN 和WM_KEYUP 消息)、击键产生的字符
(WM_CHAR)、鼠标移动(WM_MOUSEMOVE)和鼠标按钮(WM_LBUTTONDOWN)的形式给出。队列化消息还包含时钟消息(WM_TIMER)、更新消息(WM_PAINT)和退出消息(WM_QUIT)。
非队列化消息则是其它消息。在许多情况下,非队列化消息来自呼叫特定的Windows 函数。例如,当WinMain呼叫CreateWindow 时,Windows 将建立窗口并在处理中给窗口消息处理程序发送一个WM_CREATE 消息。当WinMain 呼叫ShowWindow 时,Windows 将给窗口消息处理程序发送WM_SIZE 和WM_SHOWWINDOW 消息。当WinMain 呼叫UpdateWindow 时,Windows 将给窗口消息处理程序发送WM_PAINT 消息。键盘或鼠标输入时发出的队列化消息信号,也能在非队列化消息中出现。例如,用键盘或鼠标选择了一个菜单项时,键盘或鼠标消息就是队列化的,而说明菜单项已选中的WM_COMMAND 消息则可能就是非队列化的。这一过程显然很复杂,但幸运的是,其中的大部分是由Windows 解决的,不关我们的程序的事。从窗口消息处理程序的角度来看,这些消息是以一种有序的、同步的方式进出的。窗口消息处理程序可以处理它们,也可以不处理。
摘录于《Windows程序设计》