澳门新萄京8522Windows音信机制

澳门新萄京8522Windows音信机制

1. 问题

1. 窗口进程 
各样窗口会有八个称作窗口进度的回调函数(WndProc),它包罗多少个参数,分别为:窗口句柄(Window
Handle),音讯ID(Message ID),和七个新闻参数(wParam,
lParam),当窗口收到音讯时系统就能调用此窗口进度来管理新闻。(所以叫回调函数卡塔 尔(阿拉伯语:قطر‎

音讯是指什么?
    
消息系统对于七个win32顺序来讲非常第风度翩翩,它是三个程序运营的动力来源。二个音信,是系统定义的四个叁15人的值,他唯黄金时代的定义了一个事件,向
Windows发出多个文告,告诉应用程序有些事情发生了。举例,单击鼠标、修正窗口尺寸、按下键盘上的多少个键都会使Windows发送一个新闻给应用程序。
   
音讯笔者是用作一个记下传递给应用程序的,那么些记录中包罗了新闻的品种以致别的新闻。比如,对于单击鼠标所发出的音信的话,这一个记录中富含了单击鼠标时的坐标。那个记录类型叫做MSG,MSG含有来自windows应用程序新闻队列的音信音信,它在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_USETucson)-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未有发送音信地点和岁月到窗口进程,应用程序可以透过GetmessageTime和GetMessagePos函数。

当音信队列中尚无信息的时候,线程能够使用WaitMessage函数来将调整器交给其余线程,那几个函数暂停线程,知道三个新新闻赶到,该函数才回去。

你也可以调用SetMessageExtraInfo来为日前音信队列附加三个值,通过GetMessageExtraInfo来获取那几个值。

非队列音信
绕过了系统和线程音讯队列,非队列新闻直接发送至窗口进程。系统优秀发送非队列新闻来打招呼八个窗口,四个事件影响了它。比方,当客商激活叁个新窗口,系统一发布送给窗口
WM_ACTIVATE, WM_SETFOCUS, and
WM_SETCUPAJEROSOCR-V音信。那一个新闻文告窗口它已经被激活了,键盘输入正指向该窗口,鼠标光标已经移至了窗口边框内。当应用程序调用某个系统函数时,也会窗口非队列信息,举例,应用程序在调用SetWindowPos时,系统将发送WM_WINDOWPOSCHANGED消息。

稍微新闻发送非队列消息:布罗兹castSystemMessage,
布罗兹castSystemMessageEx, 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.你也得以经过布罗兹castSystemMessage函数,并给lpdwRecipients参数制订BSN_APPLICATIONS

音讯死锁
1.SendMessage会等候窗口进度管理完结后才回到,假若窗口进度当时所在线程激昂调控权屏弃,那么僵中午死锁。
2.只要接到线程附加到了和发送线程同一个新闻队列,也将招致应用程序死锁的殡葬

稳重,正在选择音讯的线程,不应有出示扬弃调控权;调用上面函数将引起线程隐衷屏弃调控权。
DialogBox
?DialogBoxIndirect
?DialogBoxIndirectParam
?DialogBoxParam
?GetMessage
?MessageBox
?PeekMessage
?SendMessage

为了制止地下死锁,思考使用SendNotifyMessage可能SendMessageTimeout。要不然,窗口进度能够经过InSendMessage可能InSendMessageEx检查评定其收受到的新闻是还是不是来自此外线程.在处理二个新闻时,在调用上边列表中其余函数前,窗口进度应该调用InSendMessage(Ex).倘若回到TRUE,窗口进程必需在yeild前,调用ReplyMessage函数。

系统广播音信-略

总结:
1.音讯分为系统定义新闻和客户自定义音讯,其ID值都有友好的约束。
2.各样线程暗中认可是一直不音讯队列的,线程独有在率先次调用客商接口时(譬喻创造窗口卡塔 尔(英语:State of Qatar),系统才为其创设音信队列。
3.系统本人爱慕二个体系音信队列,然后还为每一个GUI线程线程维护贰个线程特意新闻队列。
4.鼠标、键盘等驱动,首先将事件转变为消息放置在系统消息队列中,然后系统又通过窗口来规定将其放入到哪些线程音信队列中。
5.线程音信循环抽取音讯,进行处理,将新闻再派发给系统,系统调用音讯对应的窗口进度。
6.PostMessage不一定成功,比方队列是满的。
7.制止新闻死锁,比如收受消息的窗口进程,在弃权前,供给检验消息是还是不是发自别的线程。不然别的线程将长日子等待。其实小编感到这里不可能成为死锁嘛,究竟如故大概再实行的,只是岁月长度而已。
8.索要潜心wm_paint,wm_timer,wm_quit等新鲜音讯
9.体系预订义新闻其实大都以这些控件新闻,布告音信,系统广播音讯等等。

当在console中调用API
ShellExecuteEx打开”test.iqy”文件时,开采excel会hang住,console退出后excel才会响应,但一贯双击”test.iqy”是绝非难点的,有趣的是以此境况唯有在xp发生,在win7上未曾这几个标题。

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, LOWOTiguanD(wParam)表示菜单项,工具栏按键或控件的ID。假诺是控件,
HIWOSportageD(wParam)表示控件音信类型
3> 控件文告(Notify Message) 
控件公告音信, 那是最灵敏的音信格式, 其Message, wParam,
lParam分别为:WM_NOTIFY,
控件ID,指向NMHDCR-V的指针。NMHDLX570包涵控件文告的剧情, 能够恣意扩充。
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

澳门新萄京8522 1typedef struct tagMsg
澳门新萄京8522 2{
澳门新萄京8522 3       HWND    hwnd;       //接纳该音信的窗口句柄
澳门新萄京8522 4       UINT    message;    //音信常量标记符,也正是我们平常所说的音信号
澳门新萄京8522 5       WPARAM  wParam;     //32个人新闻的一定附加音信,确切含义信赖于新闻值
澳门新萄京8522 6       LPARAM  lParam;     //三十一个人消息的一定附加新闻,确切含义信任于音讯值
澳门新萄京8522 7       DWOHighlanderD   time;       //音讯创立时的小时
澳门新萄京8522 8       POINT   pt;         //音讯创设时的鼠标/光标在显示器坐标系中之处
澳门新萄京8522 9}MSG;
澳门新萄京8522 10

音讯相关函数:

DispatchMessage

LONG DispatchMessage(
const MSG* lpmsg
);
1.该函数将信息,通过系统派发给窗口进程
2.万一是多少个反应计时器音信,lParam参数不是空,

 

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_TIME科雷傲唯有在Queue中绝非此外新闻的时候才会被拍卖,WM_PAINT消息还可能会被联合以进步效能。其余全体音讯以先进先出(FIFO卡塔 尔(英语:State of Qatar)的章程被管理。

   
新闻能够由系统可能应用程序发生。系统在发生输入事件时发出新闻。比如,
当客商敲键,
移动鼠标或许单击控件。系统也发出音信以响应由应用程序带给的调换,
举个例子应用程序改造系统字体制改进变窗体大小。应用程序能够爆发新闻使窗体实践职务,或许与此外应用程序中的窗口通信。

lParam指向八个函数地址,被调用的将是其黄金年代函数,而非窗口进度

GetMessage
应用程序使用该函数再次回到值来决定是还是不是终止音讯循环,并退出程序。

2. 复出步骤

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

音讯中有怎样?
   大家付出了地点的疏解,是否会对音信结构有了贰个比较清楚的认知?假如还一直不,那么我们再试着提交下边包车型大巴表达:
     hwnd
三十位的窗口句柄。窗口能够是此外项目标显示屏对象,因为Win32能够珍重大相当多可视对象的句柄(窗口、对话框、按键、编辑框等)。
    
message用于区分别的音信的常量值,这一个常量能够是Windows单元中预订义的常量,也足以是自定义的常量。音信标识符以常量命名的点子指出信息的意思。当窗口进程接收到消息随后,他就能够使用音讯标志符来决定如哪儿理音讯。比方、WM_PAINT告诉窗口进度窗体客商区被改善了特殊需要重绘。符号常量钦赐系统音信归属的系列,其前缀指明了处通晓释音信的窗体的品类。
     wParam 日常是七个与音信有关的常量值,也大概是窗口或控件的句柄。
     lParam
经常是两个照准内部存款和储蓄器中数据的指针。由于WParam、lParam和Pointer都以34个人的,由此,它们中间能够相互调换。

该函数将获取和hWnd只怕其子窗口相关的音讯。

DWORD GetMessagePos(void);

复出遭逢:XP sp3 / Office 2006(其余office版本应该也得以,未有测量检验卡塔尔国

5 PostMessage(PostThreadMessage), SendMessage 
PostMessage:把音讯放到内定窗口所在的线程音信队列中后迅即回到。
PostThreadMessage:把音信放到钦定线程的信息队列中后马上回去。
SendMessage:直接把音讯送到窗口进度管理,管理完了才回到。

音讯标志符的值
    
系统一保险留音信标志符的值在0x0000在0x03ff(WM_USE陆风X8-1)范围。那些值被系统定义音信使用。应用程序无法运用这个值给本身的新闻。应用程序消息从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USEQashqai到
0X7FFF范围的音讯由应用程序自个儿使用;0XC000到0XFFFF范围的音讯用来和其他应用程序通讯,大家顺便说一下具有标识性的音讯值:
     WM_NULL—0x0000    空消息。
     0x0001—-0x0087    主假如窗口音信。
     0x00A0—-0x00A9    非顾客区新闻 
     0x0100—-0x0108    键盘新闻
     0x0111—-0x0126    菜单音信
     0x0132—-0x0138    颜色调节音讯
     0x0200—-0x020A    鼠标新闻
     0x0211—-0x0213    菜单循环音信
     0x0220—-0x0230    多文书档案新闻
     0x03E0—-0x03E8    DDE消息
     0x0400              WM_USER
     0x8000              WM_APP
     0x0400—-0x7FFF    应用程序自定义私有新闻

该函数重临音信x,y坐标,在多种monitor下,或者有负值。

GetMessageQueueReadyTimeStamp

6 GetMessage, PeekMessage 
PeekMessage会即刻重返能够保存音信
GetMessage在有音讯时回来会去除音信

新闻有哪二种?
   其实,windows中的消息即使非常多,不过项目并不散乱,概略上有3种:窗口新闻、命令音讯和控件公告新闻。
    
窗口语资源消息息大约是系统中非常家常便饭的音信,它是指由操作系统和决定别的窗口的窗口所运用的音讯。举个例子CreateWindow、DestroyWindow和MoveWindow等都会激情窗口音信,还会有大家在下面聊到的单击鼠标所发生的新闻也是黄金时代种窗口音信。
    
命令信息,那是风姿罗曼蒂克种独特的窗口语资源音讯息,他用来拍卖从二个窗口发送到另二个窗口的客户央求,举例按下叁个开关,他就可以向主窗口发送二个命令音信。
    
控件通告音讯,是指那样黄金年代种新闻,一个窗口内的子控件发生了有的政工,须要公告父窗口。公告音讯只适用任宝茹规的窗口控件如开关、列表框、组合框、编辑框,以致Windows公共控件如树状视图、列表视图等。举例,单击或双击三个控件、在控件中甄选一些文件、操作控件的滚动条都会生出通知音信。她仿佛于命令新闻,当顾客与控件窗口交互作用时,那么控件公告音讯就能够从控件窗口发送到它的主窗口。不过这种音信的留存并非为着管理用户命令,而是为了让主窗口能够转移控件,比如加载、展现数据。举个例子按下三个开关,他向父窗口发送的音讯也足以视作是多个控件文告新闻;单击鼠标所发生的音讯可以由主窗口一向管理,然后交到控件窗口管理。
   
在那之中窗口新闻及控件文告音讯根本由窗口类即直接或直接由CWND类派生类管理。相对窗口语资源信息息及控件布告音讯来说,命令新闻的管理指标范围就广得多,它不但能够由窗口类管理,还足以由文书档案类,文书档案模板类及应用类所拍卖。
   
由于控件布告音讯比较重大的,大家用的也正如多,可是现实的意思往往令初大方昏头昏脑,所以笔者说了算把广大的多少个列出来供大家参谋:
按扭控件
BN_CLICKED        顾客单击了按键
 BN_DISABLE 开关被明确命令禁绝
 BN_DOUBLECLICKED  顾客双击了按键
 BN_HILITE  用/户加亮了按键
 BN_PAINT  按键应当重画
 BN_UNHILITE 加亮应当去掉

获得线程近年来一遍打算管理二个消息的系统时间(GetTickCount卡塔 尔(阿拉伯语:قطر‎

GetMessageSource
MSGSRC_SOFTWARE_POST表面键盘音讯来源software(postmessage标识为software卡塔 尔(阿拉伯语:قطر‎.
MSGSRC_HARDWARE_KEYBOARAV4D 表面新闻来自keyboard. MSGSRC_UNKNOWN

1> 解压iqy_test.zip

7 TranslateMessage, TranslateAccelerator 
TranslateMessage: 把一个virtual-key消息转形成字符音讯(character
message),并置于当前线程的音信队列中,音讯循环下三遍抽出管理。
TranslateAccelerator:将快捷键对应到相应的美食指南命令。它会把WM_KEYDOWN 或
WM_SYSKEYDOWN转变成飞速键表中相应的WM_COMMAND或WM_SYSCOMMAND音信,
然后把转变后的 WM_COMMAND或WM_SYSCOMMAND直接发送到窗口进度管理,
管理完后才会回去。

组合框控件
 CBN_CLOSEUP 组合框的列表框被关闭
 CBN_DBLCLK 顾客双击了一个字符串
 CBN_DROPDOWN 组合框的列表框被拉出
 CBN_EDITCHANGE 顾客校勘了编辑框中的文本
 CBN_EDITUPDATE 编辑框内的公文将在履新
 CBN_ERubicon大切诺基SPACE 组合框内存不足
 CBN_KILLFOCUS 组合框失去输入主旨
 CBN_SELCHANGE 在组合框中精选了一项
 CBN_SELENDCANCEL 客户的抉择相应被收回
 CBN_SELENDOK 顾客的取舍是官方的
 CBN_SETFOCUS 组合框获得输入主题

消息来源未知

DWORD GetQueueStatus(
UINT flags
);
在消息队列中的音讯的类型
flags为要检查实验的新闻类型。

2> 运行http_server.py(需先安装python卡塔 尔(英语:State of Qatar)

8(音讯死锁( Message Deadlocks) 
设若有线程A和B, 今后有以下下步骤
1) 线程A SendMessage给线程B, A等待音讯在线程B中拍卖后回来
2) 线程B收到了线程A发来的音讯,并进行拍卖, 在处理进度中,B也向线程A
SendMessgae,然后等待从A重临。
因为那时, 线程A正等待从线程B重回, 不也许管理B发来的音信,
进而引致了/线程A,B互相等待, 产生死锁。两个线程也足以变成环形死锁。
能够运用 SendNotifyMessage或SendMessageTimeout来幸免现身死锁。

编辑框控件
 EN_CHANGE 编辑框中的文本己更新
 EN_EEscort帕杰罗SPACE 编辑框内存不足
 EN_HSCROLL 顾客点击了水平滚动条
 EN_KILLFOCUS 编辑框正在失去输入大旨
 EN_MAXTEXT 插入的剧情被截断
 EN_SETFOCUS 编辑框得到输入大旨
 EN_UPDATE 编辑框中的文本将在更新
 EN_VSCROLL 客户点击了垂直滚动条音信含义

归来值得高字节表示这段日子在新闻队列中的音讯类型。低字节表示从上次GetQueueStatus,GetMessage或然PeekMessage后被投入队列的音讯类型。

InSendMessage

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

9 BroadcastSystemMessage 
我们平日所接触到的音讯都以发送给窗口的,其实,
音信的收信人能够是一应俱全的,它能够是应用程序(applications),
可安装驱动(installable drivers),网络设施(network drivers),
系统级设备驱动(system-level device drivers)等, 
布罗兹castSystemMessage那个API能够对上述系统组件发送新闻。

列表框控件
 LBN_DBLCLK 顾客双击了黄金时代项
 LBN_EHighlanderTiggoSPACE 列表框内部存款和储蓄器远远不够
 LBN_KILLFOCUS 列表框正在失去输入主题
 LBN_SELCANCEL 选拔被打消
 LBN_SELCHANGE 接纳了另意气风发项
 LBN_SETFOCUS 列表框拿到输入宗旨

用来剖断当前窗口进程所管理的音讯,是不是来自其余线程的SendMessage调用。

PeekMessage
1.该函数考验线程音讯队列中是不是有新闻,并将音讯放在参数结构体中
2.只要hWnd参数=-1,则只回去hWnd=NULL的消息,这种音讯来源PostThreadMessage
3.参数wRemoveMsg须求潜心

shell_execute.exe的主要code:

队列音信和非队列音讯
   从新闻的出殡和安葬门路来看,新闻能够分成2种:队列音信和非队列新闻。音信队列由得以分成种类音信队列和线程音讯队列。系统消息队列由Windows维护,线程消息队列则由各类GUI线程本人举行爱慕,为防止给non-GUI现有创立音讯队列,全数线程产生时并从未音讯队列,仅当线程第三次调用GDI函数时系统才给线程创制叁个新闻队列。队列信息送到系统消息队列,然后到线程新闻队列;非队列音信一贯送给目标窗口进程。
    
对于队列音信,最布满的是鼠标和键盘触发的音信,比方WM_MOUSERMOVE,WM_CHA牧马人等音信,还应该有风流罗曼蒂克对别的的消息,比如:WM_PAINT、
WM_TIMER和WM_QUIT。当鼠标、键盘事件被触发后,相应的鼠标或键盘驱动程序就能够把这么些事件转变到相应的音讯,然后输送到系统消息队列,由
Windows系统去开展处理。Windows系统则在适用的火候,从系统音信队列中抽出四个新闻,依照后边大家所说的MSG消息结构鲜明新闻是要被送往特别窗口,然后把抽出的新闻送往创造窗口的线程的照望队列,上边的事情就该由线程音讯队列操心了,Windows最早忙自个儿的政工去了。线程见到自身的音信队列中有消息,就从队列中收取来,通过操作系统一发布送到合适的窗口进程去管理。
    
平时来讲,系统连接将新闻Post在音信队列的尾声。那样保障窗口以先进先出的逐一选取音信。不过,WM_PAINT是贰个莫衷一是,同一个窗口的多个WM_PAINT被联合成一个 WM_PAINT 新闻,
合併全体的无用区域到叁个无效区域。合併WM_PAIN的指标是为了缩短刷新窗口的次数。
澳门新萄京8522 11

4.万一应用程序正在创建顶层窗口时调用PeekMessage,将促成窗口窗口被创建在Z-Order的末段。你必要在PeekMessage后,显式调用SetForegroundWindow。假若应用程序以致有贰个停放窗口了,那么新窗口将被置于。

PostMessage
应用程序要用HWND_BROADCAST实路程序间的互相,音讯应该赢得于RegisterWindowMessage()

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;
}

澳门新萄京8522 12
   
非队列新闻将会绕过系统队列和音讯队列,直接将消息发送到窗口进度,。系统一发布送非队列音讯公告窗口,系统一发布送音讯通告窗口。譬喻,当客户激活一个窗口系统一发布送WM_ACTIVATE,
WM_SETFOCUS, and
WM_SETCU路虎极光SO酷威。这一个消息文告窗口它被激活了。非队列新闻也得以由当应用程序调用系统函数发生。举个例子,当程序调用SetWindowPos系统一发布送WM_WINDOWPOSCHANGED音讯。一些函数也发送非队列音讯,举个例子上边大家要聊到的函数。
     
消息的出殡
    
了然了上面的那一个基本功理论之后,大家就足以开展一下简单易行的音信发送与选取。
     把一个音信发送到窗口有3种艺术:发送、寄送和播放。
    
发送音信的函数有SendMessage、SendMessageCallback、SendNotifyMessage、
SendMessage提姆eout;寄送音信的函数主要有PostMessage、PostThreadMessage、
PostQuitMessage;广播音信的函数小编明白的唯有BroadcastSystemMessage、
布罗兹castSystemMessageEx。
     SendMessage的原型如下:LRESULT SendMessage(HWND hWnd,UINT
Msg,WPARAM wParam,LPARAM
lParam),那些函数重假设向二个或八个窗口发送一条音信,一贯等到新闻被管理现在才会回来。不过必要当心的是,假设接到信息的窗口是同一个应用程序的大器晚成有个别,那么这些窗口的窗口函数就被看做二个子顺序及时被调用;若是收到消息的窗口是被别的的线程所创设的,那么窗口系统就切换成相应的线程而且调用相应的窗口函数,那条新闻不会被放进指标应用程序队列中。函数的重返值是由接纳音信的窗口的窗口函数重回,重返的值决定于被发送的音信。
     PostMessage的原型如下:BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM
wParam,LPARAM
lParam),该函数把一条音讯放置到创造hWnd窗口的线程的新闻队列中,该函数不等消息被处理就当下将决定重临。须求注意的是,假使hWnd参数为
HWND_BROADCAST,那么,新闻将被寄送给系统中的全数的重合窗口和弹出窗口,可是子窗口不会采纳该信息;若是hWnd参数为NULL,则该函数雷同于将dwThreadID参数设置成当下线程的标记来调用PostThreadMEssage函数。
  从地点的那2个颇负代表性的函数,大家能够看见音讯的发送格局和寄送形式的差距所在:被发送的音讯是或不是会被立马管理,函数是不是及时重回。被发送的音信会被马上管理,管理完成后函数才会回来;被寄送的音信不会被马上管理,他被置于贰个先进先出的行列中,一向等到应用程序空线的时候才会被拍卖,可是函数放置新闻后任何时候回去。
澳门新萄京8522 13
  实际上,发送新闻到三个窗口管理进度和间接调用窗口管理进程之间并从未太大的分别,他们直白的举世无双分裂就在于你能够供给操作系统截获全体被发送的新闻,可是不可见收获对窗口处理进度的直接调用。
  以寄送点子发送的音信常常是与客户输入事件相呼应的,因为那一个事件不是可怜心急如焚,能够开展缓慢的缓冲管理,举个例子鼠标、键盘新闻会被寄送,而开关等新闻则会被发送。
  广播音讯用得超少,BroadcastSystemMessage函数原型如下:
      long BroadcastSystemMessage(DWOKugaD dwFlags,LPDWOSportageD
lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM
lParam);该函数能够向钦命的采用者发送一条消息,这一个接受者能够是应用程序、可安装的驱动程序、网络驱动程序、系统级其余器材驱动消息和她俩的放肆组合。要求注意的是,若是dwFlags参数是BSF_QUE本田CR-VY並且最少三个选择者再次回到了BROADCAST_QUERY_DENY,则再次回到值为0,若无一点名BSF_QUELacrosseY,则函数将消息发送给全体接纳者,並且忽略其重返值。

比方发送音讯低于WM_USECR-V范围,到异步音信队列函数(PostMessage、SendNotifyMessage卡塔 尔(英语:State of Qatar),新闻参数不应当包罗指针,不然的话,操作将失利。该函数将在选用线程有机缘管理该消息前回到,发送者将释放刚刚用到的内部存款和储蓄器。

PostQuitMessage

 

音讯的收纳
 新闻的吸收接纳重要有3个函数:GetMessage、PeekMessage、WaitMessage。
  GetMessage原型如下:BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT
wMsgFilterMin,UINT
wMsgFilter马克斯);该函数用来获得与hWnd参数所钦定的窗口相关的且wMsgFilterMin和wMsgFilterMax参数所付出的新闻值范围内的音讯。需求当心的是,如果hWnd为NULL,则GetMessage获取归属调用该函数应用程序的任后生可畏窗口的音信,借使wMsgFilterMin和wMsgFilter马克斯都以0,则GetMessage就重回全部可得到的音讯。函数获取之后将去除音讯队列中的除
WM_PAINT新闻之外的此外音信,至于WM_PAINT则独有在其拍卖未来才被去除。
   PeekMessage原型如下:BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT
wMsgFilterMin,UINT wMsgFilter马克斯,UINT
wRemoveMsg卡塔 尔(阿拉伯语:قطر‎;该函数用于查看应用程序的音讯队列,假若中间有新闻就将其放入lpMsg所指的构造中,可是,与GetMessage差别的是,PeekMessage函数不会等到有新闻归入队列时才回去。同样,假如hWnd为NULL,则PeekMessage获取归属调用该函数应用程序的任少年老成窗口的音讯,如若hWnd=-1,那么函数只回去把hWnd参数为NULL的PostAppMessage函数送去的音信。借使wMsgFilterMin和wMsgFilter马克斯都是0,则PeekMessage就回去全数可获取的新闻。函数获取之后将视最终三个参数来支配是不是删除新闻队列中的除
WM_PAINT音讯之外的别的新闻,至于WM_PAINT则独有在其管理今后才被剔除。
   WaitMessage原型如下:BOOL
WaitMessage();当三个应用程序无事可做时,该函数就将调控权交给其余的应用程序,同不经常候将该应用程序挂起,直到一个新的音讯被归入应用程序的行列之中才回来。

该函数只是轻巧申明被倡议终止的线程将会终止。接收WM_QUIT的线程,应该告后生可畏段落新闻循环,并将调节权交给系统。重临给系统的退出值,一定是WM_QUIT的wParam参数

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

摄取信息的线程,通过GetMessage/PeekMessage来获取新闻,hWnd成员将会是空


RegisterWindowMessage
同一字符串,注册的值,在整整系统中是唯后生可畏的


SendMessage

3. 缘由剖析

新闻的拍卖
  接下去我们谈一下音信的管理,首先大家来看一下VC中的音讯泵:

非信息队列方式,直接调用窗口进程,系统立刻切换成接纳线程履行,发送线程锁住,知道选取线程管理完结

SendMessageTimeout

3.1 excel hang在哪里?

澳门新萄京8522 14while(GetMessage(&msg, NULL, 0, 0))
澳门新萄京8522 15{
澳门新萄京8522 16       if(!TranslateAccelerator(msg.hWnd, hAccelTable, &msg))
澳门新萄京8522 17      { 
澳门新萄京8522 18            TranslateMessage(&msg);
澳门新萄京8522 19            DispatchMessage(&msg);
澳门新萄京8522 20       }
澳门新萄京8522 21}

该函数通过调用窗口进程的法门发送音讯,假使窗口归于不相同线程,SendMessageTimerout将精晓新闻管理实现才回到或然钦定的超时已经一病不起,假如窗口就在脚下线程,则平昔调用窗口进程,并忽视time-out超时

SendNotifyMessage
万风流倜傥窗口创设于归于发送音讯的线程,则调用窗口进度,并等待窗口进度管理完结该音信。如若是不相同线程,则将新闻传递到窗口进度,并及时回去,不等待窗口进度的音信管理进度。


TranslateMessage
1.将设想键音讯调换为字符音讯,然后将字符新闻发送到调用线程的音讯队列中,该字符新闻就要下次调用GetMessage恐怕PeekMessage新闻的时候取获得。
2.WM_(SYS)KEYDOWN/UP—>WM_(SYS)_CHAR
3.假如应用程序为了其余目标,管理虚构键音讯,那么就不应有调用TranslateMessage.与二个实例,应用程序不该在TranslateAccelerator函数重返非0值时调用TranslateMessage

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

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

 

澳门新萄京8522 22

  
首先,GetMessage从进度的主线程的音信队列中获取叁个新闻并将它复制到MSG结构,要是队列中平素不音讯,则GetMessage函数将拭目以待叁个音讯的来到未来才重临。要是您将叁个窗口句柄作为第贰个参数字传送入GetMessage,那么独有内定窗口的的消息能够从队列中得到。GetMessage也得以从音讯队列中过滤新闻只选取音信队列中落在界定内的音讯。当时将在动用GetMessage/PeekMessage钦赐叁个新闻过滤器。这些过滤器是三个音信标记符的界定恐怕是一个窗体句柄,可能两个同期钦命。当应用程序要探究三个后入音讯队列的音信是很有用。WM_KEYFIRST
和 WM_KEYLAST 常量用于选取全体的键盘新闻。 WM_MOUSEFIRST 和
WM_MOUSELAST 常量用于选择全数的鼠标新闻。 
 然后TranslateAccelerator决断该消息是或不是五个开关新闻还如若叁个加快键音讯,要是是,则该函数将把多少个开关新闻调换来一个加快键音讯传递给窗口的回调函数。管理了加快键之后,函数TranslateMessage将把四个开关新闻WM_KEYDOWN和WM_KEYUP转变到多少个WM_CHATiguan,但是要求介意的是,音讯WM_KEYDOWN,WM_KEYUP照旧将传递给窗口的回调函数。     
 管理完事后,DispatchMessage函数将把此新闻发送给该音讯钦定的窗口中已设定的回调函数。假若新闻是WM_QUIT,则
GetMessage再次来到0,进而退出循环体。应用程序能够利用PostQuitMessage来为止自个儿的新闻循环。经常在主窗口的
WM_DESTROY新闻中调用。
 下边大家举三个宽广的小例子来证实这几个消息泵的应用:

能够看见Excel
hang在NtUserMessageCall()中,经过查询知,SendMessage()内部正是调用NtUserMessageCall()来发送音信的。

澳门新萄京8522 23if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE))
澳门新萄京8522 24{
澳门新萄京8522 25          if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)...
澳门新萄京8522 26}
澳门新萄京8522 27

查看参数知excel调用NtUserMessageCall()相近如下:

  这里大家选择全部的键盘新闻,所以就用WM_KEYFIRST 和
WM_KEYLAST作为参数。最后二个参数能够是PM_NOREMOVE 或者
PM_REMOVE,表示音讯消息是或不是相应从新闻队列中去除。                 
   所以这段小代码就是剖断是不是按下了Esc键,假若是就进展管理。

NtUserMessageCall(HWND_BROADCAST, WM_DDE_INITIATE)

窗口进度
 窗口进程是叁个用来拍卖全数发送到那些窗口的音信的函数。任何多少个窗口类都有贰个窗口进程。同八个类的窗口使用相同的窗口进度来响应音信。系统一发布送消息给窗口进程将音信数据作为参数字传送递给他,音信赶到之后,按照音信类型排序举办管理,当中的参数则用来区分不一样的信息,窗口进程采纳参数发生合适行为。
 一个窗口进度不平时忽略音讯,假若他不管理,它会将音讯传回到实施默许的管理。窗口进程通过调用DefWindowProc来做这么些管理。窗口进度必需return二个值作为它的音信管理结果。大许多窗口只管理小一些新闻和将其它的经过DefWindowProc传递给系统做暗中同意的拍卖。窗口进程被有着归于同二个类的窗口分享,能为差别的窗口管理音讯。下边大家来看一下实际的实例:

表达excel给持有顶层窗口发送叁个WM_DDE_INITIATE消息,不过有窗口未有response

澳门新萄京8522 28LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
澳门新萄京8522 29{
澳门新萄京8522 30 int wmId, wmEvent;
澳门新萄京8522 31 PAINTSTRUCT ps;
澳门新萄京8522 32 HDC hdc;
澳门新萄京8522 33 TCHAR szHello[MAX_LOADSTRING];
澳门新萄京8522 34 LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
澳门新萄京8522 35
澳门新萄京8522 36 switch (message) 
澳门新萄京8522 37 {
澳门新萄京8522 38  case WM_COMMAND:
澳门新萄京8522 39         wmId    = LOWORD(wParam); 
澳门新萄京8522 40         wmEvent = HIWORD(wParam); 
澳门新萄京8522 41         // Parse the menu selections:
澳门新萄京8522 42         switch (wmId)
澳门新萄京8522 43         {
澳门新萄京8522 44          case IDM_ABOUT:
澳门新萄京8522 45             DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
澳门新萄京8522 46             break;
澳门新萄京8522 47          case IDM_EXIT:
澳门新萄京8522 48             DestroyWindow(hWnd);
澳门新萄京8522 49             break;
澳门新萄京8522 50          default:
澳门新萄京8522 51             return DefWindowProc(hWnd, message, wParam, lParam);
澳门新萄京8522 52         }
澳门新萄京8522 53   break;
澳门新萄京8522 54
澳门新萄京8522 55  case WM_PAINT:
澳门新萄京8522 56         hdc = BeginPaint(hWnd, &ps);
澳门新萄京8522 57         // TODO: Add any drawing code here澳门新萄京8522 58
澳门新萄京8522 59         RECT rt;
澳门新萄京8522 60         GetClientRect(hWnd, &rt);
澳门新萄京8522 61         DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
澳门新萄京8522 62         EndPaint(hWnd, &ps);
澳门新萄京8522 63         break;
澳门新萄京8522 64
澳门新萄京8522 65  case WM_DESTROY:
澳门新萄京8522 66         PostQuitMessage(0);
澳门新萄京8522 67         break;
澳门新萄京8522 68  default:
澳门新萄京8522 69         return DefWindowProc(hWnd, message, wParam, lParam);
澳门新萄京8522 70  }
澳门新萄京8522 71  return 0;
澳门新萄京8522 72}
澳门新萄京8522 73

经过能够可疑是由于console进度在和excel用DDE新闻通信时,console未有响应excel发送的DDE消息,招致excel
hang住

 

 

新闻分流器
  平常的窗口进程是因此贰个switch语句来兑现的,这一个业务很烦,有未有更简便易行的法子吧?有,那正是新闻分流器,利用新闻分流器,大家能够把switch语句分成越来越小的函数,每一个消息都对应多少个小函数,那样做的功利即是对新闻更便于管理。
  之所以被誉为新闻分流器,就是因为它能够对别的音信进行分流。上边大家做多少个函数就很清楚了:

3.2 为了验证3.1.1的揣摸,用API Monitor一下ShellExecuteEx

澳门新萄京8522 74void MsgCracker(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)
澳门新萄京8522 75{
澳门新萄京8522 76      switch(id)
澳门新萄京8522 77      {
澳门新萄京8522 78     case ID_A:
澳门新萄京8522 79                  if(codeNotify==EN_CHANGE)澳门新萄京8522 80
澳门新萄京8522 81                  break;
澳门新萄京8522 82     case ID_B:
澳门新萄京8522 83                  if(codeNotify==BN_CLICKED)澳门新萄京8522 84
澳门新萄京8522 85                  break;
澳门新萄京8522 86             澳门新萄京8522 87.
澳门新萄京8522 88       }
澳门新萄京8522 89}
澳门新萄京8522 90

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

然后大家矫正一下窗口过程:

澳门新萄京8522 91LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
澳门新萄京8522 92{
澳门新萄京8522 93       switch(message)
澳门新萄京8522 94      {
澳门新萄京8522 95             HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);
澳门新萄京8522 96             HANDLE_MSG(hWnd,WM_DESTROY,MsgCracker);
澳门新萄京8522 97           default:
澳门新萄京8522 98                    return DefWindowProc(hWnd, message, wParam, lParam);
澳门新萄京8522 99   }
澳门新萄京8522 100  return 0;
澳门新萄京8522 101}

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

在WindowsX.h中定义了之类的HANDLE_MSG宏:

澳门新萄京8522 102

澳门新萄京8522 103   #define HANDLE_MSG(hwnd,msg,fn) \
澳门新萄京8522 104             switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));

call stack展现实乃ShellExecuteEx所调用

实际上,HANDLE_WM_XXXX都是宏,例如:HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);将被转换到如下概念:

澳门新萄京8522 105

澳门新萄京8522 106   #define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn)\ 
澳门新萄京8522 107             ((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0L);

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

好了,事情到了这一步,应该全套都晴朗了。
而是,大家发今后windowsx.h里面还应该有二个宏:FO宝马7系WAEscortD_WM_XXXX,大家照旧那WM_COMMAND为例,举办剖析:

留意到下二个API GetWindowThreadProcessId ( 0x00310172 , 0x0012fb70
),恰巧是获取那么些窗口的pid和tid,查看下参数窗口:

澳门新萄京8522 108   #define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \
澳门新萄京8522 109     (void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl))

那一个窗口所属的进程PID =
0xc54,适逢其会是excel的进度,表明ShellExecuteEx确实发送了DDE新闻给excel,何况可执发送的音讯的thread就是主线程

故而实际,FO陆风X8WA奥迪Q5D_WM_XXXX将音讯参数进行了双重新组合织,生成了wParam &&
lParam,然后调用了大家定义的函数。

澳门新萄京8522 110

后面,大家分析了音信的着力理论和主导的函数及用法,接下去,大家将特别讨论音信传递在MFC中的实现。

轶闻DDE的音信参数,可以见到wParam正是发送新闻的窗口,其句柄为2425190 =
0x250166,反向查询知那是ShellExecuteEx创造的”WorkerW”窗口

