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

2019-11-08 18:52栏目:IT操作系统

1. 问题

1. 窗口进程 
各个窗口会有三个称呼窗口进度的回调函数(WndProc),它包括八个参数,分别为:窗口句柄(Window Handle),新闻ID(Message ID),和五个音信参数(wParam, lParam),当窗口收到消息时系统就能够调用此窗口进度来拍卖音讯。(所以叫回调函数卡塔尔

新闻是指什么?
     新闻系统对此三个win32前后相继来讲非常要害,它是多个程序运维的动源泉。一个消息,是系统定义的三个三12位的值,他唯豆蔻年华的概念了贰个事变,向 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.0x0400(WM_USEENCORE)-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_SETCULacrosseSOEscort音讯。那一个新闻通告窗口它早就被激活了,键盘输入正指向该窗口,鼠标光标已经移至了窗口边框内。当应用程序调用有个别系统函数时,也会窗口非队列信息,举个例子,应用程序在调用SetWindowPos时,系统将发送WM_WINDOWPOSCHANGED消息。

有一点消息发送非队列音信:布罗兹castSystemMessage, 布罗兹castSystemMessageEx, SendMessage, SendMessageTimeout, 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可能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, LOWO奥迪Q7D(wParam)表示菜单项,工具栏开关或控件的ID。假如是控件, HIWORAV4D(wParam)表示控件音讯类型
3> 控件文告(Notify Message) 
控件文告新闻, 那是最灵敏的音信格式, 其Message, wParam, lParam分别为:WM_NOTIFY, 控件ID,指向NMHDENCORE的指针。NMHDGL450富含控件通知的内容, 能够专擅增添。
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

ca888会员登录 1typedef struct tagMsg
ca888会员登录 2{
ca888会员登录 3       HWND    hwnd;       //选拔该音讯的窗口句柄
ca888会员登录 4       UINT    message;    //新闻常量标记符,也正是我们粗衣粝食所说的信息号
ca888会员登录 5       WPARAM  wParam;     //三十个人音讯的一定附加音讯,确切含义注重于音信值
ca888会员登录 6       LPARAM  lParam;     //叁10个人音信的特定附加消息,确切含义重视于音讯值
ca888会员登录 7       DWO昂科威D   time;       //音讯成立时的日子
ca888会员登录 8       POINT   pt;         //消息创造时的鼠标/光标在显示器坐标系中之处
ca888会员登录 9}MSG;
ca888会员登录 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都以三十五人的,由此,它们中间能够互相转变。

该函数将得到和hWnd也许其子窗口相关的消息。

DWORD GetMessagePos(void);

复出碰到:XP sp3 / Office 2006(别的office版本应该也能够,未有测量检验卡塔尔

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

音讯标志符的值
     系统一保险留消息标志符的值在0x0000在0x03ff(WM_USEMercedes-A名爵-1)范围。那个值被系统定义新闻使用。应用程序不能够选用那么些值给自个儿的消息。应用程序音讯从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USE昂科威到 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_KEYBOA卡宴D 表面新闻来源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_E奥迪Q3传祺SPACE 组合框内部存款和储蓄器不足
 CBN_KILLFOCUS 组合框失去输入主题
 CBN_SELCHANGE 在组合框中精选了意气风发项
 CBN_SELENDCANCEL 顾客的取舍应该被撤回
 CBN_SELENDOK 客户的选料是官方的
 CBN_SETFOCUS 组合框得到输入主旨

新闻来源未知

DWORD GetQueueStatus(
UINT flags
);
在音信队列中的新闻的项目
flags为要检查评定的消息类型。

2> 运行http_server.py(需先安装python卡塔尔国

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_EEvoque驭胜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_EEscortMuranoSPACE 列表框内部存款和储蓄器远远不够
 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的目标是为着减少刷新窗口的次数。
ca888会员登录 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 %pn", shell_exec_info.hProcess);

    return ret;
}

ca888会员登录 12
    非队列音信将会绕过系统队列和新闻队列,直接将音信发送到窗口进程,。系统一发布送非队列音信文告窗口,系统一发布送消息布告窗口。比方,当顾客激活二个窗口系统一发布送WM_ACTIVATE, WM_SETFOCUS, and WM_ca888会员登录,SETCU奥迪Q5SO本田UR-V。这一个音信文告窗口它被激活了。非队列新闻也得以由当应用程序调用系统函数发生。比如,当程序调用SetWindowPos系统一发布送WM_WINDOWPOSCHANGED消息。一些函数也发送非队列音讯,比如下边我们要聊到的函数。
     
音讯的殡葬
     精通了下面的那么些底子理论之后,我们就足以扩充一下简易的信息发送与摄取。
     把一个新闻发送到窗口有3种方法:发送、寄送和广播。
     发送音信的函数有SendMessage、SendMessageCallback、SendNotifyMessage、 SendMessageTimeout;寄送音讯的函数主要有PostMessage、PostThreadMessage、 PostQuitMessage;广播新闻的函数笔者明白的独有布罗兹castSystemMessage、 布罗兹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个具备代表性的函数,大家能够看看音讯的出殡和安葬方式和寄送方式的界别所在:被发送的音信是不是会被马上管理,函数是或不是及时回去。被发送的信息会被马上管理,管理完结后函数才会回到;被寄送的新闻不会被当即管理,他被放到三个先进先出的队列中,一向等到应用程序空线的时候才会被拍卖,但是函数放置音讯后即时赶回。
ca888会员登录 13
  实际上,发送新闻到四个窗口管理进程和间接调用窗口管理进程之间并从未太大的界别,他们直白的头一无二分歧就在于你能够必要操作系统截获全部被发送的新闻,不过不能收获对窗口管理进程的第一手调用。
  以寄送措施发送的音信平时是与顾客输入事件相呼应的,因为这个事件不是可怜急如星火,可以扩充缓慢的缓冲管理,例如鼠标、键盘音信会被寄送,而按键等消息则会被发送。
  广播新闻用得少之甚少,布罗兹castSystemMessage函数原型如下:
      long 布罗兹castSystemMessage(DWO宝马7系D dwFlags,LPDWOPAJEROD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam);该函数能够向钦命的收信人发送一条音信,那几个接纳者能够是应用程序、可设置的驱动程序、网络驱动程序、系统级其他设施驱动新闻和他们的自便组合。要求潜心的是,纵然dwFlags参数是BSF_QUE福睿斯Y并且起码二个接纳者再次来到了BROADCAST_QUERY_DENY,则再次回到值为0,若无点名BSF_QUETucsonY,则函数将音信发送给全体接纳者,並且忽视其再次来到值。

若果发送音信低于WM_USE奥迪Q7范围,到异步新闻队列函数(PostMessage、SendNotifyMessage卡塔尔国,音讯参数不应有富含指针,不然的话,操作将失利。该函数将要抽出线程有机缘管理该新闻前回来,发送者将释放刚刚用到的内部存款和储蓄器。

PostQuitMessage

 

消息的收到
 音信的收受首要有3个函数:GetMessage、PeekMessage、WaitMessage。
  GetMessage原型如下:BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilter马克斯);该函数用来赢得与hWnd参数所钦赐的窗口相关的且wMsgFilterMin和wMsgFilter马克斯参数所提交的新闻值范围内的音讯。必要小心的是,如若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在哪里?

ca888会员登录 14while(GetMessage(&msg, NULL, 0, 0))
ca888会员登录 15{
ca888会员登录 16       if(!TranslateAccelerator(msg.hWnd, hAccelTable, &msg))
ca888会员登录 17      { 
ca888会员登录 18            TranslateMessage(&msg);
ca888会员登录 19            DispatchMessage(&msg);
ca888会员登录 20       }
ca888会员登录 21}

该函数通过调用窗口进程的艺术发送新闻,倘诺窗口归属分歧线程,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的主次是事件驱动的。他们不做任何彰显调...

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

 

ca888会员登录 22

   首先,GetMessage从进程的主线程的新闻队列中收获三个音信并将它复制到MSG结构,假设队列中绝非新闻,则GetMessage函数将静观其变一个音信的光降现在才回来。假诺您将三个窗口句柄作为首个参数字传送入GetMessage,那么唯有钦赐窗口的的消息能够从队列中赢得。GetMessage也能够从音信队列中过滤音信只选拔新闻队列中落在限制内的消息。这个时候将在动用GetMessage/PeekMessage钦定多少个音信过滤器。这么些过滤器是二个音信标志符的约束只怕是叁个窗体句柄,或许双方同时内定。当应用程序要物色叁个后入音讯队列的新闻是很有用。WM_KEYFIRST 和 WM_KEYLAST 常量用于接收全部的键盘信息。 WM_MOUSEFIRST 和 WM_MOUSELAST 常量用于接收全数的鼠标音讯。 
 然后TranslateAccelerator判定该新闻是不是二个开关消息还如果二个加快键音信,假诺是,则该函数将把多少个按钮音讯转变来三个加快键音信传递给窗口的回调函数。管理了加速键之后,函数TranslateMessage将把四个按钮音信WM_KEYDOWN和WM_KEYUP转变到二个WM_CHA凯雷德,可是须求留意的是,音信WM_KEYDOWN,WM_KEYUP仍旧将传递给窗口的回调函数。     
 管理完以往,DispatchMessage函数将把此消息发送给该音讯钦点的窗口中已设定的回调函数。假如音讯是WM_QUIT,则 GetMessage再次回到0,进而退出循环体。应用程序能够动用PostQuitMessage来结束本人的音信循环。常常在主窗口的 WM_DESTROY音讯中调用。
 下边大家举叁个遍布的小例子来证实这么些新闻泵的运用:

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

ca888会员登录 23if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE))
ca888会员登录 24{
ca888会员登录 25          if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)...
ca888会员登录 26}
ca888会员登录 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

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

