当前位置:网站首页>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;
}
边栏推荐
- 寶,運維100+服務器很頭疼怎麼辦?用行雲管家!
- Team up to learn! 14 days of Hongmeng equipment development "learning, practicing and testing" practical camp, free of charge!
- Specification of lumiprobe reactive dye indocyanine green
- Instagram 为何从内容共享平台变成营销工具?独立站卖家如何利用该工具?
- Reading the paper [learning to discretely compose reasoning module networks for video captioning]
- DTD建模
- Love business in Little Red Book
- nacos配置文件发布失败,请检查参数是否正确的解决方案
- ECS summer money saving secret, this time @ old users come and take it away
- 【Go ~ 0到1 】 第五天 7月1 类型别名,自定义类型,接口,包与初始化函数
猜你喜欢
EasyGBS主子码流都为H.265时,切换出现花屏如何解决?
案例分享:QinQ基本组网配置
见证时代!“人玑协同 未来已来”2022弘玑生态伙伴大会开启直播预约
微信公众号开发相关流程及功能介绍
Bao, what if the O & M 100+ server is a headache? Use Xingyun housekeeper!
June issue | antdb database participated in the preparation of the "Database Development Research Report" and appeared on the list of information technology and entrepreneurship industries
正则表达式=Regex=regular expression
The intelligent epidemic prevention system provides safety guarantee for the resumption of work and production at the construction site
Solution and summary of Nacos startup failure
Detailed explanation of JUnit unit test framework
随机推荐
Lake Shore - crx-em-hf low temperature probe station
Bao, what if the O & M 100+ server is a headache? Use Xingyun housekeeper!
torch.nn.functional.interpolate函数
研究了11种实时聊天软件,我发现都具备这些功能…
数商云:从规划到落地,五矿集团如何快速构建数字化发展新格局?
下载(导出)pdf模板文件(比如:审批单),报错:Invalid nested tag *** found, expected closing tag ***
PostgreSQL varchar[] array type operation
[pytorch record] automatic hybrid accuracy training torch cuda. amp
Les canaux de culture intensive s'efforcent de développer Fu Xin et Wei Shi jiajie pour organiser une conférence de formation sur les nouveaux produits
Is PMP cancelled??
赋能「新型中国企业」,SAP Process Automation 落地中国
How to solve the problem of splash screen when the main and sub code streams of easygbs are h.265?
正则表达式=Regex=regular expression
ddr4测试-2
uni-app微信小程序一键登录获取权限功能
学习笔记【gumbel softmax】
nacos启动失败问题解决与总结
新版国标GB28181视频平台EasyGBS如何配置WebRTC视频流格式播放?
Task: denial of service DOS
Native JS creates a calendar - supports mouse wheel scrolling to select months - and can be ported to any framework