MFC新闻的管理完成格局
  初看MFC中的各类新闻,以致在头脑中稳步的C++的影响,大家也许很当然的就能想到利用C++的三大特征之意气风发:设想机制来完毕音讯的传递,可是透过深入分析,大家看见专门的学业并不是想我们想像的那么,在MFC中音讯是透过生机勃勃种所谓的消息映射机制来拍卖的。
  为啥吧?在潘爱中华民族解放先锋生翻译的《Visual
C++才能内部原因》(第4版卡塔尔中付出了详实的开始和结果表达,作者再同理可得三遍。在CWnd类中大约有1拾一个音信,还也许有别的的MFC的类呢,算起来音讯太多了,在C++中对程序中用到的每二个派生类都要有五个vtable,每贰个虚函数在vtable中都要占用贰个4字节高低的输入地址,那样一来,对于各样特定类型的窗口或控件,应用程序都亟待四个440KB大小的表来扶助设想音讯控件函数。
  如若说上边的窗口或控件能够勉强达成的话,那么对于菜单命令音信及开关命令信息啊?因为分化的应用程序有两样的菜单和按键,大家怎么管理吧?在MFC
库的这种音信映射系统就制止了接收大的vtable,并且能够在拍卖符合规律Windows音讯的还要管理百废待举的应用程序的下令新闻。
  说白了,MFC中的音信机制其实质是一张高大的音讯及其管理函数的顺序对应表,然后加上深入分析管理那张表的施用框架之中的意气风发部分顺序代码.那样就可以制止在SDK编制程序中用到的累赘的CASE语句。

澳门新萄京8522 111

MFC的音讯映射的基类CCmdTarget
  假使您想让您的控件能够进行新闻映射,就务须从CCmdTarget类中派生。CCmdTarget类是MFC管理命令消息的基础、主旨。MFC为此类设计了好多分子函数和有个别成员数量,基本上是为了缓和新闻映射难题的,全体响应新闻或事件的类都从它派生,举例:应用程序类、框架类、文书档案类、视图类和各种各样的控件类等等,还会有为数不少。
不过这么些类里面有2个函数对消息映射相当重大,多个是静态成员函数DispatchCmdMsg,另叁个是虚函数OnCmdMsg。
DispatchCmdMsg特意供MFC内部接收,用来散发Windows新闻。OnCmdMsg用来传递和发送消息、更新客商界直面象的意况。
CCmdTarget对OnCmdMsg的暗中同意完毕:在一时一刻下令指标(this所指)的类和基类的新闻映射数组里探索内定命令信息的新闻管理函数。
  这里运用设想函数GetMessageMap拿到传令目的类的音讯映射入口数组_messageEntries,然后在数组里相称命令音讯ID相符、调节文告代码也相通的新闻映射条目款项。个中GetMessageMap是设想函数,所以能够确定当前命令指标的确切类。
倘诺找到了多个特出的音信映射条目款项,则动用DispachCmdMsg调用这几个管理函数;
风流洒脱旦未有找到,则运用_GetBaseMessageMap获得基类的消息映射数组,查找,直到找到或索求了全数的基类(到CCmdTarget卡塔尔国停止;
若是最后未有找到,则赶回FASLE。
  每一个从CCmdTarget派生的吩咐目的类都足以覆盖OnCmdMsg,利用它来规定是还是不是足以管理某条命令,若是不可能,就经过调用下一指令目的的
OnCmdMsg,把该命令送给下二个限令指标管理。平常,派生类覆盖OnCmdMsg时,要调用基类的被隐讳的OnCmdMsg。
  在MFC框架中,一些MFC命令目的类掩没了OnCmdMsg,如框架窗口类蒙蔽了该函数,完成了MFC的正经命令新闻发送路线。供给的话,应用程序也能够覆盖OnCmdMsg,退换三个或八个类中的发送规定,达成与正式框架发送规定不相同的出殡路线。比如,在偏下处境能够作那样的管理:在要打断发送顺序的类中把命令传给一个非MFC暗中同意对象;在新的非暗许对象中或在恐怕要传播命令的通令目的中。

澳门新萄京8522 112

音信映射的剧情
   
通过ClassWizard为大家转移的代码,大家能够看见,音信映射基本上分为2许多:
   
在头文件(.h)中有叁个宏DECLARE_MESSAGE_MAP(),他被放在了类的最后,是二个public属性的;与之相应的是在促成都部队分(.cpp)扩张了意气风发章新闻映射表,内容如下:
    BEGIN_MESSAGE_MAP(当前类, 当前类的基类)
       //{{AFX_MSG_MAP(CMainFrame)
         音讯的输入项
       //}}AFX_MSG_MAP
   END_MESSAGE_MAP()
  
不过仅是这两项还远不足以实现一条消息,借使三个音讯职业,必需有以下3个部分去合营:
1.在类的定义中加入相应的函数声明;
2.在类的音信映射表中步入相应的消息映射入口项;
3.在类的完结中参预相应的函数体;

 

音信的充裕
  
有了上边的这一个只是用作基本功,大家接下去就做大家最熟练、最常用的行事:增加消息。MFC新闻的增加重要有2种方法:自动/手动,大家就以那2种艺术为例,说一下怎么增加音信。
   1、利用Class Wizard达成机关抬高
      在菜单中选取View–>Class
Wizard,也足以用单击鼠标右键,选取Class Wizard,相符能够激活Class
Wizard。选拔Message Map标签,从Class
name组合框中选取大家想要增添音讯的类。在Object
IDs列表框中,选拔类的称呼。那时,
Messages列表框突显此类的大比非常多(若不是全体的话)可重载成员函数和窗口音信。类重载展现在列表的上部,以实际假造成员函数的大大小小写字母来表示。其余为窗口音讯,以大写字母现身,描述了实际上窗口所能响应的消息ID。选中我们向增多的信息,单击Add
Function按键,Class Wizard自动将该音信加多进去。
     
不时候,我们想要增加的消息本应有出以往Message列表中,但是就是找不到,如何是好?不要心急,大家得以行使Class
Wizard上Class Info标签以扩大新闻列表。在该页中,找到Message
Filter组合框,通过它能够校正首页中Messages列表框中的选项。这里,我们选择Window,进而显示全数的窗口音讯,大器晚成把状态下,你想要增加的新闻就可以在Message列表框中冒出了,假若尚未,那就接着往下看:)

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

   2、手动地增进音讯管理函数
   
假诺在Messages列表框中依旧看不到大家想要的新闻,那么该音讯大概是被系统忽视掉也许是您协和创建的,在此种场所下,就非得和睦手工增多。依照大家日前所说的新闻工作的3个零器件,大家意气风发风姿洒脱进行拍卖:
      1) 在类的.
