皇家娱乐赌场Windows新闻机制,hang的因由剖析

皇家娱乐赌场Windows新闻机制,hang的因由剖析

1. 问题

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

音信是指什么?
    
新闻系统对于三个win32顺序来说10分重要,它是1个程序运转的引力来源。七个新闻,是系统定义的八个三十六个人的值,他唯一的定义了三个事件,向
Windows发出三个公告,告诉应用程序某些事情时有发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的二个键都会使Windows发送3个音讯给应用程序。
   
消息作者是当做二个记录传递给应用程序的,那些记录中蕴藏了音信的门类以及任何音信。例如,对于单击鼠标所发出的音讯以来,这一个记录中隐含了单击鼠标时的坐标。那一个记录类型叫做MSG,MSG含有来自windows应用程序音讯队列的音讯音讯,它在Windows中宣称如下:

当在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途睿欧D(wParam)表示菜单项,工具栏按钮或控件的ID。如若是控件,
HIWO奥迪Q7D(wParam)表示控件音信类型
3> 控件布告(Notify Message) 
控件通告新闻, 那是最灵敏的消息格式, 其Message, wParam,
lParam分别为:WM_NOTIFY,
控件ID,指向NMHDTiggo的指针。NMHD科雷傲包罗控件通告的内容, 能够自由扩展。
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

皇家娱乐赌场 1typedef struct tagMsg
皇家娱乐赌场 2{
皇家娱乐赌场 3       HWND    hwnd;       //接受该音信的窗口句柄
皇家娱乐赌场 4       UINT    message;    //音信常量标识符,也正是大家平日所说的新闻号
皇家娱乐赌场 5       WPARAM  wParam;     //叁12个人消息的一定附加信息,确切含义重视于新闻值
皇家娱乐赌场 6       LPARAM  lParam;     //三十一个人新闻的一定附加消息,确切含义信赖于新闻值
皇家娱乐赌场 7       DWO凯雷德D   time;       //新闻创设时的小运
皇家娱乐赌场 8       POINT   pt;         //新闻创制时的鼠标/光标在显示器坐标系中的地方
皇家娱乐赌场 9}MSG;
皇家娱乐赌场 10

 

3 音讯队列(Message Queues) 
Windows中有两类别型的消息队列
1) 系统音信队列(System Message Queue) 那是3个类别唯一的Queue,设备驱动(mouse,
keyboard)会把操作输入转化成音信存在系统队列中,然后系统会把此新闻放到指标窗口所在的线程的音讯队列(thread-specific
message queue)中等候处理
2) 线程消息队列(Thread-specific Message Queue) 各类GUI线程都会尊敬这么三个线程音信队列。(那几个行列唯有在线程调用GDI函数时才会创建,暗中同意不创造)。然后线程音讯队列中的音讯会被送到对应的窗口进程(WndProc)处理.
瞩目:
线程音讯队列中WM_PAINT,WM_TIME帕杰罗唯有在Queue中一向不其余音信的时候才会被处理,WM_PAINT音信还会被合并以进步效用。别的具有信息以先进先出(FIFO)的法子被拍卖。

   
信息能够由系统或许应用程序发生。系统在发生输入事件时发出新闻。举个例子,
当用户敲键,
移动鼠标恐怕单击控件。系统也发生消息以响应由应用程序带来的浮动,
比如应用程序改变系统字体改变窗体大小。应用程序能够生出音讯使窗体执行职责,或然与其他应用程序中的窗口通信。

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 通常是2个与音讯有关的常量值,也也许是窗口或控件的句柄。
     lParam
日常是二个对准内部存储器中多少的指针。由于WParam、lParam和Pointer都以三十两人的,由此,它们中间能够互相转换。

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

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

消息标识符的值
    
系统一保险留消息标识符的值在0x0000在0x03ff(WM_USE奥德赛-1)范围。这个值被系统定义音讯使用。应用程序不可能运用那几个值给协调的新闻。应用程序新闻从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USETiggo到
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    应用程序自定义私有新闻

6 GetMessage, PeekMessage 
PeekMessage会即刻回去可以保存音信
GetMessage在有消息时重返会删除音信

音信有哪二种?
   其实,windows中的新闻尽管很多,但是项目并不散乱,大体上有3种:窗口音讯、命令新闻和控件布告新闻。
    
