MsgWaitForMultipleObjects_测试
1、个人感觉:
1.1、MSDN中(https://msdn.microsoft.com/en-us/library/ms684242.aspx),说:
“
dwWakeMask [in]
The input types for which an input event object handle will be added to the array of object handles.
”
ZC: 也就是说,会在 "event object handle"数组的最后 加入一个 事件对象句柄,这个 事件对象句柄 专门用于响应消息的。这里 我将它称为 "消息事件对象句柄"(它对应的对象就称为"消息事件对象")
1.1、MSDN中(https://msdn.microsoft.com/en-us/library/ms684242.aspx),说:
“
The QS_ALLPOSTMESSAGE and QS_POSTMESSAGE flags differ in when they are cleared. QS_POSTMESSAGE is cleared when you call GetMessage or PeekMessage, whether or not you are filtering messages. QS_ALLPOSTMESSAGE is cleared when you call GetMessage or PeekMessage without filtering messages (wMsgFilterMin and wMsgFilterMax are 0). This can be useful when you call PeekMessage multiple times to get messages in different ranges.
”
文中多次提到 "cleared",这里指 "消息事件对象"的状态。
ZC: 我做的测试结果:
QS_ALLPOSTMESSAGE : 只要消息不取走,"消息事件对象"就一直是 有信号的状态(不管是否过滤消息(GetMessage和PeekMessage函数的wMsgFilterMin和wMsgFilterMax参数))。消息被取走后,"消息事件对象" 才会变成 无信号状态。
QS_POSTMESSAGE:就算消息不取走,"消息事件对象" 还是会被设置成 无信号状态。未取走的消息还保留在消息队列中。
2、
3、Delphi
3.1、界面:

3.2、代码:
procedure TfrmMain.btnPost1000Click(Sender: TObject);
var hWnd1 :HWND;
begin
hWnd1 := StrToInt('$'+Trim(edtHWnd.Text));
PostMessage(hWnd1, WM_USER+, , );
end; procedure TfrmMain.btnPost1001Click(Sender: TObject);
var hWnd1 :HWND;
begin
hWnd1 := StrToInt('$'+Trim(edtHWnd.Text));
PostMessage(hWnd1, WM_USER+, , );
end; procedure TfrmMain.btnSend1001Click(Sender: TObject);
var hWnd1 :HWND;
begin
hWnd1 := StrToInt('$'+Trim(edtHWnd.Text));
SendMessage(hWnd1, WM_USER+, , );
end; procedure TfrmMain.btnPostCloseClick(Sender: TObject);
var hWnd1 :HWND;
begin
hWnd1 := StrToInt('$'+Trim(edtHWnd.Text));
SendMessage(hWnd1, WM_CLOSE, , );
end; procedure TfrmMain.btnSetEventClick(Sender: TObject);
var hEvent :Cardinal;
iErr :integer;
begin
hEvent := OpenEvent(EVENT_ALL_ACCESS, false, '__VC_MsgWaitForMultipleObjects_TEST_20180105__');
iErr := GetLastError;
Memo1.Lines.Add('OpenEvent return : '+IntToStr(hEvent)+', GetLastError : '+inttostr(iErr)); SetEvent(hEvent); CloseHandle(hEvent);
end; procedure TfrmMain.btnPost1100Click(Sender: TObject);
var hWnd1 :HWND;
begin
hWnd1 := StrToInt('$'+Trim(edtHWnd.Text));
PostMessage(hWnd1, WM_USER+, , );
end; procedure TfrmMain.btnSend1100Click(Sender: TObject);
var hWnd1 :HWND;
begin
hWnd1 := StrToInt('$'+Trim(edtHWnd.Text));
SendMessage(hWnd1, WM_USER+, , );
end;
4、VC6 测试代码:
#include <windows.h> #include <io.h>
#include <fcntl.h>
#include <stdio.h> HINSTANCE g_hInstance = ;
HWND g_hWnd = ; LRESULT CALLBACK ProcWindow(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void InitConsoleWindow()
{
AllocConsole();
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle((long)handle,_O_TEXT);
FILE * hf = _fdopen( hCrt, "w" );
*stdout = *hf;
} //////////// //////////// //////////// //////////// //////////// //////////// int WINAPI WinMain(
HINSTANCE _hInstance, // 当前 hInstance句柄
HINSTANCE _hPrevInstance, // 之前的 hInstance句柄
LPSTR _lpCmdLine, // 命令行
int _nCmdShow // 显示状态
)
{
g_hInstance = _hInstance; // 程序(.exe)的图标貌似默认是 资源文件中 的第一个图标??
WNDCLASS wndcls = {};
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ProcWindow;
wndcls.cbClsExtra = ;
wndcls.cbWndExtra = ;
wndcls.hInstance = _hInstance;
wndcls.hIcon = LoadIcon(NULL, IDI_ERROR); // 窗口图标
wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);
wndcls.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH); // 背景画刷
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName= "zc20110929";
// 注册窗口类
RegisterClass(&wndcls); g_hWnd = CreateWindowEx(
NULL, //WS_EX_CLIENTEDGE,
wndcls.lpszClassName,
"ZC Window",
WS_OVERLAPPEDWINDOW,
, ,
, ,
NULL,
NULL, //g_hMenu,
_hInstance,
NULL); ShowWindow(g_hWnd, SW_SHOWNORMAL);
UpdateWindow(g_hWnd); MSG msg;
while(GetMessage(&msg, , , ))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return msg.wParam;
} HANDLE g_hEvent = NULL;
//#define PM_QS_POSTMESSAGE ((QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16)
#define PM_QS_POSTMESSAGE ((QS_POSTMESSAGE) << 16) int g_iInc = ; LRESULT CALLBACK ProcWindow(
HWND _hWnd, // 窗口句柄
UINT _uMsg, // 消息ID(identifier)
WPARAM _wParam,
LPARAM _lParam)
{
switch (_uMsg)
{
case WM_USER+:
{
printf("Before MsgWaitForMultipleObjects .\n");
//DWORD dwRtn = MsgWaitForMultipleObjects(1, &g_hEvent, false, INFINITE, QS_SENDMESSAGE);
while ()
{
DWORD dwRtn = MsgWaitForMultipleObjects(, &g_hEvent, false, INFINITE, QS_SENDMESSAGE | QS_POSTMESSAGE);
if (dwRtn == )
break;
printf("MsgWaitForMultipleObjects return %d\n", dwRtn);
/*MSG msg;
::GetMessage(&msg, _hWnd, 2024, 2026);
printf("GetMessage get message : %d\n", msg.message);*/
MSG msg;
//dwRtn = ::PeekMessage(&msg, _hWnd, 2024, 2026, PM_REMOVE | PM_QS_POSTMESSAGE);// PM_QS_POSTMESSAGE
//dwRtn = ::PeekMessage(&msg, _hWnd, 2024, 2026, PM_QS_POSTMESSAGE);// PM_QS_POSTMESSAGE
//printf("PeekMessage get message(1) : %d, %d\n", msg.message, dwRtn);
dwRtn = ::PeekMessage(&msg, _hWnd, , , PM_NOREMOVE | PM_QS_POSTMESSAGE);
printf("PeekMessage get message(2) : %d, %d\n", msg.message, dwRtn);
if (msg.message == WM_CLOSE)
break; if (g_iInc == )
{
::GetMessage(&msg, _hWnd, , );
printf("GetMessage get message : %d\n", msg.message);
}
g_iInc ++;
printf("\t ==> %d\n", g_iInc);
if (g_iInc >= )
{//*
// system("pause");
::GetMessage(&msg, _hWnd, , );
printf("GetMessage get message : %d\n", msg.message);
// ::MessageBox(0, "Text", "caption", 0);
//*/
break;
}
}
/* DWORD WINAPI MsgWaitForMultipleObjects(
_In_ DWORD nCount,
_In_ const HANDLE *pHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds,
_In_ DWORD dwWakeMask
);*/
printf("After MsgWaitForMultipleObjects .\n");
return ;
}
case WM_USER+:
{
printf("WM_USER+1001\n");
return ;
}
case WM_USER+:
{
printf("WM_USER+1100\n");
return ;
}
case WM_CREATE:
{
InitConsoleWindow();
printf("WM_CREATE\n");
g_hEvent = ::CreateEvent(NULL, false, false, "__VC_MsgWaitForMultipleObjects_TEST_20180105__");
printf("HWND : %d , 0x%X\n", _hWnd, _hWnd);
return ;
}
case WM_PAINT:
{
char buf[] = {};
sprintf(buf, "HWND : %d , 0x%08X", _hWnd, _hWnd); HDC hDc;
PAINTSTRUCT ps;
hDc = BeginPaint(_hWnd, &ps);
TextOut(hDc, , , buf, strlen(buf));
EndPaint(_hWnd, &ps);
return ;
// break;
}
case WM_CLOSE:
case WM_DESTROY:
{
DestroyWindow(_hWnd);
PostQuitMessage();
return ;
}
}
return DefWindowProc(_hWnd, _uMsg, _wParam, _lParam);
}
5、
MsgWaitForMultipleObjects_测试的更多相关文章
- SignalR系列续集[系列8:SignalR的性能监测与服务器的负载测试]
目录 SignalR系列目录 前言 也是好久没写博客了,近期确实很忙,嗯..几个项目..头要炸..今天忙里偷闲.继续我们的小系列.. 先谢谢大家的支持.. 我们来聊聊SignalR的性能监测与服务器的 ...
- Apache Ignite之集群应用测试
集群发现机制 在Ignite中的集群号称是无中心的,而且支持命令行启动和嵌入应用启动,所以按理说很简单.而且集群有自动发现机制感觉对于懒人开发来说太好了,抱着试一试的心态测试一下吧. 在Apache ...
- 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...
- TechEmpower 13轮测试中的ASP.NET Core性能测试
应用性能直接影响到托管服务的成本,因此公司在开发应用时需要格外注意应用所使用的Web框架,初创公司尤其如此.此外,糟糕的应用性能也会影响到用户体验,甚至会因此受到相关搜索引擎的降级处罚.在选择框架时, ...
- .NET Core系列 :4 测试
2016.6.27 微软已经正式发布了.NET Core 1.0 RTM,但是工具链还是预览版,同样的大量的开源测试库也都是至少发布了Alpha测试版支持.NET Core, 这篇文章 The Sta ...
- 渗透测试工具BurpSuite做网站的安全测试(基础版)
渗透测试工具BurpSuite做网站的安全测试(基础版) 版权声明:本文为博主原创文章,未经博主允许不得转载. 学习网址: https://t0data.gitbooks.io/burpsuite/c ...
- 在ubuntu16.10 PHP测试连接MySQL中出现Call to undefined function: mysql_connect()
1.问题: 测试php7.0 链接mysql数据库的时候发生错误: Fatal error: Uncaught Error: Call to undefined function mysqli_con ...
- 【初学python】使用python调用monkey测试
目前公司主要开发安卓平台的APP,平时测试经常需要使用monkey测试,所以尝试了下用python调用monkey,代码如下: import os apk = {'j': 'com.***.test1 ...
- CoreCRM 开发实录——Travis-CI 实现 .NET Core 程度在 macOS 上的构建和测试 [无水干货]
上一篇文章我提到:为了使用"国货",我把 Linux 上的构建和测试委托给了 DaoCloud,而 Travis-CI 不能放着不用啊.还好,这货支持 macOS 系统.所以就把 ...
随机推荐
- 10分钟看懂!基于Zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
- Python进阶【第五篇】函数式编程及某些特殊函数
一.函数式编程——Functional Programming 函数式=编程语言定义的函数+数学意义的函数 在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语 ...
- solr 使用指定数据源
1,将solr 解压,我们观察发现它其实即可以是web服务也可以做数据分析 数据库 2,我们在example目录下新建一个hai的文件夹,用于存放数据 参考solr 目录,将solr.xml 复制一份 ...
- 结合sklearn的可视化工具Yellowbrick:超参与行为的可视化带来更优秀的实现
https://blog.csdn.net/qq_34739497/article/details/80508262 Yellowbrick 是一套名为「Visualizers」的视觉诊断工具,它扩展 ...
- JavaScript笔记 #07# 用js写算法
算法盒子初代(为了提高学习算法的热情...) 效果图: 所有代码放在单个html中: <!DOCTYPE html> <html> <head> <meta ...
- linux操作文件和文件夹
rm filerm -rf folder如将/test1目录下的file1复制到/test3目录,并将文件名改为file2,可输入以下命令:cp /test1/file1 /test3/file2 如 ...
- socket编程-阻塞和非阻塞
转自:https://www.cnblogs.com/sunziying/p/6501045.html 建立连接 阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的 ...
- git review filter的一些规则
https://review.openstack.org/#/c/258797/ https://review.openstack.org/#/q/is:closed+(owner:yuntong)+ ...
- [c/c++] programming之路(7)、数据类型转换、偷钱小程序、进制转换
一.数据类型转换 #include<stdio.h> //某些场合,必须进行数据类型转换,以匹配调用 void main0(){ printf();//printf不管你是什么类型,解析失 ...
- tp5 本地安装和调试的问题
安装的时候用官方下载的包或者用composer指定版本号,不要用git,会安装最新的包. 本地配置域名的时候出错,要不就是500要不就是找不到文件,原因是目录路径里的反斜杆加字母t被转义了,改成正斜杠 ...