h文件中丰裕管理函数的扬言,紧接在//}}AFX_MSG行之后加盟证明,注意:必供给以afx_msg开头。
     平日,增加管理函数评释的最佳的地点是源代码中Class
Wizard维护的表上面,不过在它标识其领域的{{}}括弧外面。这几个括弧中的任何事物都将会被Class
Wizard销毁。
      2)
接着,在顾客类的.cpp文件中找到//}}AFX_MSG_MAP行,紧接在它之后加盟音讯入口项。相近,也是身处{
{} }的外部
      3) 最终,在该公文中增添音讯管理函数的实体。

澳门新萄京8522 113

 

查阅一下buff的地点:

 

澳门新萄京8522 114

消息范围

说 明

0 ~ WM_USER – 1

系统消息

WM_USER ~ 0x7FFF

自定义窗口类整数消息

WM_APP ~ 0xBFFF

应用程序自定义消息

0xC000 ~ 0xFFFF

应用程序字符串消息

> 0xFFFF

为以后系统应用保留

无独有偶便是张开test.iqy的命令,表明ShellExecuteEx正是先成立了excel的长河,然后发送test.iqy的文本命令给excel张开。

表A-2  常用Windows消息

 

消息名称

说  明

WM_NULL 

0x0000

空消息,此消息将被接收窗口忽略