窗口消息大致是系统中最为广泛的音信,它是指由操作系统和控制其余窗口的窗口所利用的新闻。例如CreateWindow、DestroyWindow和MoveWindow等都会刺激窗口新闻,还有大家在上头谈到的单击鼠标所发生的音讯也是一种窗口新闻。
    
命令音信,那是一种新鲜的窗口消息,他用来处理从三个窗口发送到另二个窗口的用户请求,例如按下三个按钮,他就会向主窗口发送贰个指令音讯。
    
控件公告新闻,是指那样一种消息,八个窗口内的子控件发生了一些作业,须要文告父窗口。通告消息只适用于专业的窗口控件如按钮、列表框、组合框、编辑框,以及Windows公共控件如树状视图、列表视图等。例如,单击或双击1个控件、在控件中选拔一些文本、操作控件的滚动条都会时有爆发通告消息。她接近于命令消息,当用户与控件窗口交互时,那么控件公告新闻就会从控件窗口发送到它的主窗口。不过那种音讯的留存并不是为了处理用户命令,而是为了让主窗口能够改变控件,例如加载、显示数据。例如按下三个按钮,他向父窗口发送的新闻也能够当作是四个控件通知音信;单击鼠标所发出的音讯能够由主窗口一贯处理,然后交由控件窗口处理。
   
当中窗口语资源音信息及控件通告新闻至关心注重要由窗口类即直接或直接由CWND类派生类处理。相对窗口音信及控件通告新闻而言,命令新闻的处理目的范围就广得多,它不仅仅可以由窗口类处理,还足以由文书档案类,文书档案模板类及使用类所拍卖。
   
由于控件通告音信很首要的,人们用的也正如多,不过实际的意思往往令初大方晕头转向,所以本人说了算把普遍的多少个列出来供大家参考:
按扭控件
BN_CLICKED        用户单击了按钮
 BN_DISABLE 按钮被明确命令禁止
 BN_DOUBLECLICKED  用户双击了按钮
 BN_HILITE  用/户加亮了按钮
 BN_PAINT  按钮应当重画
 BN_UNHILITE 加亮应当去掉

1> 解压iqy_test.zip

7 TranslateMessage, TranslateAccelerator 
TranslateMessage: 把1个virtual-key新闻转化成字符信息(character
message),并放置当前线程的音讯队列中,音讯循环下1次取出处理。
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库罗德宝马X5SPACE 组合框内部存款和储蓄器不足
 CBN_KILLFOCUS 组合框失去输入核心
 CBN_SELCHANGE 在组合框中选取了一项
 CBN_SELENDCANCEL 用户的选项相应被撤废
 CBN_SELENDOK 用户的精选是法定的
 CBN_SETFOCUS 组合框得到输入宗旨

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_E奥迪Q5途乐SPACE 编辑框内部存款和储蓄器不足
 EN_HSCROLL 用户点击了水平滚动条
 EN_KILLFOCUS 编辑框正在失去输入主旨
 EN_MAXTEXT 插入的始末被截断
 EN_SETFOCUS 编辑框获得输入大旨
 EN_UPDATE 编辑框中的文本将要更新
 EN_VSCROLL 用户点击了垂直滚动条音信含义

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

9 BroadcastSystemMessage 
大家一般所接触到的音讯都以发送给窗口的,其实,
音信的接收者能够是丰裕多彩的,它能够是应用程序(applications),
可设置驱动(installable drivers),网络设施(network drivers),
系统级设备驱动(system-level device drivers)等, 
BroadcastSystemMessage这一个API能够对上述系统组件发送音讯。

列表框控件
 LBN_DBLCLK 用户双击了一项
 LBN_ELX570XC60SPACE 列表框内存不够
 LBN_KILLFOCUS 列表框正在失去输入宗旨
 LBN_SELCANCEL 选用被撤消
 LBN_SELCHANGE 选用了另一项
 LBN_SETFOCUS 列表框得到输入主题

shell_execute.exe的主要code:

队列新闻和非队列音信
   从音信的殡葬途径来看,音讯能够分为2种:队列新闻和非队列音讯。消息队列由得以分成类别音信队列和线程音信队列。系统新闻队列由Windows维护,线程音信队列则由各样GUI线程本人进行维护,为幸免给non-GUI现成创立音讯队列,所有线程发生时并不曾音讯队列,仅当线程第3回调用GDI函数时系统才给线程创制二个消息队列。队列音讯送到系统音讯队列,然后到线程新闻队列;非队列音讯一向送给指标窗口进度。
    