由此能够疑惑是由于console进度在和excel用DDE新闻通讯时,console未有响应excel发送的DDE音讯,引致excel hang住

 

 

新闻分流器
  经常的窗口进程是经过二个switch语句来落实的,那个专门的学业很烦,有未有更方便人民群众的不二等秘书技吗?有,这正是消息分流器,利用音信分流器,我们能够把switch语句分成越来越小的函数,每三个音信都对应二个小函数,那样做的益处正是对音讯更易于处理。
  之所以被誉为新闻分流器,正是因为它能够对任何音信进行分流。上边大家做贰个函数就很掌握了:

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

ca888会员登录 74void MsgCracker(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)
ca888会员登录 75{
ca888会员登录 76      switch(id)
ca888会员登录 77      {
ca888会员登录 78     case ID_A:
ca888会员登录 79                  if(codeNotify==EN_CHANGE)ca888会员登录 80
ca888会员登录 81                  break;
ca888会员登录 82     case ID_B:
ca888会员登录 83                  if(codeNotify==BN_CLICKED)ca888会员登录 84
ca888会员登录 85                  break;
ca888会员登录 86             ca888会员登录 87.
ca888会员登录 88       }
ca888会员登录 89}
ca888会员登录 90

3.2.1 依照微软的文书档案可以预知,发送DDE音讯除了WM_DDE_INITIATE和WM_DDE_ACK之外用的都以PostMessage