WM_CREATE 

0x0001

应用程序创建一个窗口

WM_DESTROY

0x0002

一个窗口被销毁

WM_MOVE

0x0003

移动一个窗口

WM_SIZE

0x0005

改变一个窗口的大小

WM_ACTIVATE

0x0006

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

WM_SETFOCUS

0x0007

获得焦点后

WM_KILLFOCUS

0x0008

失去焦点

WM_ENABLE

0x000A

应用程序Enable状态改变时产生

WM_SETREDRAW

0x000B

设置窗口是否能重画

WM_SETTEXT

0x000C

应用程序发送此消息来设置一个窗口的文本

WM_GETTEXT

0x000D

应用程序发送此消息来复制对应窗口的文本到缓冲区

WM_GETTEXTLENGTH

0x000E

得到与一个窗口有关的文本的长度(不包含空字符)

WM_PAINT

0x000F

要求一个窗口重绘自己

WM_CLOSE

0x0010

当一个窗口或应用程序要关闭时发送一个信号

WM_QUERYENDSESSION

0x0011

用户选择结束对话框或应用程序自己调用ExitWindows()函数

WM_QUIT

0x0012

用来结束程序运行或应用程序调用Postquitmessage()函数来产生此消息

WM_QUERYOPEN

0x0013

当用户窗口恢复以前的大小位置时,把此消息发送给某个图标

WM_ERASEBKGND

0x0014

当窗口背景必须被擦除时(例如在窗口改变大小时)

WM_SYSCOLORCHANGE

0x0015

当系统颜色改变时,发送此消息给所有顶级窗口

WM_ENDSESSION

0x0016

当系统进程发出WM_QUERYENDSESSION消息后,此消息发送给应用程序

WM_SHOWWINDOW

0x0018

当隐藏或显示窗口是发送此消息给这个窗口

WM_ACTIVATEAPP

0x001C

当某个窗口将被激活时,将被激活窗口和当前活动(即将失去激活)窗口会收到此消息,发此消息给应用程序哪个窗口是激活的,哪个是非激活的

WM_FONTCHANGE

0x001D

当系统的字体资源库变化时发送此消息给所有顶级窗口

WM_TIMECHANGE

0x001E

