菜单

澳门金沙国际Windows音信机制

2019年2月4日 - www6165com

本条窗口所属的进度PID =
0xc54,正好是excel的进程,表明ShellExecuteEx确实发送了DDE新闻给excel,而且可执发送的新闻的thread就是主线程

WM_NCCALCSIZE = 131

重回值得高字节表示近日在消息队列中的信息类型。低字节表示从上次GetQueueStatus,GetMessage或者PeekMessage后被参加队列的音讯类型。

InSendMessage

3> 执行”shell_execute.exe test.iqy”

7 TranslateMessage, TranslateAccelerator 
TranslateMessage: 把一个virtual-key音讯转化成字符消息(character
message),并置于当前线程的音信队列中,信息循环下一回取出处理。
TranslateAccelerator:将急速键对应到对应的菜系命令。它会把WM_KEYDOWN 或
WM_SYSKEYDOWN转化成神速键表中相应的WM_COMMAND或WM_SYSCOMMAND音讯,
然后把转化后的 WM_COMMAND或WM_SYSCOMMAND直接发送到窗口进程处理,
处理完后才会回去。

WM_MBUTTONDOWN =519

lParam指向一个函数地址,被调用的将是这些函数,而非窗口进度

GetMessage
应用程序使用该函数重回值来支配是不是终止信息循环,并退出程序。

call stack展现的确是ShellExecuteEx所调用

9 BroadcastSystemMessage 
俺们一般所接触到的音讯都是发送给窗口的,其实,
音讯的收信人能够是丰盛多彩的,它可以是应用程序(applications),
可设置驱动(installable drivers),互联网设施(network drivers),
系统级设备驱动(system-level device drivers)等, 
BroadcastSystemMessage那么些API可以对上述系统组件发送音信。

MFC新闻的处理完毕情势
  初看MFC中的各类信息,以及在脑子中牢固的C++的影响,我们或许很当然的就会想到利用C++的三大特色之一:虚拟机制来落实新闻的传递,可是通过分析,我们来看事情并不是想大家想象的这样,在MFC中音信是透过一种所谓的音信映射机制来处理的。
  为何呢?在潘爱民先生翻译的《Visual
C++技术内幕》(第4版)中提交了详细的案由表达,我再简而言之一回。在CWnd类中大约有110个消息,还有其余的MFC的类呢,算起来音信太多了,在C++中对程序中用到的每一个派生类都要有一个vtable,每一个虚函数在vtable中都要占用一个4字节高低的输入地址,那样一来,对于每个特定项目标窗口或控件,应用程序都亟待一个440KB大小的表来支持虚拟音信控件函数。
  倘使说下边的窗口或控件可以勉强完成的话,那么对于菜单命令音讯及按钮命令新闻吧?因为不一致的应用程序有例外的菜谱和按钮,大家怎么处理呢?在MFC
库的那种新闻映射系统就防止了应用大的vtable,并且可以在拍卖正常Windows新闻的还要处理丝丝缕缕的应用程序的通令新闻。
  说白了,MFC中的信息机制其实质是一张高大的音信及其处理函数的逐条对应表,然后加上分析处理这张表的使用框架之中的有些顺序代码.那样就足以幸免在SDK编程中用到的麻烦的CASE语句。

该函数通过调用窗口进度的法子发送音信,即便窗口属于不一致线程,SendMessage提姆erout将领会消息处理达成才重临或者指定的逾期已经过去,固然窗口就在当前线程,则直接调用窗口进程,并忽略time-out超时

SendNotifyMessage
设若窗口创制于属于发送音信的线程,则调用窗口进度,并等待窗口进度处理达成该新闻。假若是差异线程,则将音信传递到窗口进程,并立时赶回,不等待窗口进度的音信处理进度。


TranslateMessage
1.将虚拟键音讯转换为字符音讯,然后将字符音信发送到调用线程的消息队列中,该字符信息将在下次调用GetMessage或者PeekMessage信息的时候获得到。
2.WM_(SYS)KEYDOWN/UP—>WM_(SYS)_CHAR
3.如果应用程序为了其他目的,处理虚拟键音讯,那么就不该调用TranslateMessage.与一个实例,应用程序不应该在TranslateAccelerator函数重回非0值时调用TranslateMessage

关于音讯和新闻队列
不像基于MS-DOS的应用程序,基于Windows的程序是事件驱动的。他们不做其余突显调…

 

6 GetMessage, PeekMessage 
PeekMessage会马上回去可以保留音讯
GetMessage在有新闻时回来会去除信息

WM_SETICON = 128

非音讯队列方式,直接调用窗口进程,系统当下切换来收到线程执行,发送线程锁住,知道接收线程处理已毕