然后大家修改一下窗口进程:

ca888会员登录 91LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
ca888会员登录 92{
ca888会员登录 93       switch(message)
ca888会员登录 94      {
ca888会员登录 95             HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);
ca888会员登录 96             HANDLE_MSG(hWnd,WM_DESTROY,MsgCracker);
ca888会员登录 97           default:
ca888会员登录 98                    return DefWindowProc(hWnd, message, wParam, lParam);
ca888会员登录 99   }
ca888会员登录 100  return 0;
ca888会员登录 101}

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

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

ca888会员登录 102

ca888会员登录 103   #define HANDLE_MSG(hwnd,msg,fn) 
ca888会员登录 104             switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));

call stack彰显实在是ShellExecuteEx所调用

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

ca888会员登录 105

ca888会员登录 106   #define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn) 
ca888会员登录 107             ((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0L);

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

好了,事情到了这一步,应该全套都晴朗了。
唯独,大家发以往windowsx.h里面还应该有一个宏:FO索罗德WA奔驰M级D_WM_XXXX,大家照旧那WM_COMMAND为例,举行解析:

潜心到下二个API GetWindowThreadProcessId ( 0x00310172 , 0x0012fb70 ),正好是获得那个窗口的pid和tid,查看下参数窗口:

ca888会员登录 108   #define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) 
ca888会员登录 109     (void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl))

那几个窗口所属的经过PID = 0xc54,恰巧是excel的经过,表达ShellExecuteEx确实发送了DDE音讯给excel,何况可执发送的音讯的thread正是主线程

据此其实,FO途胜WAPAJEROD_WM_XXXX将新闻参数举行了再一次布局,生成了wParam && lParam,然后调用了小编们定义的函数。

ca888会员登录 110

日前,大家深入分析了音信的基本理论和着力的函数及用法,接下去,大家将尤其研究音讯传递在MFC中的完毕。

依照DDE的消息参数,可以预知wParam正是发送新闻的窗口,其句柄为2425190 = 0x250166,反向查询知那是ShellExecuteEx创建的”WorkerW”窗口