对于队列音讯,最普遍的是鼠标和键盘触发的新闻,例如WM_MOUSERMOVE,WM_CHA库罗德等消息,还有局地别样的新闻,例如:WM_PAINT、
WM_TIMER和WM_QUIT。当鼠标、键盘事件被触发后,相应的鼠标或键盘驱动程序就会把这个事件转换来相应的消息,然后输送到系统音信队列,由
Windows系统去实行拍卖。Windows系统则在适度的机遇,从系统消息队列中取出二个新闻,依据后面大家所说的MSG音讯结构明确音讯是要被送往万分窗口,然后把取出的新闻送往创立窗口的线程的相应队列,上面包车型地铁政工就该由线程音讯队列操心了,Windows起首忙本人的工作去了。线程看到本人的音讯队列中有消息,就从队列中取出来,通过操作系统一发布送到合适的窗口进度去处理。
    
一般来讲,系统连接将音讯Post在新闻队列的末段。那样保障窗口以先进先出的逐条接受音信。可是,WM_PAINT是3个见仁见智,同一个窗口的五个WM_PAINT被联合成多个 WM_PAINT 新闻,
合并全部的不算区域到2个不行区域。合并WM_PAIN的目标是为着减小刷新窗口的次数。
皇家娱乐赌场 11

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

皇家娱乐赌场 12
   
非队列新闻将会绕过系统队列和消息队列,间接将音讯发送到窗口进程,。系统一发布送非队列新闻布告窗口,系统一发布送消息文告窗口。例如,当用户激活叁个窗口系统一发布送WM_ACTIVATE,
WM_SETFOCUS, and
WM_SETCU安德拉SO哈弗。那几个音讯布告窗口它被激活了。非队列新闻也得以由当应用程序调用系统函数产生。例如,当程序调用SetWindowPos系统一发布送WM_WINDOWPOSCHANGED消息。一些函数也发送非队列音讯,例如下边大家要谈到的函数。
     
音信的出殡
    
了解了地点的那些基础理论之后,大家就足以开始展览一下总结的音信发送与接受。
     把三个新闻发送到窗口有3种办法:发送、寄送和播发。
    
发送消息的函数有SendMessage、SendMessageCallback、SendNotifyMessage、
SendMessageTimeout;寄送音讯的函数首要有PostMessage、PostThreadMessage、
PostQuitMessage;广播新闻的函数小编晓得的唯有布罗兹castSystemMessage、
布RhodescastSystemMessageEx。
     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个有着代表性的函数,我们得以看到新闻的出殡和埋葬格局和寄送格局的区分所在:被发送的消息是不是会被当下处理,函数是还是不是立即赶回。被发送的新闻会被及时处理,处理完成后函数才会回到;被寄送的音讯不会被马上处理,他被放置1个先进先出的队列中,一向等到应用程序空线的时候才会被拍卖,可是函数放置消息后马上回到。
皇家娱乐赌场 13
  实际上,发送新闻到叁个窗口处理进程和直接调用窗口处理进度之间并没有太大的差别,他们平素的唯一不一致就在于你能够须求操作系统截获全体被发送的音信,不过无法收获对窗口处理进度的直接调用。
  以寄送措施发送的新闻平时是与用户输入事件相呼应的,因为这么些事件不是那贰个热切,能够举行缓慢的缓冲处理,例如鼠标、键盘新闻会被寄送,而按钮等新闻则会被发送。
  广播音信用得相比较少,BroadcastSystemMessage函数原型如下:
      long 布罗兹castSystemMessage(DWOHighlanderD dwFlags,LPDWO陆风X8D
lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM
lParam);该函数能够向钦点的收信人发送一条新闻,那些接收者能够是应用程序、可设置的驱动程序、网络驱动程序、系统级其余设备驱动新闻和他们的私下己组建合。必要小心的是,假诺dwFlags参数是BSF_QUELacrosseY并且至少四个接收者再次回到了BROADCAST_QUERY_DENY,则重回值为0,假设没有点名BSF_QUERY,则函数将音信发送给全部接收者,并且忽略其再次回到值。

 