SendMessageTimeout

类似,我们得以创制一个带窗口的顺序,启动后将其挂起,那时,即便直接双击打开test.iqy也会hang住。

1. 窗口进程 
各种窗口会有一个号称窗口进程的回调函数(WndProc),它富含多个参数,分别为:窗口句柄(Window
Handle),信息ID(Message ID),和七个音讯参数(wParam,
lParam),当窗口收到音信时系统就会调用此窗口进度来处理新闻。(所以叫回调函数)

 

取得线程近来五次准备处理一个音讯的连串时间(GetTickCount)

GetMessageSource
MSGSRC_SOFTWARE_POST表面键盘信息来源software(postmessage标记为software).
MSGSRC_HARDWARE_KEYBOARD 表面新闻来自keyboard. MSGSRC_UNKNOWN

3.1 excel hang在哪里?

8(新闻死锁( Message Deadlocks) 
倘若有线程A和B, 现在有以下下步骤
1) 线程A SendMessage给线程B, A等待音讯在线程B中拍卖后归来
2) 线程B收到了线程A发来的新闻,并展开拍卖, 在处理进程中,B也向线程A
SendMessgae,然后等待从A重临。
因为此时, 线程A正等待从线程B重临, 不可能处理B发来的新闻,
从而导致了/线程A,B彼此等待, 形成死锁。多少个线程也足以形成环形死锁。
可以使用 SendNotifyMessage或SendMessage提姆eout来幸免出现死锁。

应用程序发送此新闻仅当WINDOWS或任何应用程序发出一个伸手须求绘制一个应用程序的一部分;

至于windows操作系统之音信和音信队列

有关音讯和信息队列
不像基于MS-DOS的应用程序,基于Windows的程序是事件驱动的。他们不做任何突显调用来收获输入。而是经过等待系统传递给她们。

系统为应用程序传递所有输入到程序中的不一致窗口。每个窗口都有一个称作窗口进程的函数,用于拍卖所有到该窗口的输入。窗口处理进程处理输入,并将控制重回给系统。

假设一个顶层窗口甘休响应新闻超越两秒,系统将会认为该窗口为非响应状态。在那种场地下,系统将潜伏该窗口并用具有一致Z顺序,地点,尺寸和可视化属性的ghost窗口替代该窗口。那种处境下,允许用户移动它,或者转移他的尺寸,甚至关闭应用程序。然后,那也是单独可以做的动作,因为应用程序现在是不响应的。当在调节意况下,系统不会发出ghost窗口。

本条段子,研究如下大旨:
windows消息
系统以消息的花样传递输入到窗口的处理过程。系统和应用程序均可爆发音信。系统在历次输入事件时,爆发一个新闻,比如,当用于打击,移动鼠标或者点击滚动条一类的控件。应用程序引起系统改变也会导致系统发生新闻,比如一个应用程序改变了系统的字体资源池或者转移了她协调窗口的高低。一个应用程序可以生出这么的新闻,该音信可以引导她的窗口间接执行义务依然和其余应用程序的窗口进行互相。

音讯分类:
系统定义消息
当系统和应用程序交互时,系统发送系统消息,以控制应用程序的操作以及给程序传递输入或者其他音讯。应用程序也得以发送系统音讯,应用程序平日用那些新闻来控制通过事先登记的窗口类创立的窗口的一颦一笑。

新闻常量标记指定了其所属系统预约义新闻系列。前缀确定可以翻译或者处理的音信种类。如下。
AMB/ABN ===application desktop toolbar
acm/acn ===animation control
cb/cbn ===combobox control
ccm ===generatl control
cdm ===common dialog box
dfm ===default contex menu
dl ===drag list box
sb ===status bar
tvm/tvn ===tree view contro
udm/udm === up-down controm
wm === general
……
tcm/tcn === tab control
{
Clipboard Messages Clipboard Notifications Common Dialog Box
Notifications Cursor Notifications Data Copy Message Desktop Window
Manager Messages Device Management Messages Dialog Box Notifications
Dynamic Data Exchange Messages Dynamic Data Exchange Notifications Hook
Notifications Keyboard Accelerator Messages Keyboard Accelerator
Notifications Keyboard Input Messages Keyboard Input Notifications Menu
Notifications Mouse Input Notifications Multiple Document Interface
Messages Raw Input Notifications Scroll Bar Notifications Timer
Notifications Window Messages Window Notifications
}

大致上,windows音信覆盖了一个相比宽的范围,包蕴鼠标键盘,菜单,对话框输入,窗口创设管理,DDE动态数据互换

