windows消息机制_PostMessage和SendMessage
1.子线程中建立一个窗口
为了在后面比较这两个函数,先使用win32 windows程序中建立子线程,在子线程中建立一个窗口。
(1)新建一个 win32 windows应用程序
(2)定义子窗口的窗口响应函数
LRESULT CALLBACK SubWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
MessageBoxA(0,"","SubWndProc",0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
(3)定义子线程窗口函数
void CreateWndInThread(int nWidth, int nHeight)
{
WNDCLASSEX wcex2;
wcex2.cbSize = sizeof(WNDCLASSEX);
wcex2.style = CS_HREDRAW | CS_VREDRAW;
wcex2.lpfnWndProc = SubWndProc;
wcex2.cbClsExtra = 0;
wcex2.cbWndExtra = 0;
wcex2.hInstance = GetModuleHandle(nullptr);
wcex2.hIcon = 0;
wcex2.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex2.lpszMenuName = NULL;
wcex2.lpszClassName = L"SubWindow";
wcex2.hIconSm = 0;
RegisterClassEx(&wcex2);
HWND g_hWnd = CreateWindowA("SubWindow", nullptr,WS_OVERLAPPEDWINDOW, 0, 0, nWidth, nHeight, NULL, NULL, wcex2.hInstance, 0);
ShowWindow(g_hWnd, SW_SHOW);
UpdateWindow(g_hWnd);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
(4)处理主线程的 WM_LBUTTONDOWN 消息
在里面开启一个子线程,调用 CreateWndInThread
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{ case WM_LBUTTONDOWN:
{
std::thread t(CreateWndInThread, 960, 480);
t.detach();
}
break;
//省略其他消息
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
(5)运行程序
在主窗口上鼠标左键点击,会创建一个子窗口,
然后在子窗口上鼠标左键点击,会弹出一个MessageBox。
可以发现两个窗口的消息处理互不影响。
2.PostMessage和SendMessage
PostMessage会将消息压入窗口所在线程的消息队列,然后立即返回,非阻塞
SendMessage则不经过消息队列,SendMessage可认为是直接调用了该窗口的窗口过程,阻塞
将上面的项目做如下修改:
(1)定义一个全局遍历来存储子窗体的句柄,定义子窗体自定义消息
#define WM_SUB_MSG (WM_USER+1)
HWND subWinHwnd;//子窗口
(2)修改子窗口的窗口响应函数
void CreateWndInThread(int nWidth, int nHeight)
{
WNDCLASSEX wcex2;
wcex2.cbSize = sizeof(WNDCLASSEX);
wcex2.style = CS_HREDRAW | CS_VREDRAW;
wcex2.lpfnWndProc = SubWndProc;
wcex2.cbClsExtra = 0;
wcex2.cbWndExtra = 0;
wcex2.hInstance = GetModuleHandle(nullptr);
wcex2.hIcon = 0;
wcex2.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex2.lpszMenuName = NULL;
wcex2.lpszClassName = L"SubWindow";
wcex2.hIconSm = 0;
RegisterClassEx(&wcex2);
subWinHwnd = CreateWindowA("SubWindow", nullptr,WS_OVERLAPPEDWINDOW, 0, 0, nWidth, nHeight, NULL, NULL, wcex2.hInstance, 0);
ShowWindow(subWinHwnd, SW_SHOW);
UpdateWindow(subWinHwnd);
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
(3)修改子线程窗口函数
LRESULT CALLBACK SubWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_SUB_MSG:
MessageBoxA(0,"WM_SUB_MSG","子窗体",0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
MessageBoxA(0,"左键消息","子窗体",0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
(4)修改主窗口的窗口函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_LBUTTONDOWN:
{
std::thread t(CreateWndInThread, 960, 480);
t.detach();
}
break;
case WM_RBUTTONDOWN:
{
SendMessage(subWinHwnd,WM_SUB_MSG,0,0);
//PostMessage(subWinHwnd,WM_SUB_MSG,0,0);
MessageBoxA(0,"右键消息","主窗体",0);
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(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:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
(5)运行程序
发现使用SendMessage(subWinHwnd,WM_SUB_MSG,0,0) ,
MessageBoxA(0,"右键消息","主窗体",0) 对话框在 MessageBoxA(0,"WM_SUB_MSG","子窗体",0) 后面出现
使用PostMessage(subWinHwnd,WM_SUB_MSG,0,0)
MessageBoxA(0,"右键消息","主窗体",0) 对话框在MessageBoxA(0,"WM_SUB_MSG","子窗体",0) 前面出现
(6)完整代码链接:https://www.aliyundrive.com/s/UtrYB42wyi3
总结:
PostMessage会将消息压入窗口所在线程的消息队列,然后立即返回,非阻塞
SendMessage则不经过消息队列,SendMessage可认为是直接调用了该窗口的窗口过程,阻塞
windows消息机制_PostMessage和SendMessage的更多相关文章
- 收藏:Windows消息机制
百度百科介绍的windows消息机制也不错:http://baike.baidu.com/view/672379.htm Windows的应用程序一般包含窗口(Window),它主要为用户提供一种可视 ...
- 转:Windows消息机制要点
Windows消息机制要点 1. 窗口过程 每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ...
- windows消息机制(转)
1. 引言Windows 在操作系统平台占有绝对统治地位,基于Windows 的编程和开发越来越广泛.Dos 是过程驱动的,而Windows 是事件驱动的[6],这种差别的存在使得很多Dos 程序员不 ...
- 深入理解windows 消息机制
深入理解Windows消息机制 今天我们来学一学Windows消息机制,我们知道在传统的C语音程序中,当我们需要打开一个文件时,我们可以调用fopen()函数,这个函数最后又会调用操作系统提供的函数以 ...
- Windows消息机制
Windows的消息系统是由3个部分组成的: · 消息队列.Windows能够为所有的应用程序维护一个消息队列.应用程序必须从消息队列中获取消息,然后分派给某个窗口.· 消息循环.通过这个循环机制应用 ...
- 我对windows消息机制的理解(参考深入浅出MFC,欢迎批评指正!!)
以消息为基础,以事件驱动之 程序的进行依靠外部消息来驱动,即:程序不断等待任何可能的输入,然后做判断,然后再做适当的处理. 消息输入:操作系统捕获,以消息形式进入程序.(操作系统通过其USERS模块中 ...
- <Win32_1>深入浅出windows消息机制[转自crocodile_]
上学期学习了Java ,感觉Java写一个窗口真心简单,很易上手,也就难怪很多开发人员选择Java作为自己的开发编程语言.但是由于自身对windows的热爱,让我觉得c.c++语言才是我亲睐的编程语言 ...
- 深入Delphi -- Windows 消息机制
http://www.txsz.net/xs/delphi/3/Windows%20%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6.htm Windows 消息机制 by m ...
- windows消息机制框架原理【简单版本】
windows消息机制框架原理 结合两张图理解 窗口和窗口类 Windows UI 应用程序 (e) 具有一个主线程 (g).一个或多个窗口 (a) 和一个或多个子线程 (k) [工作线程或 UI 线 ...
- Windows消息机制详解
消息是指什么? 消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...
随机推荐
- 【Anaconda】为右键菜单添加“当前位置开启Anaconda Prompt”
Stack Overflow 上查找到该解决方法:『Adding "Open Anaconda Prompt here" to context menu (Windows) - S ...
- java 基本知识点
多线程 加载器 数据结构 内存模型 gc算法
- Npoi.Mapper 日期转换
问题:Excel文档里有一些列是日期类型的数据,使用Mapper默认的转换,发现生成的实体,在有的系统环境下能正常转换,但是在有的系统环境下,转换的日期出现中文. 猜想是Excel文档里,日期列的单元 ...
- 记一次mysql5.7保存Emoji表情
1.错误:SQLException; SQL state [HY000]; error code [1366]; Incorrect string value: '\xF0\x9F\x90\x96 \ ...
- sap IUT240 Contract Accounts Receivable and Payable pdf
sap IUT240 Contract Accounts Receivable and Payable pdf sap IUT240 Contract Accounts Receivable and ...
- Pycharm实现sqlite数据库可视化
- ABAP 选择屏幕内的组件以及使用
选择屏幕组件 主要记录了ABAP编程中选择屏幕常用的组件 选择框 范围选择框 radio单选 check选择 单行展现 配合radio和check使用较多 下拉框 自定义下拉框 按钮 文件框 文字帮助 ...
- window java 字节码修改
前提: win10 安装包: 1. JDK10.0.1.msi (包含jre环境), JDK的安装路径 2. jclasslib 6.0.3 用于编辑常量 3.JBE 用于编辑 ...
- Unity 消息机制
最近有新项目需要和同事合作开发,他做UI 我做网络层,做着做着发现 如果我们要相对独立完成自己的开发任务,那我们的代码耦合得减少,不然 一个人代码有大改的时候,另一个人也要进行大幅修改,这样不便于后期 ...
- 找着CA证书位置
php -r "print_r(openssl_get_cert_locations());"