新闻的接收
 音讯的收受主要有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 wMsgFilterMax,UINT
wRemoveMsg);该函数用于查看应用程序的音讯队列,假若中间有音讯就将其放入lpMsg所指的构造中,但是,与GetMessage不一致的是,PeekMessage函数不会等到有消息放入队列时才回到。同样,借使hWnd为NULL,则PeekMessage获取属于调用该函数应用程序的任一窗口的新闻,假若hWnd=-1,那么函数只回去把hWnd参数为NULL的PostAppMessage函数送去的新闻。就算wMsgFilterMin和wMsgFilter马克斯都以0,则PeekMessage就回来全体可得到的音讯。函数获取之后将视尾数参数来决定是不是删除消息队列中的除
WM_PAINT消息之外的别的新闻,至于WM_PAINT则唯有在其处理今后才被剔除。
   WaitMessage原型如下:BOOL
WaitMessage();当三个应用程序无事可做时,该函数就将控制权交给此外的应用程序,同时将该应用程序挂起,直到叁个新的音信被放入应用程序的行列之中才重返。

3. 原因分析

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

3.1 excel hang在哪里?

皇家娱乐赌场 14while(GetMessage(&msg, NULL, 0, 0))
皇家娱乐赌场 15{
皇家娱乐赌场 16       if(!TranslateAccelerator(msg.hWnd, hAccelTable, &msg))
皇家娱乐赌场 17      { 
皇家娱乐赌场 18            TranslateMessage(&msg);
皇家娱乐赌场 19            DispatchMessage(&msg);
皇家娱乐赌场 20       }
皇家娱乐赌场 21}

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

 

皇家娱乐赌场 22

  
首先,GetMessage从进程的主线程的音讯队列中获得2个音信并将它复制到MSG结构,假如队列中从未消息,则GetMessage函数将拭目以俟一个音讯的到来现在才回来。若是你将一个窗口句柄作为第3个参数字传送入GetMessage,那么唯有内定窗口的的音讯能够从队列中拿走。GetMessage也得以从音信队列中过滤音讯只接受音讯队列中落在界定内的新闻。那时候就要动用GetMessage/PeekMessage钦赐七个音讯过滤器。那一个过滤器是二个新闻标识符的限量大概是四个窗体句柄,也许双方同时钦命。当应用程序要寻找2个后入新闻队列的新闻是很有用。WM_KEYFIRST
和 WM_KEYLAST 常量用于接受全部的键盘音讯。 WM_MOUSEFIRST 和
WM_MOUSELAST 常量用于接受全数的鼠标音讯。 
 然后TranslateAccelerator判断该新闻是或不是二个按键新闻还倘若两个加快键音讯,要是是,则该函数将把多少个按键信息转换到3个加快键新闻传递给窗口的回调函数。处理了加速键之后,函数TranslateMessage将把八个按键新闻WM_KEYDOWN和WM_KEYUP转换到二个WM_CHASportage,可是供给留意的是,音信WM_KEYDOWN,WM_KEYUP照旧将传递给窗口的回调函数。     
 处理完事后,DispatchMessage函数将把此音信发送给该音信钦命的窗口中已设定的回调函数。借使音信是WM_QUIT,则
GetMessage再次回到0,从而退出循环体。应用程序可以使用PostQuitMessage来甘休自身的音信循环。经常在主窗口的
WM_DESTROY消息中调用。
 上面大家举二个普遍的小例子来验证这些新闻泵的选择:

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

皇家娱乐赌场 23if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE))
皇家娱乐赌场 24{
皇家娱乐赌场 25          if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)...
皇家娱乐赌场 26}
皇家娱乐赌场 27

翻开参数知excel调用NtUserMessageCall()类似如下:

  那里大家承受全体的键盘音讯,所以就用WM_KEYFIRST 和
WM_KEYLAST作为参数。最后贰个参数能够是PM_NOREMOVE 或者
PM_REMOVE,表示音讯新闻是还是不是相应从音信队列中剔除。                 
   所以那段小代码正是判定是还是不是按下了Esc键,假如是就展开始拍戏卖。

NtUserMessageCall(HWND_BROADCAST, WM_DDE_INITIATE)