应用程序定义的新闻
应用程序可以创设新闻,其本人窗口能够采取,也足以用于和其他进度展开互相。

信息标记符的值应用如下:
1.系统保留了0x0000-0x03ff(即wm_user-1),应用程序不得以拔取这个值用于个人音信
2.0×0400(WM_USER)-0x7fff可以用来个人新闻
3.只要应用程序在4.0体系上,你可以使用0x8000(wm_app)-0xbfff于个人信息
4.RegisterWindowMessage重返的值在0XC000-0XFFFF之间。这些函数的重返值,可以避免任何进程用同一值而引起的争辩

音讯路由
利用使用二种形式来窗口进程音讯的门路:post类信息是通过先进先出的音讯队列方式,音信队列是暂时存储新闻的种类定义内存对象,以及sending类新闻直接到达窗口进程。

队列音讯1
系统在同一时间可以显示任意数量的窗口。为了路由鼠标键盘输入到正确的窗口,系统运用了新闻队列。

系统保证了一个种类新闻队列,并为每个GUI线程维护了而一个线程专有音信队列。为了防止为非GUI线程过多创建音信队列,所有线程在创即刻没有信息队列。系统仅仅在线程第四次发起某个专门用户函数时,创造线程新闻队列;没有GUI函数调用将唤起音讯队列的创制。

未懂:
The system creates a thread-specific message queue only when the thread
makes its first call to one of the specific user functions; no GUI
function calls result in the creation of a message queue.

队列音信2
其余时候,用户移动鼠标,点击按钮或者敲击键盘,鼠标或者键盘驱动将更换这个输入为音讯,并将它们放到系统音讯队列中。系统在检测它们的目窗口时,同时从系统音讯队列中移除它们。然后将她们发送到信息相关窗口的窗口创立线程。线程从它们的音讯队列中吸纳所有鼠标和键盘音信。线程从它们的种类中去除信息,并引导系统将它们发送到正确的窗口进程进展处理。

除了WM_PATIN,WM_TIMER,WM_QUIT音信外,系统平素将它们发送到音信队列的尾声,以担保输入新闻的FIFO种类,仅当新闻对用中从未其余音讯随后,WM_PATIN,WM_TIMER,WM_QUIT才被向前推至窗口处理进度。再不怕,多少个WM_PAINT新闻将被统一为一个,确定所有客户端无效区域到一个独立的区域。合并WM_PATINT就是为着减小窗口冲回客户区内容的次数。

从音讯队列中删去一个新闻后,应用程序将用DispatchMessage函数direct系统发送这么些信息到窗口处理进度以紧凑处理。DispatchMessage没有发送音信地点和岁月到窗口进程,应用程序能够透过Getmessage提姆e和GetMessagePos函数。

当信息队列中从未音讯的时候,线程可以利用WaitMessage函数来将控制器交给其余线程,那么些函数暂停线程,知道一个新音讯赶到,该函数才回来。

您也可以调用SetMessageExtraInfo来为当下音讯队列附加一个值,通过GetMessageExtraInfo来获取那么些值。

非队列音信
绕过了系统和线程信息队列,非队列新闻直接发送至窗口进程。系统独立发送非队列信息来打招呼一个窗口,一个事件影响了它。例如,当用户激活一个新窗口,系统发送给窗口
WM_ACTIVATE, WM_SETFOCUS, and
WM_SETCURSOR音信。那些音信通告窗口它已经被激活了,键盘输入正指向该窗口,鼠标光标已经移至了窗口边框内。当应用程序调用某些系统函数时,也会窗口非队列信息,比如,应用程序在调用SetWindowPos时,系统将发送WM_WINDOWPOSCHANGED消息。

有点音讯发送非队列音信:BroadcastSystemMessage,
BroadcastSystemMessageEx, SendMessage, SendMessage提姆eout, and
SendNotifyMessage.

消息处理
三十二线程应用程序,会在各类成立了窗口的线程包涵一个音讯队列。

MSG msg;
BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
一个应用程序能够通过调用PostQuitMessage来截止其自己的新闻循环,响应应用程序主窗口的WM_DESTROY音讯,就相比典型。

PostMessage发送一个NULL窗口句柄的信息,该音讯将会被放在脚下线程信息队列中,应用程序必须处理那个新闻。PostMessage也足以经过HWND_TOPMOST
句柄来给所有顶层窗口发送音信。

PostMessage一贯可以成功发送音讯,常常是一个张冠李戴的只要,比如音讯队列是满的。一个应用程序应该查对PostMessage的重回值。如若战败了,要求重新发送音信。

SendMessage平常用户父子窗口之间的彼此。