当系统的时间变化时发送此消息给所有顶级窗口

WM_CANCELMODE

0x001F

发送此消息来取消某种正在进行的操作

WM_SETCURSOR

0x0020

如果鼠标引起光标在某个窗口中移动且鼠标输入没有被捕获时,发消息给该窗口

WM_MOUSEACTIVATE

0x0021

当光标在某个非激活的窗口中而用户正按着鼠标的某个键发送此消息给当前窗口

WM_CHILDACTIVATE

0x0022

发送此消息给MDI子窗口当用户点击此窗口的标题栏,或当窗口被激活、移动、改变大小

WM_QUEUESYNC

0x0023

此消息由基于计算机的训练程序发送,通过WH_JOURNALPALYBACK的Hook程序分离出用户输入消息

WM_GETMINMAXINFO

0x0024

当窗口要将要改变大小或位置时,发送此消息给该窗口

WM_PAINTICON

0x0026

当窗口图标将要被重绘时,发送此消息给该窗口

WM_ICONERASEBKGND

0x0027

在一个最小化窗口的图标在重绘前,当图标背景必须被重绘时,发送此消息给该窗口

WM_NEXTDLGCTL

0x0028

发送此消息给一个对话框程序以更改焦点位置

WM_SPOOLERSTATUS

0x002A

当打印管理列队增加或减少一条作业时发出此消息

WM_DRAWITEM

0x002B

当Button,ComboBox,Listbox,Menu控件的外观改变时,发送此消息给这些控件的所有者

WM_MEASUREITEM

0x002C

当Button,ComboBox,list box,ListView,Menu 项被创建时,发送此消息给控件的所有者

WM_DELETEITEM

0x002D

当ListBox 或 ComboBox 被销毁或当某些项通过发送LB_DELETESTRING、LB_RESETCONTENT、 CB_DELETESTRING、CB_RESETCONTENT 消息被删除时,发送此消息给控件的所有者

WM_VKEYTOITEM

0x002E

一个具有LBS_WANTKEYBOARDINPUT风格的ListBox控件发送此消息给它的所有者,以此来响应WM_KEYDOWN消息

WM_CHARTOITEM

0x002F

一个具有LBS_WANTKEYBOARDINPUT风格的ListBox控件发送此消息给它的所有者,以此来响应WM_CHAR消息

WM_SETFONT

0x0030

应用程序绘制控件时,发送此消息得到以何种字体绘制控件中的文本

WM_GETFONT

0x0031

应用程序发送此消息得到当前控件绘制文本的字体

WM_SETHOTKEY

0x0032

应用程序发送此消息让一个窗口与一个热键相关联

WM_GETHOTKEY

0x0033

应用程序发送此消息来判断热键与某个窗口是否有关联

WM_QUERYDRAGICON

0x0037

此消息发送给最小化窗口,当此窗口将要被拖放而它的类中没有定义图标,应用程序就返回一个图标或光标的句柄,当用户拖放图标时系统显示这个图标或光标

WM_COMPAREITEM

0x0039

发送此消息来判定ComboBox或ListBox新增加的项的相对位置

WM_COMPACTING

0x0041

显示内存已经很少了

WM_WINDOWPOSCHANGING

0x0046

当调用SetWindowPos()函数改变窗口的大小和位置后,发送此消息给该窗口

WM_POWER

0x0048

当系统将进入挂起状态时发送此消息给所有进程

WM_COPYDATA

0x004A

当一个应用程序传递数据给另一个应用程序时发送此消息

WM_CANCELJOURNAL

0x004B

当某个用户取消程序日志激活状态,发送此消息给应用程序

WM_NOTIFY

0x004E

当某个控件的某个事件已经发生或这个控件需要得到一些信息时,发送此消息给它的父窗口

WM_INPUTLANGCHANGEREQUEST

0x0050

当用户选择某种输入语言,或输入语言的热键改变

WM_INPUTLANGCHANGE

0x0051

当应用程序输入语言改变后发送此消息给受影响的最顶级窗口

WM_TCARD

0x0052

当应用程序已经初始化Windows帮助例程时发送此消息给应用程序

WM_HELP

0x0053

当用户按下了F1,如果某个菜单是激活的,就发送此消息给此窗口关联的菜单,否则就发送给有焦点的窗口,如果当前都没有焦点,就把此消息发送给当前激活的窗口

WM_USERCHANGED

0x0054

当用户已经登录或退出后发送此消息给所有的窗口,当用户登录或退出时系统更新用户的具体设置信息,在用户更新设置时系统马上发送此消息

WM_NOTIFYFORMAT

0x0055

公用控件和它们的父窗口通过此消息来判断在WM_NOTIFY消息中是使用ANSI还是UNICODE形式的结构,使用此控件能使某个控件与它的父控件进行相互通信

WM_CONTEXTMENU

0x007B

当用户在某个窗口中点击右键,则发送此消息给该窗口

WM_STYLECHANGING

0x007C

当将要调用SetWindowLong()函数窗口的一个或多个风格时,发送此消息给该窗口

WM_STYLECHANGED

0x007D

当调用SetWindowLong()函数改变了窗口的一个或多个风格后,发送此消息给该窗口

WM_DISPLAYCHANGE

0x007E

当显示器的分辨率改变后发送此消息给所有的窗口

WM_GETICON

0x007F

发送此消息给某个窗口,返回与某个窗口有关联的大图标或小图标的句柄

WM_SETICON

0x0080

应用程序发送此消息让一个新的大图标或小图标与某个窗口关联

WM_NCCREATE

0x0081

当某个窗口第一次被创建时,此消息在WM_CREATE消息被发送前发送

WM_NCDESTROY

0x0082

此消息通知某个窗口,正在销毁非客户区

WM_NCCALCSIZE

0x0083

当计算某个窗口的客户区大小和位置时发送此消息

WM_NCHITTEST

0x0084

移动鼠标,按住或释放鼠标时产生此消息

WM_NCPAINT

0x0085

当某个窗口的框架必须被绘制时,应用程序发送此消息给该窗口

WM_NCACTIVATE

0x0086

通过改变某个窗口的非客户区来表示窗口是处于激活还是非激活状态时,此消息被发送给该窗口

WM_NCMOUSEMOVE

0x00A0

当光标在窗口的非客户区(窗口标题栏及边框)内移动时发送此消息给该窗口

WM_NCLBUTTONDOWN

0x00A1

当光标在窗口的非客户区并按下鼠标左键时发送此消息

WM_NCLBUTTONUP

0x00A2

当光标在窗口的非客户区并释放鼠标左键时发送此消息

WM_NCLBUTTONDBLCLK

0x00A3

当光标在窗口的非客户区并双击鼠标左键时发送此消息

WM_NCRBUTTONDOWN

0x00A4

当光标在窗口的非客户区并按下鼠标右键时发送此消息

WM_NCRBUTTONUP

0x00A5

当光标在窗口的非客户区并释放鼠标右键时发送此消息

WM_NCRBUTTONDBLCLK

0x00A6

当光标在窗口的非客户区并双击鼠标右键时发送此消息

WM_NCMBUTTONDOWN

0x00A7

当光标在窗口的非客户区并按下鼠标中键时发送此消息

WM_NCMBUTTONUP

0x00A8

当光标在窗口的非客户区并释放鼠标中键时发送此消息

WM_NCMBUTTONDBLCL

0x00A9

当光标在窗口的非客户区并双击鼠标中键时发送此消息

WM_KEYDOWN

0x0100

按下一个非系统键(按下键时未按下“ALT”键)

WM_KEYUP

0x0101

释放一个非系统键

WM_CHAR

0x0102

按下某键,当TranslateMessage()转发WM_KEYDOWN后发送本消息

WM_DEADCHAR

0x0103

释放某键,当TranslateMessage()转发WM_KEYUP后发送本消息

WM_SYSKEYDOWN

0x0104

当按住ALT键同时按下其他键时发送此消息给拥有键盘焦点的窗口

WM_SYSKEYUP

0x0105

当释放一个键同时按住ALT键时发送此消息给拥有键盘焦点的窗口

WM_SYSCHAR

0x0106

当TranslateMessage()转发WM_SYSKEYDOWN后发送此消息给拥有键盘焦点的窗口

WM_SYSDEADCHAR

0x0107

当TranslateMessage()转发WM_SYSKEYUP后发送此消息给拥有键盘焦点的窗口

WM_INITDIALOG

0x0110

在被显示前发送此消息对话框,通常用此消息初始化控件和执行其他任务

WM_COMMAND

0x0111

选择窗口菜单项或某个控件发送一条消息给它的父窗口或按下一个快捷键时产生此消息

WM_SYSCOMMAND

0x0112

选择窗口菜单项或选择最大化或最小化时,发送此消息给该窗口

WM_TIMER

0x0113

发生了定时器事件

WM_HSCROLL

0x0114

当窗口水平滚动条产生一个滚动事件时发送此消息给该窗口和滚动条的所有者

WM_VSCROLL

0x0115

当窗口垂直滚动条产生一个滚动事件时发送此消息给该窗口和滚动条的所有者

WM_INITMENU

0x0116

当一个菜单将要被激活时发送此消息,它发生在按下菜单项或按下菜单快捷键时,它允许程序在显示前更改菜单

WM_INITMENUPOPUP

0x0117

当一个下拉菜单或子菜单将要被激活时发送此消息,它允许显示前在修改菜单而不必更改整个菜单

WM_MENUSELECT

0x011F

选择一条菜单项时发送此消息给菜单的所有者(一般是窗口)