窗口进程
 窗口进程是2个用以拍卖全部发送到这么些窗口的消息的函数。任何3个窗口类都有三个窗口进程。同1个类的窗口使用同一的窗口进程来响应音讯。系统一发布送音讯给窗口进度将新闻数据作为参数字传送递给他,音讯赶到之后,依据音讯类型排序进行拍卖,在那之中的参数则用来区分不相同的新闻,窗口进程使用参数产生合适行为。
 贰个窗口进度不常常忽略新闻,假诺她不处理,它会将新闻传回到执行私下认可的处理。窗口进度通过调用DefWindowProc来做这些处理。窗口进程必须
return叁个值作为它的新闻处理结果。大多数窗口只处理小片段音信和将其余的经过DefWindowProc传递给系统做暗中同意的拍卖。窗口进度被所有属于同2个类的窗口共享,能为不一样的窗口处理新闻。下边大家来看一下切实的实例:

表达excel给拥有顶层窗口发送2个WM_DDE_INITIATE新闻,不过有窗口没有response

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

由此能够困惑是出于console进度在和excel用DDE音信通讯时,console没有响应excel发送的DDE信息,导致excel
hang住

 

 

消息分流器
  平常的窗口进程是通过一个switch语句来完成的,那个工作很烦,有没有更简便的办法呢?有,这就是音信分流器,利用新闻分流器,大家得以把switch语句分成更小的函数,各个新闻都对应3个小函数,这样做的补益就是对音讯更易于管理。
  之所以被称作新闻分流器,便是因为它能够对别的新闻举行分流。上边我们做1个函数就很驾驭了:

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

皇家娱乐赌场 74void MsgCracker(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)
皇家娱乐赌场 75{
皇家娱乐赌场 76      switch(id)
皇家娱乐赌场 77      {
皇家娱乐赌场 78     case ID_A:
皇家娱乐赌场 79                  if(codeNotify==EN_CHANGE)皇家娱乐赌场 80
皇家娱乐赌场 81                  break;
皇家娱乐赌场 82     case ID_B:
皇家娱乐赌场 83                  if(codeNotify==BN_CLICKED)皇家娱乐赌场 84
皇家娱乐赌场 85                  break;
皇家娱乐赌场 86             皇家娱乐赌场 87.
皇家娱乐赌场 88       }
皇家娱乐赌场 89}
皇家娱乐赌场 90

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

下一场我们修改一下窗口进程:

皇家娱乐赌场 91LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
皇家娱乐赌场 92{
皇家娱乐赌场 93       switch(message)
皇家娱乐赌场 94      {
皇家娱乐赌场 95             HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);
皇家娱乐赌场 96             HANDLE_MSG(hWnd,WM_DESTROY,MsgCracker);
皇家娱乐赌场 97           default:
皇家娱乐赌场 98                    return DefWindowProc(hWnd, message, wParam, lParam);
皇家娱乐赌场 99   }
皇家娱乐赌场 100  return 0;
皇家娱乐赌场 101}

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

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

皇家娱乐赌场 102

皇家娱乐赌场 103   #define HANDLE_MSG(hwnd,msg,fn) \
皇家娱乐赌场 104             switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));

call stack显示的确是ShellExecuteEx所调用

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

皇家娱乐赌场 105

皇家娱乐赌场 106   #define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn)\ 
皇家娱乐赌场 107             ((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0L);

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

好了,事情到了这一步,应该全套都晴朗了。
可是,大家发以后windowsx.h里面还有三个宏:FOGL450WA揽胜极光D_WM_XXXX,大家依然那WM_COMMAND为例,举办辨析:

小心到下3个API GetWindowThreadProcessId ( 0x00310172 , 0x0012fb70
),刚好是赢得那个窗口的pid和tid,查看下参数窗口:

皇家娱乐赌场 108   #define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \
皇家娱乐赌场 109     (void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl))

其一窗口所属的经过PID =
0xc54,正好是excel的历程,表达ShellExecuteEx确实发送了DDE新闻给excel,而且可执发送的音信的thread就是主线程

因而实际上,FO路虎极光WATucsonD_WM_XXXX将音讯参数实行了重新布局,生成了wParam &&
lParam,然后调用了大家定义的函数。

皇家娱乐赌场 110

前方,大家解析了新闻的中坚理论和宗旨的函数及用法,接下去,大家将越加探讨新闻传递在MFC中的达成。