SendMessageCallback函数发送一个音讯,并随即重返,窗口进程在拍卖完这些信息后,系统将调用指定的回调函数。该回调函数的切切实实,请看SendAsyncProc

偶尔,你或许想向装有顶层窗口发送新闻。例如,应用程序改变了岁月,可以由此SendMessage,并制订HWND_TOPMOST,发送WM_TIMECHANGE.你也足以透过BroadcastSystemMessage函数,并给lpdwRecipients参数制定BSN_APPLICATIONS

音信死锁
1.SendMessage会守候窗口进度处理达成后才回去,假诺窗口进度此时所在线程激昂控制权扬弃,那么僵上午死锁。
2.一旦收到线程附加到了和发送线程同一个音信队列,也将造成应用程序死锁的出殡

留意,正在接受新闻的线程,不应当显得扬弃控制权;调用上面函数将唤起线程隐私甩掉控制权。
DialogBox
?DialogBoxIndirect
?DialogBoxIndirectParam
?DialogBoxParam
?GetMessage
?MessageBox
?PeekMessage
?SendMessage

为了幸免地下死锁,考虑采取SendNotifyMessage或者SendMessage提姆eout。要不然,窗口进度能够透过InSendMessage或者InSendMessageEx检测其接收到的新闻是不是来自其余线程.在拍卖一个新闻时,在调用上边列表中任何函数前,窗口进度应该调用InSendMessage(Ex).借使回去TRUE,窗口进度必须在yeild前,调用ReplyMessage函数。

系统广播音信-略

总结:
1.新闻分为系统定义音信和用户自定义音信,其ID值皆有和好的限量。
2.各种线程默许是未曾音信队列的,线程只有在第三遍调用用户接口时(比如成立窗口),系统才为其成立音讯队列。
3.连串本身爱护一个系统音讯队列,然后还为每个GUI线程线程维护一个线程专门音信队列。
4.鼠标、键盘等驱动,首先将事件转换为音信放置在系统信息队列中,然后系统又通过窗口来确定将其放入到哪些线程信息队列中。
5.线程音讯循环取出音讯,举办处理,将音讯再派发给系统,系统调用音讯对应的窗口进程。
6.PostMessage不一定成功,比如队列是满的。
7.防止新闻死锁,比如收受消息的窗口进程,在弃权前,必要检测音讯是不是发自其余线程。否则其余线程将长日子等待。其实我倍感这里不可能成为死锁嘛,毕竟如故可能再履行的,只是岁月长短而已。
8.内需专注wm_paint,wm_timer,wm_quit等相当音信
9.种类预订义信息其实大都是那一个控件音信,通告新闻,系统广播新闻等等。

NtUserMessageCall(HWND_BROADCAST, WM_DDE_INITIATE)

5 PostMessage(PostThreadMessage), SendMessage 
PostMessage:把信息放到指定窗口所在的线程音信队列中后及时回去。
PostThreadMessage:把音信放到指定线程的音讯队列中后旋即赶回。
SendMessage:直接把新闻送到窗口进度处理,处理完了才回去。

WM_RENDERFORMAT =773

该函数再次回到信息x,y坐标,在多重monitor下,可能有负值。

GetMessageQueueReadyTimeStamp

澳门金沙国际 1

4 队列音讯(Queued Messages)和非队列音信(Non-Queued Messages)
1)队列音信(Queued Messages)
 
新闻会先保存在新闻队列中,音信循环会从此队列中取音信并散发到各窗口处理
如鼠标,键盘音信。
2) 非队列信息(NonQueued Messages) 信息会绕过系统音信队列和线程音信队列间接发送到窗口进程被拍卖
如: WM_ACTIVATE, WM_SETFOCUS, WM_SETCURSOR, WM_WINDOWPOSCHANGED 
小心: postMessage发送的音讯是队列音信,它会把信息Post到信息队列中;
SendMessage发送的音信是非队列音信, 被直接送到窗口进度处理

在windows绘制新闻框前发送此新闻给信息框的主人窗口,通过响应这条音信,所有者窗口可以

用于判断当前窗口进度所拍卖的音信,是还是不是来自其它线程的SendMessage调用。

PeekMessage
1.该函数核对线程音讯队列中是还是不是有音讯,并将新闻放在参数结构体中
2.比方hWnd参数=-1,则只回去hWnd=NULL的新闻,那种音讯来自PostThreadMessage
3.参数wRemoveMsg要求专注

3> Post WM_DDE_EXECUTE给excel,告知打开test.iqy的授命

