1.消息基础
1.消息的概念和作用
消息的组成:
窗口句柄
消息ID
消息的两个参数(两个附带信息)
消息产生的时间
消息产生时的鼠标位置
消息的作用
当系统通知窗口工作时,就采用消息的方式派发给窗口的窗口处理函数
2.窗口处理函数
窗口处理函数模板:
LRESULT CALLBACK WindowProc(
HWND hwnd,//窗口句柄
UINT uMsg,//消息ID
WPARAM wParam,//消息参数
LPARAM IParam//消息参数
){}
当系统通知窗口时,会调用窗口处理函数,同时将消息ID和消息参数传递给窗口处理函数。在窗口处理函数中,不处理的消息,使用缺省窗口处理函数。
例如:DefWindowRroc;
3.消息相关函数
GetMessage(
LPMSG lpMsg,//存放获取到的消息BUFF
HWND hWnd,//窗口句柄
UINT wMsgfilterMin,//获取消息最小ID
UINT wMsgFilterMax//获取消息的最大ID
)
lpMsg - 当获取到消息后,将消息的参数存放到MSG结构中。
hWnd - 获取到hWnd所指定的窗口消息,值为NULL时抓取所有消息
wMsgFilterMin和wMsgFilterMax - 只能获取到由它们指定的消息范围内的消息,如果都为0,标识没有范围
GetMessage只抓本进程的消息,返回值是BOOL-- int
PostQuitMessage(0);在GetMessage抓取消息的内存里存入WM_QUIT,GetMessage抓到WM_QUIT返回0;
TranslateMessage - 翻译消息,将按键消息,翻译成字符消息
BOOL TranslateMessage(
CONST MSG *lpMsg//要翻译的消息地址
)
检查按键是否是按键消息,如果不是按键消息,不做任何处理,继续执行(只翻译可见字符按键)
LRESULT DispatchMessage(
CONST MSG * ipmsg//要派发的消息
)
将消息派发到该消息的所属窗口的窗口处理函数上
4.常见消息
-
WM_DESTROY
产生时间:窗口被销毁时的消息
附带消息:wParam : 为0 ;lParam : 为0
一般用法:常用于在窗口被销毁之前,做相应的善后处理,例如资源、内存等。 -
WM_SYSCOMMAND
产生时间:当点击窗口的最大化、最小化、关闭等。
附带信息:wParam : 具体点击的位置,例如关闭SC_CLOSE等;iParam : 鼠标光标的位置。
LOWORD(lParam);//水平位置
HIWORD(lParam);//
垂直位置
一般用法:常在窗口关闭时,提示用户处理。
LRESULT CALLBACK test(HWND hwnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
switch (msgID)
{
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE && MessageBox(hwnd, L"是否关闭?", L"infor", MB_OKCANCEL| MB_ICONEXCLAMATION) == IDOK)
{
PostQuitMessage(0);
}
return 0;
break;
}
return DefWindowProc(hwnd,msgID,wParam,lParam);
}
3.WM_CREATE
产生时间:窗口创建成功但还未显示时
附带信息 : wParam : 为0 ;lParam : 为CREATESTRUCT类型指针,通过这个指针可以获取CreateWindowEx中全部12个参数
一般用法:常用于初始化窗口参数、资源等等,包括创建子窗口等。
4.WM_SIZE
产生时间:在窗口大小发生变化后
附带信息:wParam : 窗口大小变化的原因;lParam : 变换后的大小。
LOWORD(lParam)//变化后的宽度
HIWORD(IParam)//变化后的高度
一般用法: 常用于窗口大小变化后,调整窗口内各个部分的布局。
补充用于查看修改的窗口值:
AllocConsole()//增加dos窗口
HANDLE g_out = 0;//定义一个句柄类型
g_out = GetStdHandle(STD_OUTPUT_HANDLE);//获取一个标准输出句柄
#include <windows.h>
#include <stdio.h>
HANDLE g_out = 0;
void onsize(HWND hwnd,LPARAM lParam)
{
short nwidth = LOWORD(lParam);
short nhight = HIWORD(lParam);
wchar_t szText[256] = { 0 };
wsprintf(szText, L"宽度%d,高度%d", nwidth, nhight);
WriteConsole(g_out, szText, wcslen(szText), NULL, NULL);
}
LRESULT CALLBACK test(HWND hwnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
switch (msgID)
{
case WM_SIZE:
onsize(hwnd, lParam);
break;
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE)
{
if (MessageBox(hwnd, L"是否关闭?", L"infor", MB_OKCANCEL | MB_ICONEXCLAMATION) == IDOK)
{
PostQuitMessage(0);
}
else
{
return 0;
}
}
break;
}
return DefWindowProc(hwnd, msgID, wParam, lParam);
}
int CALLBACK wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
AllocConsole();//增加dos窗口
g_out = GetStdHandle(STD_OUTPUT_HANDLE);
//注册窗口类
WNDCLASS wc = { 0 };
wc.cbClsExtra = 0;//申请缓冲区
wc.cbWndExtra = 0;//申请缓冲区
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);//窗口背景色
wc.hCursor = NULL;//默认光标
wc.hIcon = NULL;//默认图标
wc.hInstance = hInstance;//实例句柄
wc.lpfnWndProc = test;//窗口处理函数
wc.lpszClassName = (LPCWSTR)L"main";//窗口类名称
wc.lpszMenuName = NULL;//不要菜单
wc.style = CS_HREDRAW | CS_VREDRAW;//窗口水平或竖直方向有变化就重绘窗口
RegisterClass(&wc);//将以上所有赋值写入操作系统
//在内存中创建窗口
HWND hwnd = CreateWindow((LPCWSTR)L"main", (LPCWSTR)L"hello world", WS_OVERLAPPEDWINDOW, 100,100, 500, 500, NULL, NULL, hInstance, NULL);
//显示窗口
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
//消息循环
MSG nMSG = { 0 };
while (GetMessage(&nMSG,NULL,0,0))
{
TranslateMessage(&nMSG);
DispatchMessage(&nMSG);//派发消息,将消息交给窗口处理函数处理
}
return 0;
}
5.WM_QUIT
产生时间:程序员发送
附带信息:wParam : PostQuitMessage 函数传递的参数 ; lParam : 0;
一般用法:用于结束消息循环,当GetMessage收到这个消息,会返回FALSE,结束while处理,退出消息循环。