基于DDE的音讯参数,可知wParam便是发送新闻的窗口,其句柄为2425190 =
0x250166,反向查询知那是ShellExecuteEx成立的”WorkerW”窗口

MFC新闻的处理落成格局
  初看MFC中的各类新闻,以及在头脑中稳步的C++的震慑,大家只怕很当然的就会想到利用C++的三大特点之一:虚拟机制来贯彻音讯的传递,不过透过分析,大家看出事情并不是想我们想像的那么,在MFC中国国投息是透过一种所谓的新闻映射机制来处理的。
  为何吗?在潘爱中华民族解放先锋生翻译的《Visual
C++技术内幕》(第4版)中提交了详实的由来表达,小编再一言以蔽之3次。在CWnd类中山高校约有110个音信,还有其它的MFC的类呢,算起来音信太多了,在C++中对程序中用到的每三个派生类都要有三个vtable,每一个虚函数在vtable中都要侵夺三个4字节大小的入口地址,那样一来,对于每一个特定项指标窗口或控件,应用程序都亟待二个440KB大小的表来援救虚拟新闻控件函数。
  假诺说上边包车型地铁窗口或控件能够勉强完结的话,那么对于菜单命令新闻及按钮命令新闻吧?因为不相同的应用程序有例外的菜单和按钮,我们怎么处理呢?在MFC
库的那种新闻映射系统就防止了选取大的vtable,并且能够在处理常规Windows音信的还要处理千头万绪的应用程序的吩咐新闻。
  说白了,MFC中的新闻机制其实质是一张高大的消息及其处理函数的依次对应表,然后加上分析处理那张表的利用框架之中的有的先后代码.那样就足以幸免在SDK编制程序中用到的麻烦的CASE语句。

皇家娱乐赌场 111

MFC的音讯映射的基类CCmdTarget
  若是你想让您的控件能够举办消息映射,就非得从CCmdTarget类中派生。CCmdTarget类是MFC处理命令新闻的基本功、主旨。MFC为此类设计了重重成员函数和一些分子数量,基本上是为了缓解音讯映射难点的,全体响应新闻或事件的类都从它派生,例如:应用程序类、框架类、文书档案类、视图类和丰硕多彩的控件类等等,还有众多。
可是那个类里面有3个函数对消息映射非常重要,3个是静态成员函数DispatchCmdMsg,另一个是虚函数OnCmdMsg。
DispatchCmdMsg专门供MFC内部使用,用来散发Windows音信。OnCmdMsg用来传递和发送新闻、更新用户界面对象的情景。
CCmdTarget对OnCmdMsg的暗中同意完成:在当下命令指标(this所指)的类和基类的音信映射数组里找找钦点命令新闻的音信处理函数。
  那里运用虚拟函数GetMessageMap获得命令指标类的音讯映射入口数组_messageEntries,然后在数组里匹配命令音讯ID相同、控制公告代码也同样的新闻映射条目。个中GetMessageMap是虚拟函数,所以可以确认当前下令目的的确切类。
一旦找到了2个卓殊的新闻映射条目,则动用DispachCmdMsg调用那几个处理函数;
只要没有找到,则应用_GetBaseMessageMap获得基类的音信映射数组,查找,直到找到或探寻了具有的基类(到CCmdTarget)截至;
假如最终没有找到,则赶回FASLE。
  每一种从CCmdTarget派生的吩咐指标类都足以覆盖OnCmdMsg,利用它来分明是或不是能够拍卖某条命令,假如无法,就因而调用下一下令指标的
OnCmdMsg,把该命令送给下七个命令指标处理。平日,派生类覆盖OnCmdMsg时,要调用基类的被掩盖的OnCmdMsg。
  在MFC框架中,一些MFC命令指标类掩盖了OnCmdMsg,如框架窗口类掩盖了该函数,落成了MFC的规范命令音讯发送路径。供给的话,应用程序也得以覆盖OnCmdMsg,改变三个或多个类中的发送规定,达成与正规框架发送规定差异的出殡路径。例如,在偏下意况可以作那样的拍卖:在要打断发送顺序的类中把命令传给多个非MFC私下认可对象;在新的非暗许对象中或在或者要传播命令的吩咐指标中。

皇家娱乐赌场 112

新闻映射的始末
   
