关于windows操作系统之新闻和音讯队列

作者:操作系统

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

1. 窗口进度 
每一种窗口会有二个叫做窗口进程的回调函数(WndProc),它蕴涵多少个参数,分别为:窗口句柄(Window Handle),消息ID(Message ID),和多少个消息参数(wParam, lParam),当窗口收到音讯时系统就能够调用此窗口进程来拍卖音信。(所以叫回调函数卡塔 尔(英语:State of Qatar)

此消息发送给窗口当它就要改进大小或岗位;

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

DWORD GetMessagePos(void);

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

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本田CR-VD(wParam)表示菜单项,工具栏开关或控件的ID。假使是控件, HIWO本田CR-VD(wParam)表示控件音信类型
3> 控件通告(Notify Message) 
控件文告音讯, 那是最灵敏的新闻格式, 其Message, wParam, lParam分别为:WM_NOTIFY, 控件ID,指向NMHDCRUISER的指针。NMHDQashqai包罗控件布告的内容, 可以恣心纵欲扩充。
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

当三个会话框控件将要被绘制前发送此音讯给它的父窗口;通过响应那条音讯,全体者窗口能够

用来决断当前窗口进程所处理的音讯,是还是不是来自别的线程的SendMessage调用。

PeekMessage
1.该函数核实线程新闻队列中是或不是有音信,并将信息放在参数结构体中
2.譬如hWnd参数=-1,则只回去hWnd=NULL的新闻,这种音讯来自PostThreadMessage
3.参数wRemoveMsg必要潜心

 

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

通过响应WM_GETDLGCODE音信,应用程序能够把她真是二个特殊的输入控件并能管理它

该函数只是简单注明被倡议终止的线程将会告黄金年代段落。选择WM_QUIT的线程,应该告黄金年代段落音讯循环,并将调整权交给系统。重回给系统的淡出值,一定是WM_QUIT的wParam参数

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

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


RegisterWindowMessage
同一字符串,注册的值,在全部种类中是头一无二的


SendMessage

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

9 BroadcastSystemMessage 
我们常常所接触到的音讯皆以发送给窗口的,其实, 音讯的接受者能够是有滋有味的,它能够是应用程序(applications), 可设置驱动(installable drivers),互联网设施(network drivers), 系统级设备驱动(system-level device drivers)等, 
布罗兹castSystemMessage那个API能够对以上系统组件发送消息。

当剪贴板包罗CF_OWNERAV4DIPLAY格式的数量同一时间剪贴板旁观窗口的顾客区要求重画;

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

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

当在console中调用API ShellExecuteEx展开"test.iqy"文件时,发掘excel会hang住,console退出后excel才会响应,但一向双击"test.iqy"是不曾难点的,有趣的是以此状态独有在xp发生,在win7上从未有过这几个标题。

WM_DDE_INITIATE =WM_DDE_FIRST 0

假设发送消息低于WM_USE帕杰罗范围,到异步新闻队列函数(PostMessage、SendNotifyMessage卡塔 尔(英语:State of Qatar),音信参数不该满含指针,不然的话,操作将倒闭。该函数将要收到线程有机缘管理该音信前回到,发送者将释放刚刚用到的内部存款和储蓄器。

PostQuitMessage

5. 为啥win7上不会有那般的标题

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

WM_MEASUREITEM = 44

非音讯队列格局,直接调用窗口进度,系统及时切换成收到线程实行,发送线程锁住,知道选取线程管理落成

SendMessageTimeout

3.2.1 依据微软的文书档案可以看到,发送DDE新闻除了WM_DDE_INITIATE和WM_DDE_ACK之外用的都是PostMessage

6 GetMessage, PeekMessage 
PeekMessage会马上回到能够保留新闻
GetMessage在有音讯时重临会删除消息

type

有关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_USERubicon)-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_SETCUPorsche911SOENVISION音讯。那么些新闻文告窗口它已经被激活了,键盘输入正指向该窗口,鼠标光标已经移至了窗口边框内。当应用程序调用某个系统函数时,也会窗口非队列音讯,比如,应用程序在调用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或然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.种类预订义音信其实大都是那个控件音讯,通告音信,系统广播音讯等等。

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

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来制止现身死锁。

WM_VKEYTOITEM = 46

信息相关函数:

DispatchMessage

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

图片 1

7 TranslateMessage, TranslateAccelerator 
TranslateMessage: 把三个virtual-key消息转产生字符新闻(character message),并放置当前线程的音讯队列中,新闻循环下二遍抽出处理。
TranslateAccelerator:将快速键对应到对应的菜系命令。它会把WM_KEYDOWN 或 WM_SYSKEYDOWN转形成飞快键表中相应的WM_COMMAND或WM_SYSCOMMAND音信, 然后把转变后的 WM_COMMAND或WM_SYSCOMMAND直接发送到窗口进程管理, 管理完后才会重临。

WM_ENABLE = 10

该函数再次来到音信x,y坐标,在多种monitor下,或然有负值。

GetMessageQueueReadyTimeStamp

 

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_TIMELacrosse只有在Queue中从不其它音讯的时候才会被拍卖,WM_PAINT音讯还或许会被统一以提升作用。别的具有音讯以先进先出(FIFO卡塔尔国的法子被管理。

当贰个静态控件就要被绘制时发送此音信给它的父窗口;通过响应这条音讯,全数者窗口能够

4.假诺应用程序正在创造顶层窗口时调用PeekMessage,将促成窗口窗口被创立在Z-Order的结尾。你要求在PeekMessage后,显式调用SetForegroundWindow。假如应用程序以至有贰个松开窗口了,那么新窗口将被安置。

PostMessage
应用程序要用HWND_BROADCAST实路程序间的竞相,新闻应该获得于RegisterWindowMessage()

3.2 为了验证3.1.1的推断,用API Monitor一下ShellExecuteEx

WM_CTLCOLORMSGBOX =306

该函数通过调用窗口进程的章程发送新闻,如果窗口归于分裂线程,SendMessageTimerout将明了音讯管理实现才重临大概钦命的过期已经过去,就算窗口就在时下线程,则直接调用窗口进度,并忽视time-out超时

SendNotifyMessage
假使窗口创造于归于发送信息的线程,则调用窗口进度,并等候窗口进度管理完成该音讯。假使是分歧线程,则将音讯传递到窗口进度,并当即回到,不等待窗口进程的音讯管理进度。

--
TranslateMessage
1.将虚构键音信调换为字符音信,然后将字符音信发送到调用线程的音讯队列中,该字符新闻就要下一次调用GetMessage大概PeekMessage音信的时候取拿到。
2.WM_(SYS)KEYDOWN/UP--->WM_(SYS)_CHAR
3.假诺应用程序为了其他指标,处理设想键音讯,那么就不应有调用TranslateMessage.与两个实例,应用程序不应有在TranslateAccelerator函数再次回到非0值时调用TranslateMessage

关于音讯和音讯队列 不像基于MS-DOS的应用程序,基于Windows的程序是事件驱动的。他们不做任何显示调...

图片 2

WM_CTLCOLOREDIT =307

音讯来源未知

DWORD GetQueueStatus(
UINT flags
);
在音信队列中的音讯的花色
flags为要检查测验的消息类型。

1. 问题

拿到线程方今一遍计划管理叁个音信的连串时间(GetTickCount卡塔 尔(英语:State of Qatar)

GetMessageSource
MSGSRC_SOFTWARE_POST表面键盘消息来源于software(postmessage标志为software卡塔 尔(英语:State of Qatar). MSGSRC_HARDWARE_KEYBOAEvoqueD 表面音信来源于keyboard. MSGSRC_UNKNOWN

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

WM_LBUTTONDOWN =513

回去值得高字节表示近年来在音信队列中的音信类型。低字节表示从上次GetQueueStatus,GetMessage或然PeekMessage后被投入队列的音讯类型。

InSendMessage

WM_COALESCE_LAST =927

 

 

5.1 在API Monitor中看下PostMessageW

列表框

 

表A-4  公告音信-组合框

 

在WM_NOTIFY新闻,使用此控件能使某些控件与它的父控件之间实行相互通信

当the list box 或 combo box 被销毁 或 当 某个项被删除通过LB_DELETESTRING,LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT 消息

适逢其会正是开垦test.iqy的指令,表达ShellExecuteEx正是先创建了excel的进程,然后发送test.iqy的文书命令给excel张开。

当某些窗口第二次被成立时,此新闻在WM_CREATE新闻发送前发送;

call stack显示实在是ShellExecuteEx所调用

窗口进度
 窗口进程是八个用于拍卖全体发送到那么些窗口的新闻的函数。任何四个窗口类都有叁个窗口进程。同三个类的窗口使用相通的窗口进度来响应音讯。系统一发布送音讯给窗口进度将信息数据作为参数字传送递给他,音信赶到之后,遵照音信类型排序进行拍卖,个中的参数则用来差别不相同的音讯,窗口过程使用参数产生合适行为。
 叁个窗口进程不平时忽视音讯,要是他不管理,它会将消息传回到实行暗许的拍卖。窗口进程通过调用DefWindowProc来做这几个管理。窗口进度必得return三个值作为它的音信管理结果。大多数窗口只管理小部分音讯和将其他的通过DefWindowProc传递给系统做暗许的管理。窗口进度被抱有归属同二个类的窗口共享,能为不相同的窗口管理新闻。上面大家来看一下现实的实例:

能够是ShellExecuteEx内部成立的线程,所以win7上ShellExecuteEx成立了四个线程专门用来管理和excel的DDE音讯通讯,那样就能够通常的接受处理excel发过来的WM_DDE_INITIATE消息了

前后相继在体现前修正菜单

3. 缘由深入分析

WM_VSCROLLCLIPBOARD= 778

图片 3

C B N _ S E T F O CU S组合框获得输入主题

5> excel收到WM_DDE_EXECUTE新闻后会广播WM_DDE_INITIATE音信,"WorkerW"窗口所在的console进度由于并未定义音信管理函数,ShellExecuteEx定义的"WorkerW"窗口音信处理函数得不到CPU实行机遇,诱致不会response该新闻,进而引致excel hang住

当三个编辑型控件就要被绘制时发送此新闻给它的父窗口;通过响应那条信息,全体者窗口能够

3.3 总结

经过利用给定的连带呈现设备的句柄来设置滚动条的背景颜色

1> 解压iqy_test.zip

前后相继发送此新闻给MDI顾客窗口以层叠方式重新排列全体MDI子窗口

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

当MDI子窗口被创立或被销毁,或顾客按了一下鼠标键而光标在子窗口上时发送此新闻给它的父窗口

因为双击展开实际是用explorer.exe打开,而explorer.exe是有窗口的,能够通常的选用项理WM_DDE_INITIATE消息

WM_QUERYOPEN = 19

再次出现情况:XP sp3 / Office 二〇〇六(别的office版本应该也得以,未有测验卡塔尔

MFC音信的拍卖完成格局
  初看MFC中的各样新闻,以致在头脑中稳步的C 的震慑,大家兴许很自然的就能够想到利用C 的三大特点之大器晚成:虚构机制来达成音信的传递,可是透过剖析,我们看见工作并非想我们想象的那么,在MFC中国国投息是经过风流倜傥种所谓的音讯映射机制来拍卖的。
  为啥吧?在潘爱中华民族解放先锋生翻译的《Visual C 技巧内情》(第4版卡塔 尔(英语:State of Qatar)中提交了详尽的来由表达,小编再不问可以看到三次。在CWnd类中山大学约有110个音信,还应该有任何的MFC的类呢,算起来新闻太多了,在C 中对程序中用到的每一个派生类都要有一个vtable,各种虚函数在vtable中都要占领二个4字节高低的输入地址,那样一来,对于每一个特定项指标窗口或控件,应用程序都必要一个440KB大小的表来辅助虚构音讯控件函数。
  要是说上边的窗口或控件能够勉强达成的话,那么对于菜单命令消息及开关命令消息吧?因为不相同的应用程序有例外的美食做法和开关,大家怎么管理呢?在MFC 库的这种新闻映射系统就防止了利用大的vtable,并且能够在管理常规Windows音讯的还要管理百废待举的应用程序的授命新闻。
  说白了,MFC中的音信机制其实质是一张高大的消息及其管理函数的依次对应表,然后加上解析管理那张表的应用框架之中的有些顺序代码.那样就能够幸免在SDK编制程序中用到的繁杂的CASE语句。

2. 再次出现步骤

消息名称

说 明

EN_CHANGE

编辑框中的文本己更新

EN_ERRSPACE

编辑框内存不足

EN_HSCROLL

用户点击了水平滚动条

EN_KILLFOCUS

编辑框失去输入焦点

EN_MAXTEXT

插入的内容被截断

EN_SETFOCUS

编辑框获得输入焦点

EN_UPDATE

编辑框中的文本将要更新

EN_VSCROLL

用户点击了垂直滚动条

基于DDE的音信参数,可以预知wParam就是发送消息的窗口,其句柄为2425190 = 0x250166,反向查询知那是ShellExecuteEx创立的”WorkerW”窗口

C B N _ E D I T U PD AT E编辑框内的文件就要履新

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

当贰个开关控件将在被绘制时发送此音信给它的父窗口;通过响应那条新闻,全数者窗口可以

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

当某些客商打消程序日志激活状态,提交此音信给程序

图片 4

WM_PALETTEISCHANGING=784

 

在windows绘制新闻框前出殡此消息给音讯框的主人窗口,通过响应那条消息,全体者窗口能够

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

透过利用给定的连带显示设备的句柄来设置对话框的公文背景颜色

本条窗口所属的历程PID = 0xc54,凑巧是excel的长河,表达ShellExecuteEx确实发送了DDE音信给excel,况兼可执发送的音信的thread就是主线程

WM_NCMBUTTONDOWN =167

图片 5

WM_NCLBUTTONUP =162

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

当WM_SYSKEYDOWN音信被TRANSLATEMESSAGE函数翻译后发送此音信给全部核心的窗口

3.1 excel hang在哪里?

WM_CTLCOLORSCROLLBAR=311

 

 

图片 6

E N _ K I L L F O CU S编辑框正在失去输入宗旨

翻开一下buff的地址:

WM_MDIDESTROY = 545

图片 7

WM_PAINT = 15

2> 然后创设二个"WorkerW"的窗口用于DDE通讯

当光标在某些非激活的窗口中而客商正按着鼠标的某部键发送此新闻给当下窗口

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

WM_NCMBUTTONDBLCLK= 169

图片 8

WM_CHARTOITEM = 47

shell_execute.exe的主要code:

WM_TIMEENVISION = 275 //产生了沙漏事件

图片 9

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

NtUserMessageCall(HWND_BROADCAST, WM_DDE_INITIATE)

当某些控件的有些事件已经发出或以此控件必要拿到一些新闻时,发送此新闻给它的父窗口

表达excel给持有顶层窗口发送三个WM_DDE_INITIATE新闻,可是有窗口没有response

WM_MOUSEMOVE = 512

通过能够嫌疑是出于console进度在和excel用DDE音讯通讯时,console未有响应excel发送的DDE音讯,导致excel hang住

当客商已经登陆或退出后发送此信息给具备的窗口,当客户登录或抽离时系统更新客商的具体

4> ShellExecuteEx实行达成,但并不destroy "WorkerW"窗口

//释放贰个键

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

程序发送此音信给叁个编辑框或combobox来删除当前甄选的文书

图片 10

C B N _ S E L E N DC A N C E L客户的精选应该被撤回

翻开参数知excel调用NtUserMessageCall()相仿如下:

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

能够见到Excel hang在NtUserMessageCall()中,经过查询知,SendMessage()内部便是调用NtUserMessageCall()来发送消息的。

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

看似,大家能够成立八个带窗口的次序,运行后将其挂起,此时,就算直接双击展开test.iqy也会hang住。

是或不是以为三个新闻记录中的新闻像拉脱维亚语雷同?即使是那样,那么看后生可畏看上边包车型客车表达:

出殡此音信给那多少个窗口的大小和地方已经被改成时,来调用setwindowpos函数或别的窗口管理函数

WM_IME_KEYDOWN =656

WM_CLOSE = 16

图片 11
    非队列消息将会绕过系统队列和消息队列,直接将消息发送到窗口进度,。系统一发布送非队列新闻通告窗口,系统一发布送音信文告窗口。举例,当客商激活八个窗口系统一发布送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCU悍马H2SO凯雷德。这几个音讯通告窗口它被激活了。非队列新闻也得以由当应用程序调用系统函数发生。举个例子,当程序调用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参数设置成当下线程的注解来调用PostThreadM埃萨ge函数。
  从上边的那2个具备代表性的函数,我们得以观看音讯的发送方式和寄送方式的分别所在:被发送的信息是或不是会被任何时候处理,函数是不是立刻再次来到。被发送的新闻会被当下管理,管理完成后函数才会回去;被寄送的音讯不会被及时管理,他被平放三个先进先出的队列中,平素等到应用程序空线的时候才会被拍卖,可是函数放置新闻后及时回去。
图片 12
  实际上,发送音信到一个窗口处理进度和从来调用窗口管理进度之间并未太大的分别,他们向来的并世无两区别就在于你能够必要操作系统截获全体被发送的消息,不过不可以预知收获对窗口处理进程的一向调用。
  以寄送点子发送的新闻平日是与客户输入事件相对应的,因为这一个事件不是不行等不比,能够展开缓慢的缓冲管理,比方鼠标、键盘音讯会被寄送,而按键等新闻则会被发送。
  广播消息用得相当少,布罗兹castSystemMessage函数原型如下:
      long 布罗兹castSystemMessage(DWORubiconD dwFlags,LPDWOKugaD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam);该函数能够向钦定的收信人发送一条音讯,那些选择者能够是应用程序、可设置的驱动程序、互连网驱动程序、系统级其他设施驱动新闻和她们的妄动组合。须要潜心的是,假诺dwFlags参数是BSF_QUE大切诺基Y何况最少四个选择者重回了BROADCAST_QUERY_DENY,则重返值为0,若无一点点名BSF_QUE奥迪Q7Y,则函数将新闻发送给全数选用者,而且忽视其再次来到值。

当光标在三个窗口的非客商区内移动时发送此新闻给那么些窗口 //非客商区为:窗体的标题栏及窗

L B N _ S E T F O CU S列表框得到输入宗旨

WM_DROPFILES = 563

WM_KEYFIRST = 256

WM_MBUTTONDBLCLK =521

经过动用给定的连带呈现设备的句柄来设置列表框的公文和背景颜色

WM_ACTIVATE = 6

WM_SETTEXT = 12

WM_NCRBUTTONDBLCLK= 166

WM_CONTEXTMENU =123

B N _ PA I N T开关应当重画

当绘制文本时前后相继发送此新闻获得控件要用的颜料

WM_WINDOWPOSCHANGED= 71

WM_KEYLAST = 264

WM_IME_COMPOSITIONFULL= 644

WM_MENUCOMMAND =294

当菜单已被激活客商按下了有些键(不相同于加快键卡塔尔国,发送此音讯给菜单的持有者;

WM_CREATE = 1

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

三个DDE客商程序提交此音信给叁个DDE服务程序,客户采用此信息来号令服务器收到一个未经允许的数据项;服务器通过答复WM_DDE_ACK音讯提醒是或不是它选取那么些数据项;

WM_MDIGETACTIVE =553

来改换系统调色板

//双击鼠标中键

Windows新闻大全

消息映射的剧情
    通过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.在类的贯彻中投入相应的函数体;

//双击鼠标右键

当窗口背景必得被擦除时(例在窗口改变大小时卡塔 尔(阿拉伯语:قطر‎

 

WM_DESTROY = 2

图片 13   #define HANDLE_MSG(hwnd,msg,fn) 
图片 14             switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));

WM_STYLECHANGING =124

次第发送此音信给MDI顾客窗口用MDI菜单代替子窗口的美食做法

WM_CHANGEUISTATE =295

WM_KEYDOWN = 256

因而选择给定的相关显示设备的句柄来安装静态控件的文书和背景颜色

WM_SPOOLERSTATUS =42

C B N _ D B L C L K客商双击了几个字符串

当某些窗口的顾客区域必得被核算时发送此音讯

WM_GETFONT = 49

WM_MOUSELAST = 522

WM_CTLCOLORLISTBOX= 308

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

此音信由三个LBS_WANTKEYBOA瑞鹰DINPUT风格的列表框发送给她的主人来响应WM_CHAR消息

消息名称

说 明

CBN_CLOSEUP

组合框的列表框被关闭

CBN_DBLCLK

用户双击了一个字符串

CBN_DROPDOWN

组合框的列表框被拉下

CBN_EDITCHANGE

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

CBN_EDITUPDATE

组合框内的文本即将更新

CBN_ERRSPACE

组合框内存不足

CBN_KILLFOCUS

组合框失去输入焦点

CBN_SELCHANGE

在组合框中选择了一项

CBN_SELENDCANCEL

用户的选择将被忽略

CBN_SELENDOK

用户的选择将被执行

CBN_SETFOCUS

组合框获得输入焦点

TMsg = packedrecord

lParam 常常是贰个照准内部存款和储蓄器中多少的指针。由于WParm、lParam和Pointer都以34个人的,由此,它们中间能够相互转换。

//按下某键,并已产生WM_KEYDOWN, WM_KEYUP消息

B N _ D O U B L E CL I C K E D //客户双击了开关

pt: TPoint / /新闻创造时的鼠标地点

WM_CUT = 768

time: DWOHighlanderD / /新闻成立时的时光

WM_POWERBROADCAST =536

公用控件,自定义控件和她俩的父窗口通过此新闻来剖断控件是选择ANSI照旧UNICODE结构

//按下三个键

然后我们改过一下窗口进度:

当剪贴板的剧情改换时发送此音讯给剪贴板观看链的第叁个窗口;它同意用剪贴板观望窗口来

当客商双击鼠标右键同一时候光标有个别窗口在非客户区十发送此音讯

每当打印管理列队扩张或调减一条作业时爆发此消息

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暗许对象;在新的非暗中同意对象中或在只怕要传播命令的指令目的中。

通知新闻(Notification message)是指那样风流罗曼蒂克种音讯,三个窗口内的子控件产生了一些专业,必要通

WM_POWER = 72(适用于16位的windows)

发送此新闻给叁个会话框程序去改动主题地点

WM_DEADCHAR = 259

图片 15void MsgCracker(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)
图片 16{
图片 17      switch(id)
图片 18      {
图片 19     case ID_A:
图片 20                  if(codeNotify==EN_CHANGE)图片 21
图片 22                  break;
图片 23     case ID_B:
图片 24                  if(codeNotify==BN_CLICKED)图片 25
图片 26                  break;
图片 27             图片 28.
图片 29       }
图片 30}
图片 31

本文由ca88发布,转载请注明来源

关键词: ca88网址 c/c++ Windows Delphi-消息大全 WindowAPI