3 消息队列(Message Queues) 
Windows中有二种档次的消息队列
1) 系统音信队列(System Message Queue) 那是一个系统唯一的Queue,设备驱动(mouse,
keyboard)会把操作输入转化成音信存在系统队列中,然后系统会把此音信放到目标窗口所在的线程的音信队列(thread-specific
message queue)中伺机处理
2) 线程音讯队列(Thread-specific Message Queue) 每一个GUI线程都会珍爱这么一个线程新闻队列。(这些队列唯有在线程调用GDI函数时才会成立,默许不创制)。然后线程音讯队列中的信息会被送到对应的窗口进度(WndProc)处理.
留意:
线程信息队列中WM_PAINT,WM_TIMER唯有在Queue中并未任何音信的时候才会被处理,WM_PAINT音信还会被合并以提升功用。其余所有音信以先进先出(FIFO)的法子被处理。

WM_DDE_FIRST = 992

音信相关函数:

DispatchMessage

LONG DispatchMessage(
const MSG* lpmsg
);
1.该函数将音信,通过系统派发给窗口进度
2.只假若一个定时器信息,lParam参数不是空,

3.3 总结

2 信息类型 
1) 系统定义信息(System-Defined Messages)
 
在SDK中优先定义好的新闻,非用户定义的,其范围在[0x0000, 0x03ff]里面,
可以分成以下三类:
1>窗口音信(Windows Message) 
与窗口的中间运转有关,如创设窗口,绘制窗口,销毁窗口等。可以是一般的窗口,也可以是Dialog,控件等。
如:WM_CREATE, WM_PAINT, WM_MOUSEMOVE, WM_CTLCOLOR, WM_HSCROLL…
2>命令音讯(Command Message):注意那类音信通称为WM_COMMAND
与处理用户请求有关, 如单击菜单项或工具栏或控件时, 就会生出命令消息。
WM_COMMAND, LOWORD(wParam)表示菜单项,工具栏按钮或控件的ID。假使是控件,
HIWORD(wParam)表示控件消息类型
3> 控件公告(Notify Message) 
控件公告信息, 那是最灵敏的音信格式, 其Message, wParam,
lParam分别为:WM_NOTIFY,
控件ID,指向NMHDR的指针。NMHDR包罗控件通告的内容, 可以随心所欲扩张。
2) 程序定义音讯(Application-Defined Messages) 
用户自定义的信息, 对于其范围有如下规定:
WM_USER: 0x0400-0x7FFF    (ex. WM_USER+10)
WM_APP(winver>4.0): 0x8000-0xBFFF (ex.WM_APP+4)
RegisterWindowMessage: 0xC000-0xFFFF

/////////////////////////////////////////////////////////////////////

该函数只是不难注明被呼吁终止的线程将会终止。接收WM_QUIT的线程,应该为止音信循环,并将控制权交给系统。重回给系统的退出值,一定是WM_QUIT的wParam参数

BOOL PostThreadMessage(
DWORD idThread,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);

接到音讯的线程,通过GetMessage/PeekMessage来获取音信,hWnd成员将会是空


RegisterWindowMessage
同一字符串,注册的值,在任何种类中是唯一的


SendMessage

澳门金沙国际 2

当用户在运动窗口时发送此音信,通过此音讯应用程序能够监视窗口大小和职位

比方发送音讯低于WM_USER范围,到异步消息队列函数(PostMessage、SendNotifyMessage),音讯参数不应当包括指针,不然的话,操作将破产。该函数将在吸纳线程有时机处理该音讯前回到,发送者将释放刚刚用到的内存。

PostQuitMessage

2> 运行http_server.py(需先安装python)

WM_ASKCBFORMATNAME= 780

4.借使应用程序正在开创顶层窗口时调用PeekMessage,将导致窗口窗口被创制在Z-Order的最后。你需求在PeekMessage后,显式调用SetForegroundWindow。借使应用程序以及有一个放权窗口了,那么新窗口将被置于。

PostMessage
应用程序要用HWND_BROADCAST举行程序间的互相,新闻应该赢得于RegisterWindowMessage()

澳门金沙国际 3

WM_SYSTEMERROR = 23

该函数将获得和hWnd或者其子窗口相关的新闻。

DWORD GetMessagePos(void);

1. 问题

WM_KILLFOCUS = 8

信息来源未知

DWORD GetQueueStatus(
UINT flags
);
在音信队列中的信息的品种
flags为要检测的音信类型。

2> 然后创立一个”WorkerW”的窗口用于DDE通讯

WM_NCCREATE = 129

4> ShellExecuteEx执行达成,但并不destroy “WorkerW”窗口

WM_CTLCOLOREDIT =307

小心到下一个API GetWindowThreadProcessId ( 0x00310172 , 0x0012fb70
),刚好是收获这几个窗口的pid和tid,查看下参数窗口:

WM_UPDATEUISTATE =296

澳门金沙国际 4

WM_KEYLAST = 264

澳门金沙国际 5

消息名称

说 明

LBN_DBLCLK

用户双击了一项

LBN_ERRSPACE

列表框内存不足

LBN_KILLFOCUS

列表框正在失去输入焦点

LBN_SELCANCEL

用户选择被取消

LBN_SELCHANGE

用户选择将改变

LBN_SETFOCUS

列表框获得输入焦点

1> ShellExecuteEx打开test.iqy的时先创造excel进度

知父窗口。公告新闻只适用于专业的窗口控件如按钮、列表框、组合框、编辑框,以及Windows
95公

翻开一下buff的地点:

//双击鼠标中键

因为双击打开实际是用explorer.exe打开,而explorer.exe是有窗口的,可以健康的接受处理WM_DDE_INITIATE消息

  表A-3  文告音信-按钮

 

WM_GETFONT = 49

5>
excel收到WM_DDE_EXECUTE信息后会广播WM_DDE_INITIATE信息,”WorkerW”窗口所在的console进度由于没有概念新闻处理函数,ShellExecuteEx定义的”WorkerW”窗口音讯处理函数得不到CPU执行机会,导致不会response该音讯,从而造成excel
hang住

 

3.2 为了验证3.1.1的猜度,用API Monitor一下ShellExecuteEx

WM_MOUSEFIRST = 512

正要就是打开test.iqy的下令,表达ShellExecuteEx就是先创制了excel的长河,然后发送test.iqy的文书命令给excel打开。

一个窗口被激活或失去激活状态;

5.1 在API Monitor中看下PostMessageW

  
首先,GetMessage从进度的主线程的新闻队列中获取一个音信并将它复制到MSG结构,如若队列中绝非音信,则GetMessage函数将等待一个音信的过来将来才回去。假如你将一个窗口句柄作为首个参数传入GetMessage,那么唯有指定窗口的的音讯可以从队列中赢得。GetMessage也足以从信息队列中过滤音信只接受新闻队列中落在限制内的音讯。这时候就要选拔GetMessage/PeekMessage指定一个音信过滤器。这么些过滤器是一个音讯标识符的界定或者是一个窗体句柄,或者双方同时指定。当应用程序要摸索一个后入消息队列的音讯是很有用。WM_KEYFIRST
和 WM_KEYLAST 常量用于接受所有的键盘音讯。 WM_MOUSEFIRST 和
WM_MOUSELAST 常量用于接受所有的鼠标音讯。 
 然后TranslateAccelerator判断该信息是还是不是一个按键音讯还假如一个加快键音讯,要是是,则该函数将把多少个按键音信转换成一个加快键信息传递给窗口的回调函数。处理了加快键之后,函数TranslateMessage将把多少个按键新闻WM_KEYDOWN和WM_KEYUP转换成一个
WM_CHAR,然而要求留意的是,音信WM_KEYDOWN,WM_KEYUP如故将传递给窗口的回调函数。     
 处理完之后,DispatchMessage函数将把此新闻发送给该音信指定的窗口中已设定的回调函数。倘诺音讯是WM_QUIT,则
GetMessage重返0,从而退出循环体。应用程序可以采用PostQuitMessage来甘休自己的新闻循环。经常在主窗口的
WM_DESTROY音信中调用。
 上边大家举一个普遍的小例子来证实那一个信息泵的运用:

澳门金沙国际 6

WM_DESTROYCLIPBOARD= 775

1> 解压iqy_test.zip

WM_NCRBUTTONDBLCLK= 166

通过可以怀疑是由于console进度在和excel用DDE音讯通讯时,console没有响应excel发送的DDE信息,导致excel
hang住

当用户按住ALT键同时按下别的键时提交此音讯给持有大旨的窗口;

澳门金沙国际 7

WM_SYSDEADCHAR =263

 

message
用于区分其余新闻的常量值,这个常量可以是Windows单元中预订义的常量,也得以是自定义的常量。

澳门金沙国际 8

当一个模态对话框或菜单进入空载状态时发送此音讯给它的主人,一个模态对话框或菜单进入空载状态就是在拍卖完一条或几条先前的新闻后不曾新闻它的列队中伺机

表达excel给持有顶层窗口发送一个WM_DDE_INITIATE信息,然而有窗口没有response

WM_IME_KEYDOWN =656

 

错开宗旨

在API Monitor中摸索一下PostMessage的调用,果然搜到一条

WM_GETICON = 127

查阅参数知excel调用NtUserMessageCall()类似如下:

WM_ICONERASEBKGND =39

bool shell_execute_file(wstring file_path)
{
    SHELLEXECUTEINFOW shell_exec_info = { 0 };
    shell_exec_info.cbSize = sizeof(SHELLEXECUTEINFOW);
    shell_exec_info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
    shell_exec_info.hwnd = NULL;
    shell_exec_info.lpVerb = NULL;
    shell_exec_info.lpFile = file_path.c_str();
    shell_exec_info.lpParameters = NULL;
    shell_exec_info.lpDirectory = NULL;
    shell_exec_info.nShow = SW_SHOW;
    shell_exec_info.hInstApp = NULL;
    bool ret = ShellExecuteExW(&shell_exec_info);
    printf("process handle is %p\n", shell_exec_info.hProcess);

    return ret;
}

WM_MDIRESTORE = 547

 

在WindowsX.h中定义了如下的HANDLE_MSG宏:

4. 怎么双击打开excel不会hang住

hwnd
32位的窗口句柄。窗口可以是任何类型的显示器对象,因为Win32力所能及保证大部分可视对象的句柄(窗口、对话框、按钮、编辑框等)。

注意到win7下PostMessageW是用的线程2调用的,搜一下线程成立API
CreateThread

后边,大家分析了新闻的要旨境论和要旨的函数及用法,接下去,大家将越来越研商新闻传递在MFC中的完结。

shell_execute.exe的主要code:

WM_CHANGECBCHAIN =781

2. 再现步骤

 

 

澳门金沙国际 9

WM_MOVE = 3

据悉DDE的新闻参数,可见wParam就是殡葬音信的窗口,其句柄为2425190 =
0x250166,反向查询知这是ShellExecuteEx创制的”WorkerW”窗口

WM_DDE_ACK = WM_DDE_FIRST+ 4

澳门金沙国际 10

WM_CTLCOLORDLG =310

3. 缘故剖析

一个DDE客户程序提交此音信给一个DDE服务程序来呼吁服务器每当数据项改成时更新它

消息1000为WM_DDE_EXECUTE,Post窗口句柄为0x00310172。

WM_QUERYENDSESSION= 17

3.2.1
依据微软的文档可见,发送DDE音信除了WM_DDE_INITIATE和WM_DDE_ACK之外用的都是PostMessage

WM_WINDOWPOSCHANGED= 71

3.2.2 为了验证3.2.1的结论,在PostMessageW上下断点跟踪一下

经过行使给定的有关突显设备的句柄来安装对话框的文本背景颜色

再次出现环境:XP sp3 / Office 2007(其余office版本应该也得以,没有测试)

次第发送此音信给MDI客户窗口来找到激活的子窗口的句柄

 

WM_CTLCOLORBTN =309

5. 为啥win7上不会有如此的题目

先后发送此音信给editcontrol或combobox从剪贴板中获得数码

3.1.1 用windbg附加到excel上,输入如下命令查看主线程hang住的地点

WM_INPUTLANGCHANGE= 81

当在console中调用API
ShellExecuteEx打开”test.iqy”文件时,发现excel会hang住,console退出后excel才会响应,但直接双击”test.iqy”是不曾难点的,有意思的是其一情形只有在xp暴发,在win7上尚未这一个难点。

WM_HELP = 83

可以见到Excel
hang在NtUserMessageCall()中,经过查询知,SendMessage()内部就是调用NtUserMessageCall()来发送音讯的。

WM_VKEYTOITEM = 46

 

澳门金沙国际 11if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE))
澳门金沙国际 12{
澳门金沙国际 13          if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)...
澳门金沙国际 14}
澳门金沙国际 15

type

可以是ShellExecuteEx内部创制的线程,所以win7上ShellExecuteEx成立了一个线程专门用来拍卖和excel的DDE新闻通讯,那样就能健康的接受处理excel发过来的WM_DDE_INITIATE消息了

当显示屏的分辨率改变后发送此音讯给所有的窗口

安装窗口是或不是能重画

列表框控件
 LBN_DBLCLK 用户双击了一项
 LBN_ERRSPACE 列表框内存不够
 LBN_KILLFOCUS 列表框正在失去输入宗旨
 LBN_SELCANCEL 选用被吊销
 LBN_SELCHANGE 拔取了另一项
 LBN_SETFOCUS 列表框获得输入宗旨

L B N _ S E L C H AN G E选拔了另一项

当平台现场一度被改动后发送此音信给受影响的最超级窗口

当用户已经登入或剥离后发送此音信给所有的窗口,当用户登入或退出时系统立异用户的求实

WM_NOTIFYFORMAT =85

WM_CHILDACTIVATE =34