WM_MENUCHAR

0x0120

当菜单已被激活且用户按下了某个键(非快捷键),发送此消息给菜单的所有者

WM_ENTERIDLE

0x0121

当一个有模式对话框或菜单进入空闲状态时发送此消息给它的所有者,空闲状态指在处理完一条或几条先前的消息后,消息列队为空

WM_MENURBUTTONUP

0x0122

当光标位于菜单项上时,释放鼠标右键产生此消息

WM_MENUDRAG

0x0123

当拖动菜单项时,发送此消息给拖放菜单的所有者

WM_MENUGETOBJECT

0x0124

当光标移入菜单项或者从菜单项中心移到菜单项顶部或底部时,发送此消息给拖放菜单的所有者

WM_UNINITMENUPOPUP

0x0125

当下拉菜单或者子菜单被销毁时产生此消息

WM_MENUCOMMAND

0x0126

当用户选择菜单项时产生此消息

WM_CHANGEUISTATE

0x0127

应用程序发送此消息表明用户界面(UI)状态应当被改变

WM_UPDATEUISTATE

0x0128

应用程序发送此消息改变指定窗口及其子窗口的用户界面(UI)状态

WM_QUERYUISTATE

0x0129

应用程序发送此消息得到某个窗口的用户界面(UI)状态

WM_CTLCOLORMSGBOX

0x0132

绘制消息框前发送此消息给它的父窗口,通过响应这条消息,父窗口可以通过使用给定的相关显示设备的句柄来设置消息框的文本和背景颜色

WM_CTLCOLOREDIT

0x0133

绘制编辑型控件前发送此消息给它的父窗口,可用来设置编辑框的文本和背景颜色

WM_CTLCOLORLISTBOX

0x0134

绘制列表框控件前发送此消息给它的父窗口,可用来设置编辑框的文本和背景颜色

WM_CTLCOLORBTN

0x0135

绘制按钮控件前发送此消息给它的父窗口,可用来设置编辑框的文本和背景颜色

WM_CTLCOLORDLG

0x0136

绘制对话框前发送此消息给它的父窗口,可用来设置编辑框的文本和背景颜色

WM_CTLCOLORSCROLLBAR

0x0137

绘制滚动条控件前发送此消息给它的父窗口,可用来设置滚动条控件的文本和背景颜色

WM_CTLCOLORSTATIC

0x0138

绘制静态控件前发送此消息给它的父窗口,可用来设置静态控件的文本和背景颜色

WM_MOUSEMOVE

0x0200

鼠标移动

WM_LBUTTONDOWN

0x0201

按下鼠标左键

WM_LBUTTONUP

0x0202

释放鼠标左键

WM_LBUTTONDBLCLK

0x0203

双击鼠标左键

WM_RBUTTONDOWN

0x0204

按下鼠标右键

WM_RBUTTONUP

0x0205

释放鼠标右键

WM_RBUTTONDBLCLK

0x0206

双击鼠标右键

WM_MBUTTONDOWN

0x0207

按下鼠标中键

WM_MBUTTONUP

0x0208

释放鼠标中键

WM_MBUTTONDBLCLK

0x0209

双击鼠标中键

WM_MOUSEWHEEL

0x020A

当鼠标滚轮转动时发送此消息给当前获得焦点的窗口

WM_PARENTNOTIFY

0x0210

当MDI子窗口被创建或被销毁,或当光标位于子窗口上且用户按了一下鼠标键时,发送此消息给它的父窗口

WM_ENTERMENULOOP

0x0211

发送此消息通知应用程序的主窗口进程已经进入了菜单模式循环

WM_EXITMENULOOP

0x0212

发送此消息通知应用程序的主窗口进程已经退出了菜单模式循环

WM_SIZING

0x0214

调整窗口大小时发送此消息给窗口,通过此消息应用程序可以监视或修改窗口大小和位置

WM_CAPTURECHANGED

0x0215

当窗口设定为不捕获鼠标事件时,发送此消息给该窗口

WM_MOVING

0x0216

移动窗口时发送此消息给窗口,通过此消息应用程序可以监视或修改窗口大小和位置

WM_POWERBROADCAST

0x0218

发送此消息给应用程序通知它有关电源管理事件

WM_DEVICECHANGE

0x0219

当设备的硬件配置改变时发送此消息给应用程序或设备驱动程序

WM_MDICREATE

0x0220

应用程序发送此消息给多文档的客户窗口来创建一个MDI 子窗口

WM_MDIDESTROY

0x0221

应用程序发送此消息给多文档的客户窗口来关闭一个MDI 子窗口

WM_MDIACTIVATE

0x0222

应用程序发送此消息给多文档的客户窗口通知客户窗口激活另一个MDI子窗口,当客户窗口收到此消息后,它发出WM_MDIACTIVE消息给MDI子窗口(未激活)来激活它

WM_MDIRESTORE

0x0223

应用程序发送此消息给MDI客户窗口通知子窗口恢复到原来大小

WM_MDINEXT

0x0224

应用程序发送此消息给MDI客户窗口激活下一个或前一个窗口

WM_MDIMAXIMIZE

0x0225

应用程序发送此消息给MDI客户窗口以最大化一个MDI子窗口

WM_MDITILE

0x0226

应用程序发送此消息给MDI客户窗口以平铺方式重新排列所有MDI子窗口

WM_MDICASCADE

0x0227

应用程序发送此消息给MDI客户窗口以层叠方式重新排列所有MDI子窗口

WM_MDIICONARRANGE

0x0228

应用程序发送此消息给MDI客户窗口重新排列所有最小化的MDI子窗口

WM_MDIGETACTIVE

0x0229

应用程序发送此消息给MDI客户窗口以找到激活的子窗口的句柄

WM_MDISETMENU

0x0230

应用程序发送此消息给MDI客户窗口用MDI菜单代替子窗口的菜单

WM_ENTERSIZEMOVE

0x0231

当窗口进入移动或改变大小模式循环时,发送此消息给该窗口

WM_EXITSIZEMOVE

0x0232

当窗口退出移动或改变大小模式循环时,发送此消息给该窗口

WM_DROPFILES

0x0233

当用户在应用程序窗口中拖动某个文件时,产生此消息

WM_MDIREFRESHMENU

0x0234

应用程序发送此消息给MDI客户窗口以刷新窗口菜单

WM_MOUSEHOVER

0x02A1

当光标在窗口客户区悬停超过TrackMouseEvent()指定的时间时,发送此消息给该窗口

WM_MOUSELEAVE

0x02A3

当光标离开窗口客户区超过TrackMouseEvent()指定的时间时,发送此消息给该窗口

WM_CUT

0x0300

应用程序发送此消息给一个编辑框或ComboBox以删除当前选择的文本

WM_COPY

0x0301

应用程序发送此消息给一个编辑框或ComboBox以复制当前选择的文本到剪贴板

WM_PASTE 

0x0302

应用程序发送此消息给一个编辑框或ComboBox以从剪贴板中得到数据

WM_CLEAR

0x0303

应用程序发送此消息给一个编辑框或ComboBox以清除当前选择的内容

WM_UNDO

0x0304

应用程序发送此消息给一个编辑框或ComboBox以撤消最后一次操作

WM_DESTROYCLIPBOARD

0x0307

当调用EmptyClipboard()清空剪贴板时,发送此消息给剪贴板所有者

WM_DRAWCLIPBOARD

0x0308

当剪贴板的内容变化时发送此消息给剪贴板观察链中的第一个窗口,它允许用剪贴板观察窗口来显示剪贴板的新内容

WM_PAINTCLIPBOARD

0x0309

当剪贴板包含CF_OWNERDIPLAY格式的数据且剪贴板观察窗口的客户区需要重绘时,发送此消息给剪贴板所有者

WM_VSCROLLCLIPBOARD

0x030A

当剪贴板包含CF_OWNERDIPLAY格式的数据且剪贴板观察窗口发生垂直滚动条事件时,剪贴板观察窗口发送此消息给剪贴板所有者

WM_SIZECLIPBOARD

0x030B

当剪贴板包含CF_OWNERDIPLAY格式的数据且剪贴板观察窗口的客户区域的大小已经改变时,剪贴板观察窗口发送此消息给剪贴板的所有者

WM_ASKCBFORMATNAME

0x030C

剪贴板观察窗口发送此消息给剪贴板所有者以获得CF_OWNERDISPLAY剪贴板格式的名字

WM_CHANGECBCHAIN

0x030D

当一个窗口从剪贴板观察链中移去时发送此消息给剪贴板观察链中的第一个窗口

WM_HSCROLLCLIPBOARD

0x030E

当剪贴板包含CF_OWNERDIPLAY格式的数据且剪贴板观察窗口发生水平滚动条事件时,剪贴板观察窗口发送此消息给剪贴板所有者

WM_QUERYNEWPALETTE

0x030F

发送此消息给将要获得键盘焦点的窗口,此消息使窗口在获得焦点时同时有机会实现它的逻辑调色板

WM_PALETTEISCHANGING

0x0310

应用程序将要实现它的逻辑调色板时发送此消息通知所有应用程序

WM_PALETTECHANGED

0x0311

获得焦点的窗口实现它的逻辑调色板后发送此消息给所有顶级并重叠的窗口,以此

来改变系统调色板

WM_HOTKEY

0x0312

当用户按下由RegisterHotKey()注册的热键时产生此消息

WM_PRINT

0x0317

应用程序发送此消息给窗口,要求窗口在指定设备环境中绘制自己,一般情况下是打印机设备环境

