当前位置:网站首页>GetMessage底层机制分析
GetMessage底层机制分析
2022-07-01 18:45:00 【小小bugbug】
GUI线程的消息队列其实上是分为七个子消息队列,
其中有一个子消息队列专门存储sendmessage函数跨线程传递过来的消息
GetMessage内部内层循环会首先去判断sendMessageListHead子消息队列中是否由消息,
如果有则通过调用KeUserModeCallBack返回三环调用对应窗口的窗口过程函数去处理消息,
等所有sendMessageListHead子消息队列中的
消息被处理完后,会依次从其他队列中去获取消息,
这时如果获取到了消息则跳出外层循环GetMessage函数返回;
并把获取的消息传递给dispatchMessage函数处理;
如果没有取得消息就一直反复循环=>GetMessage阻塞的效果
注意在上述过程中处理sendMessageListHead子队列中的消息时,
是在GetMessage函数内部直接调用KeUserModeCallBack最终调用窗口过程函数去处理的;
而对于其他消息只是获取然后返回;
为什么说sendMessageListHead存储的是sendmessage函数跨线程传递过来的消息呢,
因为sendMessage只有跨线程传递时消息才走消息队列,
如果是同一进程sendMessage直接调用对应的窗口过程函数,
不会把消息放入消息队列中即不会把消息放入sendMessageListHead子消息队列
// WinMessage.cpp : 定义应用程序的入口点。
//
#include "framework.h"
#include "WinMessage.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
HWND g_hwnd;
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此处放置代码。
// 初始化全局字符串
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_WINMESSAGE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINMESSAGE));
MSG msg;
SendMessage(g_hwnd, WM_LBUTTONDOWN, 0, 0);//如果sendMessage没有跨线程发送消息 即便注释掉整个消息循环,依然可以调用窗口过程函数=>这时消息不进入消息队列存储了
// 主消息循环:
/* while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }*/
return 0;
}
//
// 函数: MyRegisterClass()
//
// 目标: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINMESSAGE));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINMESSAGE);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目标: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 将实例句柄存储在全局变量中
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
g_hwnd = hWnd;
return TRUE;
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目标: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN://依然被执行
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
边栏推荐
- 下载(导出)pdf模板文件(比如:审批单),报错:Invalid nested tag *** found, expected closing tag ***
- [to.Net] C set class source code analysis
- Love business in Little Red Book
- MySQL common graphics management tools | dark horse programmers
- Is PMP cancelled??
- Learn MySQL from scratch - database and data table operations
- B2B e-commerce platform solution for fresh food industry to improve the standardization and transparency of enterprise transaction process
- Solidity - 合约结构 - 错误(error)- ^0.8.4版本新增
- Dom4j parsing XML, XPath retrieving XML
- Summary of SQL query de duplication statistics methods
猜你喜欢

axure不显示元件库
![Reading the paper [learning to discretely compose reasoning module networks for video captioning]](/img/a2/acdaebeb67ec4bcb01c8ff4bbd1d1e.png)
Reading the paper [learning to discretely compose reasoning module networks for video captioning]

Intensive cultivation of channels for joint development Fuxin and Weishi Jiajie held a new product training conference

Lake Shore低温恒温器的氦气传输线

混沌工程平台 ChaosBlade-Box 新版重磅发布

见证时代!“人玑协同 未来已来”2022弘玑生态伙伴大会开启直播预约

【pytorch记录】自动混合精度训练 torch.cuda.amp

Netease games, radical going to sea

宝,运维100+服务器很头疼怎么办?用行云管家!

PMP是被取消了吗??
随机推荐
混沌工程平台 ChaosBlade-Box 新版重磅发布
Lake Shore continuous flow cryostat transmission line
The intelligent epidemic prevention system provides safety guarantee for the resumption of work and production at the construction site
Methods of finding various limits
[pytorch record] automatic hybrid accuracy training torch cuda. amp
求各种极限的方法
The market value evaporated by 74billion yuan, and the big man turned and entered the prefabricated vegetables
数字化转型企业成功的关键,用数据创造价值
记一次 .NET 差旅管理后台 CPU 爆高分析
ddr4测试-2
PostgreSQL varchar[] 数组类型操作
论文阅读【Discriminative Latent Semantic Graph for Video Captioning】
水产行业智能供应链管理平台解决方案:支撑企业供应链数字化,提升企业管理效益
【org.slf4j.Logger中info()方法】
Solidity - 算术运算的截断模式(unchecked)与检查模式(checked)- 0.8.0新特性
机械设备行业数字化供应链集采平台解决方案:优化资源配置,实现降本增效
How to redraw the header of CListCtrl in MFC
Cdga | if you are engaged in the communication industry, you should get a data management certificate
Lean thinking: source, pillar, landing. I understand it after reading this article
torch.nn.functional.interpolate函数