通过ClassWizard为我们转变的代码,我们能够见见,音讯映射基本上分为2大多数:
   
在头文件(.h)中有叁个宏DECLARE_MESSAGE_MAP(),他被放在了类的最后,是七个public属性的;与之对应的是在贯彻部分(.cpp)扩张了一章音信映射表,内容如下:
    BEGIN_MESSAGE_MAP(当前类, 当前类的基类)
       //{{AFX_MSG_MAP(CMainFrame)
         音讯的入口项
       //}}AFX_MSG_MAP
   END_MESSAGE_MAP()
  
可是仅是那两项还远不足以完毕一条信息,假设一个音信工作,必须有以下三个部分去同盟:
1.在类的定义中投入相应的函数评释;
2.在类的音信映射表中进入相应的新闻映射入口项;
3.在类的达成中参与相应的函数体;

 

新闻的丰硕
  
有了地点的这一个只是作为基础,大家接下去就做我们最精通、最常用的行事:添加新闻。MFC消息的丰裕主要有2种艺术:自动/手动,大家就以那2种格局为例,说一下如何添加音讯。
   壹 、利用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上下断点跟踪一下

   二 、手动地抬高音讯处理函数
   
倘使在Messages列表框中照旧看不到我们想要的新闻,那么该音信恐怕是被系统忽略掉或然是您自个儿创设的,在那种气象下,就必须本人手工业添加。依据我们前边所说的新闻工作的三个部件,大家挨个进行拍卖:
      1) 在类的.
h文件中增加处理函数的注脚,紧接在//}}AFX_MSG行之后加盟阐明,注意:一定要以afx_msg开头。
     常常,添加处理函数证明的最佳的地点是源代码中Class
Wizard维护的表下边,可是在它标志其领域的{{}}括弧外面。这么些括弧中的任李强西都将会被Class
Wizard销毁。
      2)
接着,在用户类的.cpp文件中找到//}}AFX_MSG_MAP行,紧接在它今后进入音信入口项。同样,也是身处{
{} }的外面
      3) 最终,在该文件中添加新闻处理函数的实业。

皇家娱乐赌场 113

 

查阅一下buff的地方:

 

皇家娱乐赌场 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先将输入的音讯放入系统音讯队列中,然后再将输入的音讯拷贝到相应的应用程序队列中,应用程序中的音信循环从它的音信队列中找找每三个信息并发送给相应的窗口函数中。1个事变的发出,到达处理它的窗口函数必须经历上述进度。值得注意的是音讯的非超过性,即无论是事件的急与缓,总是按到达的程序排队(一些体系音信除却),这就使得部卓殊表实时事件或然得不到当时的拍卖。

 

  由于Windows本身是由消息使得的,举贰个例子来注脚那个难点。打开记事本程序,该程序有一个File菜单,那么,在运维该应用程序的时候,借使用户单击了File菜单里New命令时,那么些动作将被Windows
(而不是应用程序自个儿!)所擒获,Windows经过分析得知这些动作应该由地点所说的不行应用程序去处理,既然是如此,Windows就发送了个名叫WM_COMMAND的新闻给应用程序,该新闻所富含新闻告诉应用程序:”用户单击了New菜单”,应用程序得知这一消息随后,接纳对应的动作来响应它,这几个进度称为新闻处理。Windows为每二个应用程序(确切地说是每3个线程)维护了相应的音信队列,应用程序的职务就是不停的从它的消息队列中获撤除息,分析新闻和拍卖新闻,直到一条吸收名为WM_QUIT新闻截止,那一个进程一般是由一种名叫音讯循环的程序结构来实现的。

5. 为何win7上不会有如此的标题

  音信小编是用作二个记下传递给应用程序的,这么些记录中含有了新闻的花色以及任何音讯。例如,对于单击鼠标所发出的音讯的话,这几个记录中隐含了单击鼠标时的坐标。这一个记录类型叫做T
M s g,它在Wi n d o w s单元中是如此申明的:

5.1 在API Monitor中看下PostMessageW

type

皇家娱乐赌场 115

TMsg = packedrecord

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

hwnd: HWND / /窗口句柄

皇家娱乐赌场 116

message: UINT / /音讯常量标识符

可见是ShellExecuteEx内部创造的线程,所以win7上ShellExecuteEx创立了1个线程专门用来处理和excel的DDE音信通讯,那样就能符合规律的吸收接纳处理excel发过来的WM_DDE_INITIATE消息了