MFC新闻的拍卖达成形式
  初看MFC中的种种音讯,甚至在脑子中坚固的C 的影响,大家恐怕很自然的就能够想到利用C 的三大特色之风姿浪漫:虚构机制来完结消息的传递,不过通过解析,我们看来专门的职业并非想大家想象的那么,在MFC中音信是经过后生可畏种所谓的音信映射机制来拍卖的。
  为啥吗?在潘爱中华民族解放先锋生翻译的《Visual C 技艺内部情形》(第4版卡塔尔国中提交了详实的因由表达,小编再简单的讲三回。在CWnd类中山大学约有113个音信,还也可能有任何的MFC的类呢,算起来音信太多了,在C 中对程序中用到的每四个派生类都要有叁个vtable,每一个虚函数在vtable中都要侵夺八个4字节高低的进口地址,那样一来,对于每一种特定项目标窗口或控件,应用程序都必要叁个440KB大小的表来扶植设想新闻控件函数。
  假若说上面的窗口或控件能够勉强落成的话,那么对于菜单命令音讯及开关命令音信啊?因为分化的应用程序有分歧的美食指南和开关,我们怎么管理吧?在MFC 库的这种新闻映射系统就幸免了动用大的vtable,况且能够在管理常规Windows音讯的同期管理百端待举的应用程序的下令音讯。
  说白了,MFC中的新闻机制其实质是一张高大的信息及其管理函数的逐大器晚成对应表,然后加上解析管理这张表的运用框架之中的风流洒脱部分顺序代码.那样就可以制止在SDK编制程序中用到的麻烦的CASE语句。

ca888会员登录 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暗中同意对象;在新的非私下认可对象中或在恐怕要传播命令的通令指标中。

ca888会员登录 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列表框展现此类的抢先50%(若不是全体的话)可重载成员函数和窗口语资源音信息。类重载呈现在列表的上部,以实际杜撰成员函数的朗朗上口写字母来表示。其余为窗口音信,以大写字母现身,描述了实在窗口所能响应的新闻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) 最终,在该公文中加多音讯管理函数的实业。

ca888会员登录 113

 

翻看一下buff的地址:

 

ca888会员登录 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卡塔 尔(英语:State of Qatar)驱动式系统,Windows音信提供了应用程序与应用程序之间、应用程序与Windows系统之间张开电视发表的手段。应用程序要落到实处的职能由音讯来触发,并靠对音信的响应和拍卖来形成。Windows系统中有三种音信队列,生机勃勃种是系统音讯队列,另黄金年代种是应用程序新闻队列。Computer的具备输入设备由 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

ca888会员登录 115

TMsg = packedrecord

留神到win7下PostMessageW是用的线程2调用的,搜一下线程创设API CreateThread

hwnd: HWND / /窗口句柄

ca888会员登录 116

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

可以知道是ShellExecuteEx内部创设的线程,所以win7上ShellExecuteEx创制了多少个线程特意用来拍卖和excel的DDE音讯通讯,那样就能够健康的收取管理excel发过来的WM_DDE_INITIATE消息了

wParam: WPA 奥迪Q5 AM  // 三10位音讯的特定附加音信

lParam: LPA XC90 AM  // 32人新闻的一定附加音讯

time: DWOTiggoD / /音信成立时的小时

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

end

 

音信中有啥?

是还是不是感到一个消息记录中的新闻像爱沙尼亚语相像?要是是如此,那么看后生可畏看下边包车型地铁讲授:

hwnd 34位的窗口句柄。窗口能够是别的项目标荧屏对象,因为Win32能够保养大非常多可视对象的句柄(窗口、对话框、开关、编辑框等)。

message 用于区分其余音信的常量值,这几个常量能够是Windows单元中预约义的常量,也足以是自定义的常量。

wParam 平日是三个与音讯有关的常量值,也恐怕是窗口或控件的句柄。

lParam 日常是多个针对内部存款和储蓄器中多少的指针。由于WParm、lParam和Pointer都是33人的,由此,它们之间能够相互调换。

 

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

得到与几个窗口有关的文本的长短(不含有空字符卡塔 尔(英语:State of Qatar)

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_QUE冠道YENDSESSION新闻后,此消息发送给应用程序,

照会它对话是不是截至

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

版权声明:本文由ca888发布于IT操作系统,转载请注明出处:至于windows操作系统之音信和音信队列