WM_PRINTCLIENT

0x0318

应用程序发送此消息给窗口,要求窗口在指定设备环境中绘制窗口客户区,一般情况下是打印机设备环境

WM_APP

0x8000

帮助用户自定义消息,自定义消息可以为WM_APP+X,X为正整数

WM_USER

0x0400

帮助用户自定义消息,自定义消息可以为WM_USER+X,X为正整数

3.3 总结

  表A-3  通告新闻-按键

1> ShellExecuteEx张开test.iqy的时先创设excel进程

消息名称

说 明

BN_CLICKED

单击按钮

BN_DISABLE

按钮被禁止

BN_DOUBLECLICKED

双击按钮

BN_HILITE

加亮按钮

BN_PAINT

按钮应当重画

BN_UNHILITE

加亮应当去掉

2> 然后制造八个”WorkerW”的窗口用于DDE通讯

表A-4  通告音讯-组合框

3> Post WM_DDE_EXECUTE给excel,告知张开test.iqy的指令

消息名称

说 明

CBN_CLOSEUP

组合框的列表框被关闭

CBN_DBLCLK

用户双击了一个字符串

CBN_DROPDOWN

组合框的列表框被拉下

CBN_EDITCHANGE

用户修改了组合框中的文本

CBN_EDITUPDATE

组合框内的文本即将更新

CBN_ERRSPACE

组合框内存不足

CBN_KILLFOCUS

组合框失去输入焦点

CBN_SELCHANGE

在组合框中选择了一项

CBN_SELENDCANCEL

用户的选择将被忽略

CBN_SELENDOK

用户的选择将被执行

CBN_SETFOCUS

组合框获得输入焦点

4> ShellExecuteEx试行完成,但并不destroy “WorkerW”窗口

表A-5  公告新闻-编辑框

5>
excel收到WM_DDE_EXECUTE音信后会广播WM_DDE_INITIATE新闻,”WorkerW”窗口所在的console进程由于没有定义新闻管理函数,ShellExecuteEx定义的”WorkerW”窗口新闻管理函数得不到CPU实施机缘,招致不会response该音讯,进而产生excel
hang住

消息名称

说 明

EN_CHANGE

编辑框中的文本己更新

EN_ERRSPACE

编辑框内存不足

EN_HSCROLL

用户点击了水平滚动条

EN_KILLFOCUS

编辑框失去输入焦点

EN_MAXTEXT

插入的内容被截断

EN_SETFOCUS

编辑框获得输入焦点

EN_UPDATE

编辑框中的文本将要更新

EN_VSCROLL

用户点击了垂直滚动条

接近,大家得以创立八个带窗口的程序,运维后将其挂起,这个时候,固然直接双击展开test.iqy也会hang住。

表A-6  公告新闻-列表框

 

消息名称

说 明

LBN_DBLCLK

用户双击了一项

LBN_ERRSPACE

列表框内存不足

LBN_KILLFOCUS

列表框正在失去输入焦点

LBN_SELCANCEL

用户选择被取消

LBN_SELCHANGE

用户选择将改变

LBN_SETFOCUS

列表框获得输入焦点

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

Windows音信大全

因为双击展开实际是用explorer.exe展开,而explorer.exe是有窗口的,能够健康的抽取管理WM_DDE_INITIATE消息

  Windows是风度翩翩消息(Message卡塔尔国驱动式系统,Windows新闻提供了应用程序与应用程序之间、应用程序与Windows系统之间开展报纸发表的手腕。应用程序要落到实处的功用由音信来触发,并靠对消息的响应和拍卖来产生。Windows系统中有三种音讯队列,风度翩翩种是系统新闻队列,另少年老成种是应用程序信息队列。计算机的保有输入设备由
Windows监察和控制,当一个风浪爆发时,Windows先将输入的音讯放入系统新闻队列中,然后再将输入的音讯拷贝到相应的应用程序队列中,应用程序中的新闻循环从它的新闻队列中检索每一个音信并发送给相应的窗口函数中。叁个平地风波的发出,达到管理它的窗口函数必得经验上述进度。值得注意的是音讯的非超越性,即无论是事件的急与缓,总是按到达的主次排队(一些类别新闻除却),那就使得有个别外表实时事件大概得不到马上的管理。

 

  由于Windows本人是由新闻使得的,举叁个例证来证实那个主题材料。打开记事本程序,该程序有多少个File菜单,那么,在运作该应用程序的时候,假诺顾客单击了File菜单里New命令时,那个动作将被Windows
(实际不是应用程序本身!卡塔尔国所捕获,Windows经过分析获知那一个动作应该由位置所说的极度应用程序去管理,既然是这么,Windows就发送了个名称为WM_COMMAND的音讯给应用程序,该音讯所满含消息报告应用程序:”客户单击了New菜单”,应用程序获悉那风度翩翩音信随后,接受对应的动作来响应它,这一个进度称为新闻管理。Windows为每一个应用程序(确切地说是每叁个线程)维护了对应的新闻队列,应用程序的职分正是不停的从它的新闻队列中拿到消息,深入分析新闻和管理新闻,直到一条吸取名称为WM_QUIT新闻停止,那些进度平时是由风度翩翩种叫做音讯循环的程序结构来落到实处的。

5. 怎么win7上不会有诸如此比的主题素材

  音讯笔者是当作多个笔录传递给应用程序的,这几个记录中含有了消息的品种以致任何音信。举个例子,对于单击鼠标所发出的信息的话,那个记录中蕴涵了单击鼠标时的坐标。这些记录类型叫做T
M s g,它在Wi n d o w s单元中是如此注解的:

5.1 在API Monitor中看下PostMessageW

type

澳门新萄京8522 115

TMsg = packedrecord

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

hwnd: HWND / /窗口句柄

澳门新萄京8522 116

message: UINT / /新闻常量标志符

可以知道是ShellExecuteEx内部制造的线程,所以win7上ShellExecuteEx创造了一个线程专门用来拍卖和excel的DDE音信通讯,那样就能够寻常的选取管理excel发过来的WM_DDE_INITIATE消息了

wParam: WPA 哈弗 AM  // 叁15人消息的一定附加新闻

lParam: LPA 揽胜 AM  // 叁十一人音讯的一定附加新闻

time: DWO凯雷德D / /新闻创造时的岁月

pt: TPoint / /音讯创造时的鼠标地方

end

 

消息中有如何?

是否以为一个音信记录中的消息像马耳他语雷同?假设是如此,那么看大器晚成看上边包车型大巴表明:

hwnd
三16位的窗口句柄。窗口可以是别的类型的荧屏对象,因为Win32力所能致有限匡助大繁多可视对象的句柄(窗口、对话框、开关、编辑框等)。

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

wParam 经常是贰个与音讯有关的常量值,也或然是窗口或控件的句柄。

lParam
平常是二个照准内部存款和储蓄器中数据的指针。由于WParm、lParam和Pointer都以31个人的,由此,它们中间能够相互转变。

 

WM_NULL = 0

WM_CREATE = 1

应用程序成立贰个窗口

WM_DESTROY = 2

三个窗口被销毁

WM_MOVE = 3

活动二个窗口

WM_SIZE = 5

改造多少个窗口的大小

WM_ACTIVATE = 6

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

WM_SETFOCUS = 7

赢得主旨后

WM_KILLFOCUS = 8

失去核心

WM_ENABLE = 10

改变enable状态

WM_SETREDRAW = 11

设置窗口是不是能重画

WM_SETTEXT = 12

应用程序发送此音信来设置三个窗口的文本

WM_GETTEXT = 13

应用程序发送此音信来复制对应窗口的公文到缓冲区

WM_GETTEXTLENGTH =14

赢得与三个窗口有关的公文的长短(不分包空字符卡塔 尔(阿拉伯语:قطر‎

WM_PAINT = 15

渴求一个窗口重画自身

WM_CLOSE = 16

当二个窗口或应用程序要关闭时发送四个非随机信号

WM_QUERYENDSESSION= 17

当客商筛选截至对话框或程序本身调用ExitWindows函数

WM_QUIT = 18

用来终止程序运营或当程序调用postquitmessage函数

WM_QUERYOPEN = 19

当客户窗口复苏原先的尺寸地点时,把此音讯发送给有些Logo

WM_ERASEBKGND = 20

当窗口背景必得被擦除时(例在窗口变越来越大小时卡塔 尔(英语:State of Qatar)

WM_SYSCOLORCHANGE =21

当系统颜色改良时,发送此消息给全体一级窗口

WM_ENDSESSION = 22

当系统经过产生WM_QUESportageYENDSESSION音信后,此音信发送给应用程序,

照会它对话是不是甘休

WM_SYSTEMERROR = 23

WM_SHOWWINDOW = 24

当隐蔽或显示窗口是出殡和安葬此音讯给那一个窗口

WM_ACTIVATEAPP = 28

发此音讯给应用程序哪个窗口是激活的,哪个是非激活的;

WM_FONTCHANGE = 29

当系统的书体能源库变化时发送此消息给全体一流窗口

WM_TIMECHANGE = 30

当系统的时光改造时发送此消息给持有超级窗口

WM_CANCELMODE = 31

出殡此新闻来撤除某种正在打开的摸态(操作卡塔 尔(英语:State of Qatar)

WM_SETCURSOR = 32

假若鼠标引起光标在有些窗口中活动且鼠标输入未有被破获时,就发音信给有些窗口

WM_MOUSEACTIVATE =33

发表评论

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

网站地图xml地图