wParam: WPA 库罗德 AM  // 三十多少人音讯的一定附加音讯

lParam: LPA LAND AM  // 3二位音信的特定附加音讯

time: DWOLANDD / /音讯创制时的年月

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

end

 

音讯中有啥样?

是还是不是觉得1个新闻记录中的音讯像塞尔维亚语一样?若是是那样,那么看一看下边包车型大巴表明:

hwnd
三十五人的窗口句柄。窗口能够是其他项指标显示屏对象,因为Win32力所能及保险当先25%可视对象的句柄(窗口、对话框、按钮、编辑框等)。

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

wParam 平日是三个与新闻有关的常量值,也说不定是窗口或控件的句柄。

lParam
平时是一个针对性内部存款和储蓄器中数量的指针。由于WParm、lParam和Pointer都是三十一位的,因而,它们之间能够相互转换。

 

WM_NULL = 0

WM_CREATE = 1

应用程序创立叁个窗口

WM_DESTROY = 2

三个窗口被灭绝

WM_MOVE = 3

运动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

当三个窗口或应用程序要关张时发送3个信号

WM_QUERYENDSESSION= 17

当用户选取截至对话框或程序自身调用ExitWindows函数

WM_QUIT = 18

用来收尾程序运转或当程序调用postquitmessage函数

WM_QUERYOPEN = 19

当用户窗口恢复原先的大小地点时,把此音讯发送给某些图标

WM_ERASEBKGND = 20

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

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

出殡此音信来撤消某种正在进展的摸态(操作)

WM_SETCURSOR = 32

假定鼠标引起光标在某些窗口中移动且鼠标输入没有被捕获时,就发消息给某些窗口

WM_MOUSEACTIVATE =33

当光标在有个别非激活的窗口中而用户正按着鼠标的有个别键发送此新闻给当下窗口

WM_CHILDACTIVATE =34

出殡此新闻给MDI子窗口当用户点击此窗口的标题栏,或当窗口被激活,移动,改变大小

WM_QUEUESYNC = 35

此新闻由基于总计机的练习程序发送,通过WH_JOURNALPALYBACK的hook程序

分手出用户输入消息

WM_GETMINMAXINFO =36

此新闻发送给窗口当它将要改变大小或岗位;

WM_PAINTICON = 38

发送给最小化窗口当它图标将要被重画

WM_ICONERASEBKGND =39

此音讯发送给有个别最小化窗口,仅当它在画图标前它的背景必须被重画

WM_NEXTDLGCTL = 40

发送此音信给2个对话框程序去改变宗旨地方

WM_SPOOLERSTATUS =42

每当打字与印刷管理列队增添或收缩一条作业时发生此消息

WM_DRAWITEM = 43

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

此新闻给那一个空件的主人

WM_MEASUREITEM = 44

当button, combo box, list box, list view control, or menu item 被创制时

出殡此音信给控件的全部者

WM_DELETEITEM = 45

当the list box 或 combo box 被灭绝 或 当
有个别项被剔除通过LB_DELETESTRING,LB_RESETCONTENT, CB_DELETESTRING, or
CB_RESETCONTENT 消息

WM_VKEYTOITEM = 46

此音信有3个LBS_WANTKEYBOA揽胜DINPUT风格的发出给它的持有者来响应WM_KEYDOWN消息

WM_CHARTOITEM = 47

此音信由三个LBS_WANTKEYBOA牧马人DINPUT风格的列表框发送给他的全数者来响应WM_CHAR消息

WM_SETFONT = 48

当绘制文本时先后发送此音信获得控件要用的颜色

WM_GETFONT = 49

应用程序发送此音信获得当前控件绘制文本的书体

WM_SETHOTKEY = 50

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

WM_GETHOTKEY = 51

应用程序发送此消息来判定热键与某些窗口是不是有关联

WM_QUERYDRAGICON =55

此音讯发送给最小化窗口,当此窗口将要被拖放而它的类中并未概念图标,应用程序能

回去二个图标或光标的句柄,当用户拖放图标时系统来得这些图标或光标

WM_COMPAREITEM = 57

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

WM_GETOBJECT = 61

WM_COMPACTING = 65

发表评论

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

网站地图xml地图