WM_MDINEXT = 548

音信分流器
  平时的窗口进程是因此一个switch语句来落实的,那几个工作很烦,有没有更方便的措施呢?有,那就是音讯分流器,利用音信分流器,大家可以把switch语句分成更小的函数,每一个音信都对应一个小函数,这样做的补益就是对新闻更易于管理。
  之所以被叫做音讯分流器,就是因为它可以对别的信息举办疏散。下边大家做一个函数就很明白了:

当WM_SYSKEYDOWN新闻被TRANSLATEMESSAGE函数翻译后交付此新闻给持有宗旨的窗口

time: DWORD / /音讯创制时的时刻

WM_MENUCHAR = 288

WM_PAINT = 15

WM_PRINTCLIENT =792

WM_COMMAND = 273

当一个菜单将要被激活时发送此音信,它发出在用户菜单条中的某项或按下某个菜单键,它同意

澳门金沙国际 16   #define HANDLE_MSG(hwnd,msg,fn) \
澳门金沙国际 17             switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));

当button,combobox,listbox,menu的可视外观改动时发送

当隐藏或出示窗口是发送此音信给这么些窗口

来得剪贴板的新情节;

WM_CREATE = 1

次第发送此音讯给MDI客户窗口用MDI菜单代替子窗口的菜单

WM_DEVICECHANGE =537

WM_ACTIVATEAPP = 28

WM_IME_COMPOSITIONFULL= 644

WM_MENURBUTTONUP =290

出殡此音讯通知应用程序的主窗口that已退出了菜单循环格局

此音信发送给某个窗口仅当它的非客户区需求被改变来显示是激活仍然非激活状态;

WM_GETTEXTLENGTH =14

WM_MDIMAXIMIZE =549

当剪贴板包罗CF_OWNERDIPLAY格式的数据同时剪贴板观望窗口的客户区域的深浅已经转移是此信息通过剪贴板观看窗口发送给剪贴板的持有者;

当某个用户裁撤程序日志激活状态,提交此信息给程序

通过使用给定的连带突显设备的句柄来安装按纽的文本和背景颜色

WM_COMPAREITEM = 57

此音信发送给最小化窗口,当此窗口将要被拖放而它的类中平素不定义图标,应用程序能

也可以修改他们;

WM_CHANGEUISTATE =295

透过利用给定的有关展现设备的句柄来设置滚动条的背景颜色

滚动条都会暴发公告信息。

此音信后,它爆发WM_MDIACTIVE消息给MDI子窗口(未激活)激活它;

一个DDE服务程序提交此音信给DDE客户程序来传递个一多少项给客户或文告客户的一条可用数据项

pt: TPoint / /音信创制时的鼠标地方

一个DDE客户程序通过此音信文告一个DDE服务程序不革新指定的项或一个新鲜的剪贴板格式的项

WM_HANDHELDFIRST =856

//释放鼠标左键

发送此音信给那一个窗口的轻重缓急和岗位已经被改成时,来调用setwindowpos函数或其余窗口管理函数

消息范围

说 明

0 ~ WM_USER – 1

系统消息

WM_USER ~ 0x7FFF

自定义窗口类整数消息

WM_APP ~ 0xBFFF

应用程序自定义消息

0xC000 ~ 0xFFFF

应用程序字符串消息

> 0xFFFF

为以后系统应用保留

当用户自由鼠标右键同时光标又在窗口的非客户区时发送此新闻

WM_DROPFILES = 563

WM_HANDHELDLAST =863

WM_NCLBUTTONDBLCLK= 163

WM_NCDESTROY = 130

音讯中有哪些?

当用户按下鼠标中键同时光标又在窗口的非客户区时发送此信息

WM_QUERYNEWPALETTE= 783

WM_NCHITTEST =132//移动鼠标,按住或释放鼠标时发生

当用户按下鼠标右键同时光标又在窗口的非客户区时发送此音讯

当用户接纳为止对话框或程序自己调用ExitWindows函数

WM_DDE_INITIATE =WM_DDE_FIRST + 0

发送此新闻来判断combobox或listbox新增加的项的相对地方

当某个窗口第三回被创建时,此新闻在WM_CREATE信息发送前发送;

WM_RBUTTONDBLCLK =518

WM_ENTERIDLE = 289

WM_NCRBUTTONUP =165

澳门金沙国际 18   #define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn)\ 
澳门金沙国际 19             ((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0L);

C B N _ K I L L F OC U S组合框失去输入主题

此音信展现用户按下了F1,如若某个菜单是激活的,就发送此新闻个此窗口关联的菜单,否则就

表A-2  常用Windows消息

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图