消息:
MSG 结构体
1.hWnd 消息属于哪个窗口
2.消息
3.lParam
4.wParam
事件 -> 封装成消息 -> 存入消息队列 -> 消息响应
消息产生后 进入消息队列
应用程序 从消息队列中获取消息
获取到消息后 翻译消息
翻译好之后 派发消息 发送给每个窗口
窗口接收到调用消息处理函数 WndProc
系统消息队列: os message queue
操作系统维护的队列
例如:鼠标消息 键盘消息
应用程序消息队列:
应用程序来维护 存放当前应用程序的消息 WM_PAINT 绘图
系统消息:
操作系统已经定义好了。 WM_ 0-0x3FF 1024
1111111111
用户消息(自定义消息): WM_USER 0x400 - 0x7FF
队列消息:
存储和取出都要经过消息队列
WM_PAINT
非队列消息:
不需要存储 直接处理
WM_CREATE : 窗口被创建后,显示前发送的消息
WM_SIZE : 窗口大小被改变的时候产生并发送的消息
PeekMessage:非阻塞方式接受消息
检查消息队列,如果有消息就看最后一个参数:
最后一个参数为False 0: 直接返回1
最后一个参数为true : 从消息队列中删除消息然后返回1
如果消息队列中没有消息
直接返回0
GetMessage:从消息队列中获取一个消息存放到MSG结构体中
从消息队列中获取消息,如果当前程序消息队列中有消息。
把消息存入MSG,删除当前程序消息队列里的消息。返回非0。直到遇到WM_QUIT消息才返回0.
如果当前程序消息队列中没有消息。
去系统消息队列里看有没有消息
有消息:
把系统消息队列中的消息放入当前程序消息队列。
没有消息:
检查窗口是否需要重新绘制
需要重新绘制:
发送WM_PAINT消息
不需要重新绘制:
查看是否有定时器
有定时器:
处理定时器消息
没有定时器:
优化资源,处理内存,然后继续等待
#include
#include
#include "resource.h"
HINSTANCE g_hInstance;
HANDLE g_hConsole; //命令行窗口句柄
HCURSOR g_hCursor1, g_hCursor2;
void OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hParInstance,
LPSTR lpCmdLine,
int nCmd
)
{
g_hInstance = hInstance;
//1.注册窗口类
WNDCLASSEXW wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpszClassName = L"firstWindow";
wc.lpfnWndProc = WndProc;
wc.hbrBackground = NULL;
wc.hCursor = NULL;//LoadCursor(g_hInstance, MAKEINTRESOURCE(IDC_CURSOR1));
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)); //图标
wc.hIconSm = NULL; //小图标
wc.hInstance = hInstance;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassExW(&wc);
//2.创建窗口
HWND hWnd = CreateWindowExW(
NULL,
wc.lpszClassName,
L"我的第一个窗口",
WS_OVERLAPPEDWINDOW,
500, 500,
600, 600,
NULL,
NULL,
wc.hInstance,
NULL
);
if (!hWnd)
{
MessageBoxExW(NULL, L"未创建窗口", L"提示", MB_OK, 0);
}
//3.显示窗口
ShowWindow(hWnd, nCmd);
//4.刷新窗口
UpdateWindow(hWnd);
AllocConsole();
g_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
g_hCursor1 = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));
g_hCursor2 = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR2));
//5.消息循环
MSG msg;
BOOL bRet;
while (true)
{
if (PeekMessageW(&msg, nullptr, 0, 0, false))
{
if ((bRet = GetMessage(&msg, nullptr, 0, 0)) != 0)//检测到窗口退出,返回0,不退出,返回非0
{
if (bRet == -1)
{
//出现错误
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
break;
}
}
}
return 0;
}
//5.消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
EndPaint(hWnd, &ps);
break;
}
case WM_MOUSEMOVE:
{
OnMouseMove(hWnd, wParam, lParam);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return NULL;
}
void OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
int y = HIWORD(lParam);
int x = LOWORD(lParam);
WCHAR buf[256] = { 0 };
swprintf(buf, L"(%d, %d)\n", x, y);
WriteConsole(g_hConsole, buf, wcslen(buf), NULL, NULL);
RECT rect;
GetWindowRect(hWnd, &rect);
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
if (x < width / 2)
{
SetClassLongPtrW(hWnd, GCL_HCURSOR, (LONG_PTR)g_hCursor1);
}
else
{
SetClassLongPtrW(hWnd, GCL_HCURSOR, (LONG_PTR)g_hCursor2);
}
}