Window消息使用详解
Windows消息机制详解
Windows消息机制详解Windows操作系统最大的特点就是其图形化的操作界面,其图形化界面是建立在其消息处理机制这个基础之上的。
如果不理解Windows消息处理机制,肯定无法深入的理解Windows编程。
可惜很多程序员对W indows消息只是略有所闻,对其使用知之甚少,更不了解其内部实现原理,本文试着一步一步向大家披露我理解的Windows消息机制。
可以说,掌握了这一部分知识,就是掌握了Windows编程中的神兵利器,灵活运用它,将会极大的提高我们的编程能力。
一、消息概述Windows窗体是怎样展现在屏幕上的呢?众所周知,是通过API绘制实现的。
Windows操作系统提供了一系列的API函数来实现界面的绘制功能,例如:DrawText绘制文字DrawEdge绘制边框DrawIcon绘制图标BitBlt 绘制位图Rectangle绘制矩形…再复杂的程序界面都是通过这个函数来实现的。
那什么时候调用这些函数呢?显然我们需要一个控制中心,用来进行“发号施令”,我们还需要一个命令传达机制,将命令即时的传达到目的地。
这个控制中心,就是一个动力源,就像一颗心脏,源源不断地将血液送往各处。
这个命令传达机制就是Windows消息机制,Windows消息就好比是身体中的血液,它是命令传达的使者。
Windows消息控制中心一般是三层结构,其顶端就是Windows内核。
Windows内核维护着一个消息队列,第二级控制中心从这个消息队列中获取属于自己管辖的消息,后做出处理,有些消息直接处理掉,有些还要发送给下一级窗体(Window)或控件(Control)。
第二级控制中心一般是各Windows应用程序的Applicat ion对象。
第三级控制中心就是Windows窗体对象,每一个窗体都有一个默认的窗体过程,这个过程负责处理各种接收到的消息。
消息是以固定的结构传送给应用程序的,结构如下:Public Type MSGhwnd As Longmessage As LongwParam As LonglParam As Longtime As Longpt As POINTAPIEnd Type其中hwnd是窗体的句柄,message是一个消息常量,用来表示消息的类型,wParam和lParam都是32位的附加信息,具体表示什么内容,要视消息的类型而定,time是消息发送的时间,pt是消息发送时鼠标所在的位置。
windows消息机制的工作原理
windows消息机制的工作原理Windows消息机制是一种用于不同进程间进行通信的机制,Windows操作系统以消息队列为基础,将消息作为一种最基本的通信单元进行传输。
在这个机制下,进程之间可以通过发送和接收消息来进行通信。
Windows消息机制的工作原理如下:1. 消息队列的创建:每个进程都有自己的消息队列,用于存储接收到的消息。
当进程初始化时,系统会为该进程创建一个消息队列,并为之分配一个唯一的标识符。
2. 消息的发送:当一个进程需要向其他进程发送消息时,它首先需要明确消息的发送目标。
在Windows中,每个进程都有一个唯一的标识符(句柄),可以用来标识其他进程。
发送消息的进程根据目标进程的标识符,将消息发送到目标进程的消息队列。
3. 消息的接收:当一个进程接收到消息时,它需要从自己的消息队列中读取消息。
Windows提供了一种机制,使得进程可以通过消息循环来接收和处理消息。
消息循环是一个无限循环,负责从消息队列中读取消息,并将消息分发给相应的处理函数。
4. 消息的处理:一旦消息被分发给相应的处理函数,进程就可以根据消息的类型和附加数据来进行相应的处理。
处理函数可以修改进程中的状态,调用相应的函数,或者发送其他消息。
5. 消息的传递:在发送和接收消息的过程中,消息并不是实时传输的。
当一个进程发送消息时,消息并不会立即发送给目标进程,而是先存储在发送进程的消息队列中。
接收进程通过消息循环来读取消息,也是间断性的进行读取。
因此,消息的传递是一种异步的过程。
6. 消息的优先级:Windows中的消息有不同的优先级,系统会根据消息的优先级来确定消息的处理顺序。
一般情况下,系统会优先处理高优先级的消息,然后才会处理低优先级的消息。
7. 消息的同步和异步:在发送消息的过程中,Windows提供了两种方式:同步方式和异步方式。
同步方式下,发送消息的进程会等待接收进程对消息的处理完成,然后才会继续执行。
异步方式下,发送消息的进程不需要等待接收进程的处理结果,可以立即继续执行。
消息使用大全
当用户已经登入或退出后发送此消息给所有的窗口,当用户登入或退出时系统更新用户的具体
设置信息,在用户更新设置时系统马上发送此消息;
WM_NOTIFYFORMAT = $0055
公用控件,自定义控件和他们的父窗口通过此消息来判断控件是使用ANSI还是UNICODE结构
message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。
wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。
lParam 通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m和P o i n t e r都是3 2位的,
的边框体
WM_NCLBUTTONDOWN = $00A1
当光标在一个窗口的非客户区同时按下鼠标左键时提交此消息
WM_NCLBUTTONUP = $00A2
当用户释放鼠标左键同时光标某个窗口在非客户区十发送此消息;
WM_NCLBUTTONDBLCLK = $00A3
当用户双击鼠标左键同时光标某个窗口在非客户区十发送此消息
在WM_NOTIFY消息,使用此控件能使某个控件与它的父控件之间进行相互通信
WM_CONTEXTMENU = $007B
当用户某个窗口中点击了一下右键就发送此消息给这个窗口
WM_STYLECHANGING = $007C
当调用SETWINDOWLONG函数将要改变一个或多个 窗口的风格时发送此消息给那个窗口
WM_VKEYTOITEM = $002E
此消息有一个LBS_WANTKEYBOARDINPUT风格的发出给它的所有者来响应WM_KEYDOWN消息
windows消息原理
windows消息原理Windows消息原理是Windows操作系统中一种实现进程间通信的机制。
当一个应用程序需要发送消息给另一个应用程序时,它会创建一个消息,并将该消息发送给目标应用程序的消息队列。
消息由消息标识、消息参数和消息回调函数组成。
消息标识用于识别消息的类型,每个消息标识都有一个唯一的整数值。
消息参数则用于传递附加的信息,例如鼠标位置、键盘按键等。
回调函数是接收消息并对其进行处理的函数。
当一个程序需要发送消息时,它会使用函数PostMessage或SendMessage来将消息发送给目标程序。
PostMessage函数将消息放入目标应用程序的消息队列中,并立即返回。
而SendMessage函数则会等待目标应用程序处理完消息后才返回。
接收消息的应用程序会不断从自己的消息队列中取出消息,并将其传递给消息回调函数进行处理。
回调函数根据消息类型进行相应的操作,例如更新界面、处理用户输入等。
处理完消息后,应用程序会继续处理下一个消息,直到消息队列为空。
消息机制的优点是它允许不同的应用程序之间进行松耦合的通信。
发送消息的应用程序不需要知道目标应用程序的具体实现细节,只需要知道消息标识和消息参数即可。
同时,由于消息的处理是异步的,应用程序可以同时处理多个消息,提高了系统的响应速度。
然而,消息机制也存在一些缺点。
首先,由于消息的传递是通过消息队列,因此消息的接收可能会有延迟。
另外,由于消息的处理是在接收消息的线程中进行的,如果处理消息的时间过长,会导致界面无响应或其他应用程序的操作延迟。
因此,需要合理设计消息的处理逻辑,避免长时间的阻塞操作。
总的来说,Windows消息原理是一种可靠且灵活的进程间通信机制,它为应用程序之间的数据交换提供了一种简单而高效的方式。
1.2WindowMessages(窗口消息)
1.2WindowMessages(窗⼝消息)窗⼝消息GUI应⽤程序必须响应来⾃⽤户和操作系统的事件。
来⾃⽤户的事件包括⽤户与程序交互的所有⽅式:⿏标点击、按键、触摸屏⼿势等等。
来⾃操作系统的事件包括程序之外的任何可能影响程序⾏为的东西。
例如,⽤户可能插⼊⼀个新的硬件设备,或者Windows可能进⼊低功耗状态(睡眠或休眠)。
这些事件可以在程序运⾏时的任何时间发⽣,⼏乎可以按任何顺序发⽣。
如何构造⼀个不能预先预测执⾏流(flow)的程序?为了解决这个问题,Windows使⽤了消息传递模型。
操作系统通过传递消息与应⽤程序窗⼝进⾏通信。
消息只是指定特定事件的数字代码。
例如,如果⽤户按下⿏标左键,窗⼝将接收到具有以下消息代码的消息。
C++#define WM_LBUTTONDOWN 0x0201⼀些消息具有与它们相关联的数据。
例如,消息包含⿏标光标的x坐标和y坐标。
要将消息传递给窗⼝,操作系统将调⽤为该窗⼝注册的窗⼝过程。
(现在你知道窗⼝程序的作⽤了。
)消息环(The message loop)应⽤程序在运⾏时将收到数千条消息。
(考虑到每次击键和点击⿏标按钮都会产⽣⼀条消息。
)另外,应⽤程序可以有多个窗⼝,每个窗⼝都有⾃⼰的窗⼝过程。
程序如何接收所有这些消息并将它们发送到正确的窗⼝过程?应⽤程序需要⼀个循环来检索消息并将其发送到正确的窗⼝。
对于创建窗⼝的每个线程,操作系统都为窗⼝消息创建⼀个队列(queue)。
此队列保存了在该线程上创建的所有窗⼝的消息。
队列本⾝在程序是隐藏不可见的。
您不能直接操作队列。
但是,您可以通过调⽤函数从队列中提取消息。
C++MSG msg;GetMessage(&msg, NULL, 0, 0);此函数会从队列的头部移除第⼀个消息。
如果队列为空,函数将阻塞,直到另⼀条消息⼊队列。
事实上,阻塞不会使您的程序没有响应。
如果没有消息,程序就没有什么可做的。
如果您必须执⾏后台处理,您可以创建额外的线程,在GetMessage等待另⼀个消息时继续运⾏。
Windows消息机制详解
Windows消息机制详解Windows系统是一个消息驱动的OS,什么是消息呢?我很难说得清楚,也很难下一个定义(谁在嘘我),我下面从不同的几个方面讲解一下,希望大家看了后有一点了解。
1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。
当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。
例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。
当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。
2、谁将收到消息:一个消息必须由一个窗口接收。
在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。
例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。
3、未处理的消息到那里去了:M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。
正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。
例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。
4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。
而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。
例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。
5、示例:下面有一段伪代码演示如何在窗口过程中处理消息LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,LPARAM){switch(uMessageType){//使用SWITCH语句将各种消息分开case(WM_PAINT):doYourWindow(...);//在窗口需要重新绘制时进行输出break;case(WM_LBUTTONDOWN):doYourWork(...);//在鼠标左键被按下时进行处理break;default:callDefaultWndProc(...);//对于其它情况就让系统自己处理break;}}接下来谈谈什么是消息机制:系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。
Windows 10通知中心设置
Windows 10通知中心设置Windows 10是微软公司最新的操作系统,拥有许多强大的功能。
其中一个重要的功能是通知中心,它可以帮助用户管理和查看来自各种应用程序的通知消息。
在本文中,我们将详细讨论Windows 10通知中心的设置,并介绍如何根据个人需求进行自定义配置。
Windows 10的通知中心位于任务栏的右下方,通过点击任务栏上的“通知”图标即可打开。
在通知中心中,您将看到来自各种应用程序的通知消息和提醒,例如邮件、日历、消息、应用更新等。
通过通知中心,您可以轻松地查看所有未读消息,并快速采取相应的操作。
要自定义Windows 10的通知中心设置,您可以按照以下步骤操作:第一步,打开系统设置。
您可以通过点击“开始”按钮,然后点击设置图标来打开系统设置。
另外,您还可以使用快捷键Win + I来打开系统设置。
第二步,点击“系统”。
在系统设置窗口中,您将看到多个选项,点击“系统”选项以进入下一步设置。
第三步,选择“通知和操作”。
在系统设置中,您将看到一个左侧导航栏,点击“通知和操作”选项以打开通知设置。
第四步,自定义通知中心。
在通知和操作设置中,您可以控制Windows 10的通知中心的外观和功能。
以下是一些主要选项:- 您可以打开或关闭通知中心。
如果您不想在任务栏中看到通知图标,可以通过切换“在任务栏上显示或隐藏通知图标”选项来实现。
- 您可以选择在通知中心中显示的通知数量。
通过调整“在通知中心中显示的最新通知数”选项,您可以控制通知中心中显示的通知消息的数量。
- 您可以选择是否在锁定屏幕上显示通知。
通过切换“在锁定屏幕上显示应用通知”选项,您可以控制是否在锁定屏幕上显示来自应用程序的通知消息。
- 您还可以根据个人需求自定义每个应用程序的通知设置。
通过单击通知设置下方的“更多通知设置”链接,您可以进入每个应用程序的通知设置页面。
在这个页面上,您可以选择是否显示该应用程序的通知,以及选择显示或隐藏通知的详细信息等。
易语言WIN消息使用
【易语言】WIN消息大全1、窗口最大化===发送信息(274,61488,0)‘如果还是启动窗口要加上窗口名称,如:窗口1.发送信息()2、改变输入法===发送信息(8,0,0)例如:编辑框.发送信息(258,#A健,5)在编辑框输入5个A3、移动控件控件.发送信息(274,61458,0)控件.发送信息(161,2,0)4、调整控件调整左边:控件.发送信息(274,61441,0)调整右边:控件.发送信息(274,61442,0)调整顶边:控件.发送信息(274,61443,0)左上角调整:控件.发送信息(274,61444,0)右上角调整:控件.发送信息(274,61445,0)调整底部控件.发送信息(274,61446,0)左下角调整:控件.发送信息(274,61447,0)右下角调整:控件.发送信息(274,61448,0)4、控件最大化控件.发送信息(274,61488,0)5、控件最小化控件.发送信息(274,61473,0)6、关闭控件控件.发送信息(16,0,0)7、单击鼠标左键控件.发送信息(513,0,0)8、鼠标带问号(再次单击问号消失)发送信息(274,61836,0)9、清除窗口标题控件.发送信息(12,0,0)10、复制编辑框.发送信息(769,0,0)11、粘贴编辑框.发送信息(770,0,0)12、全选编辑框.发送信息(177,0,-1)13、清空内容编辑框.发送信息(12,1,0)14、按钮单击发送消息(发送按钮句柄,245,0,0)15、删除控件.发送信息(768,0,0)16、撤销控件.发送信息(772,0,0)17、剪切控件.发送信息(771,0,0)18、退出控件.发送信息(1,0,0)19、获得焦点控件.发送信息(7,0,0)20、失去焦点控件.发送信息(8,0,0)21、结束控件.发送信息(25,0,0)22、单击鼠标右键控件.发送信息(123,0,0)23、取消全选控件.发送信息(177,0,0)24、1组合框弹出列表组合框.发送信息(155,1,0)25、发送文本(Dll命令。
Windows系统如何设置系统通知和提醒
Windows系统如何设置系统通知和提醒现代操作系统如Windows为了提供更好的用户体验,通常都会提供系统通知和提醒功能。
通过设置系统通知,用户可以及时了解到重要的系统更新、应用程序通知以及其他系统事件的提醒信息。
本文将介绍如何在Windows系统中设置系统通知和提醒,以便您获得更好的使用体验。
一、打开通知和动作中心首先,我们需要打开通知和动作中心来进行系统通知和提醒的设置。
通知和动作中心是Windows系统的一个重要功能,可以帮助我们管理所有的通知和提醒信息。
您可以通过以下两种方式打开通知和动作中心:1. 点击系统托盘中的通知图标,然后点击右下方的“所有设置”按钮,再选择“系统”>“通知和动作中心”。
2. 使用快捷键“Win键+ I”打开系统设置,然后选择“系统”>“通知和动作中心”。
二、调整通知首选项在通知和动作中心中,您可以根据个人需求,针对不同的应用程序进行通知首选项的调整。
以下是具体步骤:1. 打开通知和动作中心后,您会看到一个列表,列出了已安装的应用程序。
在这个列表中,您可以找到您想要调整通知设置的应用程序。
2. 点击您想要调整通知设置的应用程序,在弹出的设置窗口中,您可以根据您的需求,选择是否开启或关闭该应用程序的通知显示。
3. 您还可以通过设置具体通知行为,来满足个人化的需求。
例如,您可以设置应用程序通知是否需要发出声音、显示在屏幕顶部或隐藏在通知中心等。
三、自定义快速操作按钮在Windows系统中,通知和动作中心还提供了快速操作按钮,方便您进行快速操作。
以下是如何自定义快速操作按钮的步骤:1. 打开通知和动作中心后,在页面上方可以看到一个“快速操作”部分。
点击“添加快速操作”按钮。
2. 在弹出的窗口中,您可以看到一些可选的快速操作按钮,例如“无线网”、“屏幕投射”等。
选择您想要添加的快速操作按钮,然后点击“添加”按钮。
3. 添加成功后,在通知和动作中心中将显示您自定义的快速操作按钮。
windows消息汇总
本文主要包括以下内容:1、简单理解Windows的消息2、一段简单的Win32消息循环程序3、进一步深入理解Windows消息4、队列消息和非队列消息5、WM_COMMAND和WM_NOTIFY1、简单理解Windows的消息消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。
举个例子来说,鼠标单击某应用程序的一个按钮。
这时,Windows(操作系统)给应用程序发送这个消息,通知应用程序该按钮被点击,应用程序将进行相应反应。
消息一般用一个32位的数来标识,这个数唯一地标识这个消息。
这些消息的标识符一般在头文件winuser.h 中定义,如:#define WM_PAINT 0×000F#define WM_QUIT 0×0012其实消息本身是一个MSG结构。
MSG结构定义如下:typedef struct tagMSG {HWND hwnd; //接受消息的窗口句柄UINT message; //消息标识符WPARAM wParam; //32位附加信息LPARAM lParam; //32位附加信息DWORD time; //消息创建的时间POINT pt; //消息创建时鼠标在屏幕坐标系中的位置} MSG;也就是说,对于任何一个消息,都有一个MSG变量与之对应,该变量包含了消息的相关信息。
而我们在一般情况下,只使用消息的消息标识符,该标识符也唯一地代表了这个消息。
举个例子来说,当我们收到一个字符消息的时候,message成员变量的值就是WM_CHAR,但用户到底输入的是什么字符,那么就由wParam和lParam来说明。
wParam、lParam表示的信息随消息的不同而不同。
Windows操作系统已经给我们定义了大量的消息,这些消息我们称为系统消息。
除了系统消息,我们还可以自己定义消息,即自定义消息。
值小于0×0400的消息都是系统消息,自定义消息一般都大于0×0400。
windows消息浅析
在PB中使用Windows消息(一)Wm_syscommand参数使用消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。
例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。
消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。
例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。
这个记录类型叫做TMsg。
它在Windows单元中是这样声明的:hwnd: HWND; / /窗口句柄message: UINT; / /消息常量标识符wParam: WPARAM ; // 32位消息的特定附加信息lParam: LPARAM ; // 32位消息的特定附加信息time: DWORD; / /消息创建时的时间pt: TPoint; / /消息创建时的鼠标位置hwnd 32位的窗口句柄。
窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。
message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。
wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。
lParam 通常是一个指向内存中数据的指针。
由于W P a r a m、l P a r a m和P o i n t e r都是3 2位的,因此,它们之间可以相互转换。
对于我们使用来说,在众多的消息当中,WM_SYSCOMMAND,使用率是最高的,对於WM_SYSCOMMAND,功能表ID指示系统功能表中的哪一项被选中,所参数对应值如下:MF_BYCOMMAND = &H0&MF_BYPOSITION = &H400&SC_ARRANGE = &HF110SC_CLOSE = &HF060SC_HOTKEY = &HF150SC_HSCROLL = &HF080SC_KEYMENU = &HF100SC_MAXIMIZE = &HF030SC_MINIMIZE = &HF020SC_MOVE = &HF012 或 F010SC_NEXTWINDOW = &HF040SC_PREVWINDOW = &HF050SC_RESTORE = &HF120SC_SIZE = &HF000SC_VSCROLL = &HF070SC_TASKLIST = &HF130SC_SCREENSAVE = &HF140下面,介绍一下SC_COLSE、SC_MAXIMIZE、SC_MINIMIZE、SC_MOVE、SC_RESTORE、SC_SIZE、SC_HOTKEY这几个常用参数在PB中的应用:1、SC_CLOSE:61536 执行关闭功能。
Windows窗口消息机制简介
从图中可以看出,Windows维护着一个全局系统消息队列,外界的一切动作变化,都首先以消息的形式传入到系统消息队列中。
Windows 又为每一个应用程序维护着一个属于单个应用程序的消息队列,Windows会对系统消息队列中的消息进行筛选,将属于某个应用程序的消息分配到对应的应用程序消息队列中。
无论是系统消息队列,还是应用程序的消息队列,全部都是在Windows的控制下,应用程序通过GetMessage系统调用从Windows 管辖的相对应的应用程序消息队列中取得消息,并进行处理。
从图中可以看出,通过GetMessage取得消息,有一个从用户态到内核态的过程。
因为能操作消息队列的,只有Windows自己。
应用程序取得消息之后,对消息进行简单的处理(TranslateMessage)后,通过DispatchMessage系统调用将消息返还给Windows,再由Windows以该消息为参数,调用应用程序的窗口过程函数。
也就是说,应用程序的窗口过程不是由应用程序自己直接调用的,而是通过Windows系统间接调用的。
应用程序的窗口过程之所以要由Windows来调用,而不是应用程序亲自调用,主要是因为下面几点原因:1.一个应用程序可能会有多个窗口,不同窗口的消息应该发给不同的窗口过程,如果这个过程由应用程序自己来管理的话,会给编程带来很大的难度。
2.其它的应用程序可能会通过SendMessage系统调用直接将消息通过Windows发给应用程序的窗口过程3.Windows并不是将所有的消息都放入到应用程序的消息队列中,一些紧急的消息,Windows会直接调用应用程序的窗口过程。
图中还有关于postMessage和sendMessage的介绍:postMessage是由其它应用程序调用,将消息放入到应用程序的消息队列中。
sendMessage是由其它应用程序调用,将消息直接发送大应用程序的窗口过程。
这两个方法同样都是通过Windows系统操作应用程序的窗口过程^_^。
Delphi编程:Window消息大全使用详解(2)
Delphi编程:Window消息大全使用详解(2)--------------------------------------------------------------------------------à′?′£oE酷 [2004-1-13][35]WM_INITMENUPOPUP = $0117;当一个下拉菜单或子菜单将要被激活时发送此消息,它允许程序在它显示前更改菜单,而不要改变全部WM_MENUSELECT = $011F;当用户选择一条菜单项时发送此消息给菜单的所有者(一般是窗口)WM_MENUCHAR = $0120;当菜单已被激活用户按下了某个键(不同于加速键),发送此消息给菜单的所有者;WM_ENTERIDLE = $0121;当一个模态对话框或菜单进入空载状态时发送此消息给它的所有者,一个模态对话框或菜单进入空载状态就是在处理完一条或几条先前的消息后没有消息它的列队中等待WM_MENURBUTTONUP = $0122;WM_MENUDRAG = $0123;WM_MENUGETOBJECT = $0124;WM_UNINITMENUPOPUP = $0125;WM_MENUCOMMAND = $0126;WM_CHANGEUISTATE = $0127;WM_UPDATEUISTATE = $0128;WM_QUERYUISTATE = $0129;WM_CTLCOLORMSGBOX = $0132;在windows绘制消息框前发送此消息给消息框的所有者窗口,通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置消息框的文本和背景颜色WM_CTLCOLOREDIT = $0133;当一个编辑型控件将要被绘制时发送此消息给它的父窗口;通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置编辑框的文本和背景颜色WM_CTLCOLORLISTBOX = $0134;当一个列表框控件将要被绘制前发送此消息给它的父窗口;通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置列表框的文本和背景颜色WM_CTLCOLORBTN = $0135;当一个按钮控件将要被绘制时发送此消息给它的父窗口;通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置按纽的文本和背景颜色WM_CTLCOLORDLG = $0136;当一个对话框控件将要被绘制前发送此消息给它的父窗口;通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置对话框的文本背景颜色WM_CTLCOLORSCROLLBAR= $0137;当一个滚动条控件将要被绘制时发送此消息给它的父窗口;通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置滚动条的背景颜色WM_CTLCOLORSTATIC = $0138;当一个静态控件将要被绘制时发送此消息给它的父窗口;通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置静态控件的文本和背景颜色WM_MOUSEFIRST = $0200;WM_MOUSEMOVE = $0200;// 移动鼠标WM_LBUTTONDOWN = $0201;//按下鼠标左键WM_LBUTTONUP = $0202;//释放鼠标左键WM_LBUTTONDBLCLK = $0203;//双击鼠标左键WM_RBUTTONDOWN = $0204;//按下鼠标右键WM_RBUTTONUP = $0205;//释放鼠标右键WM_RBUTTONDBLCLK = $0206;//双击鼠标右键WM_MBUTTONDOWN = $0207;//按下鼠标中键WM_MBUTTONUP = $0208;//释放鼠标中键WM_MBUTTONDBLCLK = $0209;//双击鼠标中键WM_MOUSEWHEEL = $020A;当鼠标轮子转动时发送此消息个当前有焦点的控件WM_MOUSELAST = $020A;WM_PARENTNOTIFY = $0210;当MDI子窗口被创建或被销毁,或用户按了一下鼠标键而光标在子窗口上时发送此消息给它的父窗口WM_ENTERMENULOOP = $0211;发送此消息通知应用程序的主窗口that已经进入了菜单循环模式WM_EXITMENULOOP = $0212;发送此消息通知应用程序的主窗口that已退出了菜单循环模式WM_NEXTMENU = $0213;WM_SIZING = 532;当用户正在调整窗口大小时发送此消息给窗口;通过此消息应用程序可以监视窗口大小和位置也可以修改他们WM_CAPTURECHANGED = 533;发送此消息给窗口当它失去捕获的鼠标时;WM_MOVING = 534;当用户在移动窗口时发送此消息,通过此消息应用程序可以监视窗口大小和位置也可以修改他们;WM_POWERBROADCAST = 536;此消息发送给应用程序来通知它有关电源管理事件;WM_DEVICECHANGE = 537;当设备的硬件配置改变时发送此消息给应用程序或设备驱动程序WM_IME_STARTCOMPOSITION = $010D;WM_IME_ENDCOMPOSITION = $010E;WM_IME_COMPOSITION = $010F;WM_IME_KEYLAST = $010F;WM_IME_SETCONTEXT = $0281;WM_IME_NOTIFY = $0282;WM_IME_CONTROL = $0283;WM_IME_COMPOSITIONFULL = $0284;WM_IME_SELECT = $0285;WM_IME_CHAR = $0286;WM_IME_REQUEST = $0288;WM_IME_KEYDOWN = $0290;WM_IME_KEYUP = $0291;WM_MDICREATE = $0220;应用程序发送此消息给多文档的客户窗口来创建一个MDI 子窗口WM_MDIDESTROY = $0221;应用程序发送此消息给多文档的客户窗口来关闭一个MDI 子窗口WM_MDIACTIVATE = $0222;应用程序发送此消息给多文档的客户窗口通知客户窗口激活另一个MDI子窗口,当客户窗口收到此消息后,它发出WM_MDIACTIVE消息给MDI子窗口(未激活)激活它;WM_MDIRESTORE = $0223;程序发送此消息给MDI客户窗口让子窗口从最大最小化恢复到原来大小WM_MDINEXT = $0224;程序发送此消息给MDI客户窗口激活下一个或前一个窗口WM_MDIMAXIMIZE = $0225;程序发送此消息给MDI客户窗口来最大化一个MDI子窗口;WM_MDITILE = $0226;程序发送此消息给MDI客户窗口以平铺方式重新排列所有MDI子窗口WM_MDICASCADE = $0227;程序发送此消息给MDI客户窗口以层叠方式重新排列所有MDI子窗口WM_MDIICONARRANGE = $0228;程序发送此消息给MDI客户窗口重新排列所有最小化的MDI子窗口WM_MDIGETACTIVE = $0229;程序发送此消息给MDI客户窗口来找到激活的子窗口的句柄WM_MDISETMENU = $0230;程序发送此消息给MDI客户窗口用MDI菜单代替子窗口的菜单WM_ENTERSIZEMOVE = $0231;WM_EXITSIZEMOVE = $0232;WM_DROPFILES = $0233;WM_MDIREFRESHMENU = $0234;WM_MOUSEHOVER = $02A1;WM_MOUSELEAVE = $02A3;WM_CUT = $0300;程序发送此消息给一个编辑框或combobox来删除当前选择的文本WM_COPY = $0301;程序发送此消息给一个编辑框或combobox来复制当前选择的文本到剪贴板WM_PASTE = $0302;程序发送此消息给editcontrol或combobox从剪贴板中得到数据WM_CLEAR = $0303;程序发送此消息给editcontrol或combobox清除当前选择的内容;WM_UNDO = $0304;程序发送此消息给editcontrol或combobox撤消最后一次操作WM_RENDERFORMAT = $0305;WM_RENDERALLFORMATS = $0306;WM_DESTROYCLIPBOARD = $0307;当调用ENPTYCLIPBOARD函数时发送此消息给剪贴板的所有者WM_DRAWCLIPBOARD = $0308;当剪贴板的内容变化时发送此消息给剪贴板观察链的第一个窗口;它允许用剪贴板观察窗口来显示剪贴板的新内容;WM_PAINTCLIPBOARD = $0309;当剪贴板包含CF_OWNERDIPLAY格式的数据并且剪贴板观察窗口的客户区需要重画;WM_VSCROLLCLIPBOARD = $030A;WM_SIZECLIPBOARD = $030B;当剪贴板包含CF_OWNERDIPLAY格式的数据并且剪贴板观察窗口的客户区域的大小已经改变是此消息通过剪贴板观察窗口发送给剪贴板的所有者;WM_ASKCBFORMATNAME = $030C;通过剪贴板观察窗口发送此消息给剪贴板的所有者来请求一个CF_OWNERDISPLAY格式的剪贴板的名字WM_CHANGECBCHAIN = $030D;当一个窗口从剪贴板观察链中移去时发送此消息给剪贴板观察链的第一个窗口;WM_HSCROLLCLIPBOARD = $030E;此消息通过一个剪贴板观察窗口发送给剪贴板的所有者;它发生在当剪贴板包含CFOWNERDISPALY格式的数据并且有个事件在剪贴板观察窗的水平滚动条上;所有者应滚动剪贴板图象并更新滚动条的值;WM_QUERYNEWPALETTE = $030F;此消息发送给将要收到焦点的窗口,此消息能使窗口在收到焦点时同时有机会实现他的逻辑调色板WM_PALETTEISCHANGING= $0310;当一个应用程序正要实现它的逻辑调色板时发此消息通知所有的应用程序WM_PALETTECHANGED = $0311;此消息在一个拥有焦点的窗口实现它的逻辑调色板后发送此消息给所有顶级并重叠的窗口,以此来改变系统调色板WM_HOTKEY = $0312;当用户按下由REGISTERHOTKEY函数注册的热键时提交此消息WM_PRINT = 791;应用程序发送此消息仅当WINDOWS或其它应用程序发出一个请求要求绘制一个应用程序的一部分;WM_PRINTCLIENT = 792;WM_HANDHELDFIRST = 856;WM_HANDHELDLAST = 863;WM_PENWINFIRST = $0380;WM_PENWINLAST = $038F;WM_COALESCE_FIRST = $0390;WM_COALESCE_LAST = $039F;WM_DDE_FIRST = $03E0;WM_DDE_INITIATE = WM_DDE_FIRST + 0;一个DDE客户程序提交此消息开始一个与服务器程序的会话来响应那个指定的程序和主题名;WM_DDE_TERMINATE = WM_DDE_FIRST + 1;一个DDE应用程序(无论是客户还是服务器)提交此消息来终止一个会话;WM_DDE_ADVISE = WM_DDE_FIRST + 2;一个DDE客户程序提交此消息给一个DDE服务程序来请求服务器每当数据项改变时更新它WM_DDE_UNADVISE = WM_DDE_FIRST + 3;一个DDE客户程序通过此消息通知一个DDE服务程序不更新指定的项或一个特殊的剪贴板格式的项WM_DDE_ACK = WM_DDE_FIRST + 4;此消息通知一个DDE(动态数据交换)程序已收到并正在处理WM_DDE_POKE, WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE, WM_DDE_UNADVISE, or WM_DDE_INITIAT消息WM_DDE_DATA = WM_DDE_FIRST + 5;一个DDE服务程序提交此消息给DDE客户程序来传递个一数据项给客户或通知客户的一条可用数据项WM_DDE_REQUEST = WM_DDE_FIRST + 6;一个DDE客户程序提交此消息给一个DDE服务程序来请求一个数据项的值;WM_DDE_POKE = WM_DDE_FIRST + 7;一个DDE客户程序提交此消息给一个DDE服务程序,客户使用此消息来请求服务器接收一个未经同意的数据项;服务器通过答复WM_DDE_ACK消息提示是否它接收这个数据项;WM_DDE_EXECUTE = WM_DDE_FIRST + 8;一个DDE客户程序提交此消息给一个DDE服务程序来发送一个字符串给服务器让它象串行命令一样被处理,服务器通过提交WM_DDE_ACK消息来作回应;WM_DDE_LAST = WM_DDE_FIRST + 8;WM_APP = $8000;WM_USER = $0400;此消息能帮助应用程序自定义私有消息;/////////////////////////////////////////////////////////////////////通知消息(Notification message)是指这样一种消息,一个窗口内的子控件发生了一些事情,需要通知父窗口。
windows消息详解
WM_COMMAND ,WM_NOTIFY,WM_ACTIVE,WM_SETCURSOR#define AfxWndProc (*AfxGetAfxWndProc())LRESULT CALLBACK AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam){// special message which identifies the window as using AfxWndProcif (nMsg == WM_QUERYAFXWNDPROC)return 1;// all other messages route through message mapCWnd* pWnd = CWnd::FromHandlePermanent(hWnd);ASSERT(pWnd != NULL);ASSERT(pWnd==NULL || pWnd->m_hWnd == hWnd);if (pWnd == NULL || pWnd->m_hWnd != hWnd)return ::DefWindowProc(hWnd, nMsg, wParam, lParam);return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam); }friend LRESULT AFXAPI AfxCallWndProc(CWnd*, HWND, UINT, WPARAM, LPARAM);/////////////////////////////////////////////////////////////////////////////// Official way to send message to a CWndLRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, HWND hWnd, UINT nMsg,WPARAM wParam = 0, LPARAM lParam = 0){_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();MSG oldState = pThreadState->m_lastSentMsg; // save for nestingpThreadState->m_lastSentMsg.hwnd = hWnd;pThreadState->m_lastSentMsg.message = nMsg;pThreadState->m_lastSentMsg.wParam = wParam;pThreadState->m_lastSentMsg.lParam = lParam;#ifdef_DEBUG_AfxTraceMsg(_T("WndProc"), &pThreadState->m_lastSentMsg);#endif// Catch exceptions thrown outside the scope of a callback// in debug builds and warn the user.LRESULT lResult;TRY{#ifndef_AFX_NO_OCC_SUPPORT// special case for WM_DESTROYif ((nMsg == WM_DESTROY) && (pWnd->m_pCtrlCont != NULL))pWnd->m_pCtrlCont->OnUIActivate(NULL);#endif// special case for WM_INITDIALOGCRect rectOld;DWORD dwStyle = 0;if (nMsg == WM_INITDIALOG)_AfxPreInitDialog(pWnd, &rectOld, &dwStyle);// delegate to object's WindowProclResult = pWnd->WindowProc(nMsg, wParam, lParam);// more special case for WM_INITDIALOGif (nMsg == WM_INITDIALOG)_AfxPostInitDialog(pWnd, rectOld, dwStyle);}CATCH_ALL(e){lResult = AfxProcessWndProcException(e, &pThreadState->m_lastSentMsg);TRACE(traceAppMsg, 0, "Warning: Uncaught exception in WindowProc (returning %ld).\n", lResult);DELETE_EXCEPTION(e);}END_CATCH_ALLpThreadState->m_lastSentMsg = oldState;return lResult;}protected:// for processing Windows messagesvirtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);// for handling default processingLRESULT Default();virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);// for custom cleanup after WM_NCDESTROYvirtual void PostNcDestroy();// for notifications from parentvirtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);// return TRUE if parent should not process this messageBOOL ReflectChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);static BOOL PASCAL ReflectLastMsg(HWND hWndChild, LRESULT* pResult = NULL);// main WindowProc implementationLRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam){// OnWndMsg does most of the work, except for DefWindowProc callLRESULT lResult = 0;if (!OnWndMsg(message, wParam, lParam, &lResult)) lResult = DefWindowProc(message, wParam, lParam);return lResult;}BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult){LRESULT lResult = 0;union MessageMapFunctions mmf;mmf.pfn = 0;CInternalGlobalLock winMsgLock;// special case for commandsif (message == WM_COMMAND){if (OnCommand(wParam, lParam)){lResult = 1;goto LReturnTrue;}return FALSE;}// special case for notifiesif (message == WM_NOTIFY){NMHDR* pNMHDR = (NMHDR*)lParam;if (pNMHDR->hwndFrom != NULL && OnNotify(wParam, lParam, &lResult))goto LReturnTrue;return FALSE;}// special case for activationif (message == WM_ACTIVATE)_AfxHandleActivate(this, wParam,CWnd::FromHandle((HWND)lParam));// special case for set cursor HTERRORif (message == WM_SETCURSOR &&_AfxHandleSetCursor(this, (short)LOWORD(lParam), HIWORD(lParam))){lResult = 1;goto LReturnTrue;}// special case for windows that contain windowless ActiveX controlsBOOL bHandled;bHandled = FALSE;if ((m_pCtrlCont != NULL) && (m_pCtrlCont->m_nWindowlessControls > 0)){if (((message >= WM_MOUSEFIRST) && (message <= AFX_WM_MOUSELAST)) ||((message >= WM_KEYFIRST) && (message <= WM_IME_KEYLAST)) ||((message >= WM_IME_SETCONTEXT) && (message <= WM_IME_KEYUP))){bHandled = m_pCtrlCont->HandleWindowlessMessage(message, wParam, lParam, &lResult);}}if (bHandled){goto LReturnTrue;}const AFX_MSGMAP* pMessageMap; pMessageMap = GetMessageMap();UINT iHash; iHash = (LOWORD((DWORD_PTR)pMessageMap) ^ message) & (iHashMax-1);winMsgLock.Lock(CRIT_WINMSGCACHE);AFX_MSG_CACHE* pMsgCache; pMsgCache = &_afxMsgCache[iHash];const AFX_MSGMAP_ENTRY* lpEntry;if (message == pMsgCache->nMsg && pMessageMap == pMsgCache->pMessageMap){// cache hitlpEntry = pMsgCache->lpEntry;winMsgLock.Unlock();if (lpEntry == NULL)return FALSE;// cache hit, and it needs to be handledif (message < 0xC000)goto LDispatch;elsegoto LDispatchRegistered;}else{// not in cache, look for itpMsgCache->nMsg = message;pMsgCache->pMessageMap = pMessageMap;for (/* pMessageMap already init'ed */; pMessageMap->pfnGetBaseMap != NULL;pMessageMap = (*pMessageMap->pfnGetBaseMap)()){// Note: catch not so common but fatal mistake!!// BEGIN_MESSAGE_MAP(CMyWnd, CMyWnd)ASSERT(pMessageMap != (*pMessageMap->pfnGetBaseMap)());if (message < 0xC000){// constant window messageif ((lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries,message, 0, 0)) != NULL){pMsgCache->lpEntry = lpEntry;winMsgLock.Unlock();goto LDispatch;}}else{// registered windows messagelpEntry = pMessageMap->lpEntries;while ((lpEntry = AfxFindMessageEntry(lpEntry, 0xC000, 0, 0)) != NULL){UINT* pnID = (UINT*)(lpEntry->nSig);ASSERT(*pnID >= 0xC000 || *pnID == 0);// must be successfully registeredif (*pnID == message){pMsgCache->lpEntry = lpEntry;winMsgLock.Unlock();goto LDispatchRegistered;}lpEntry++; // keep looking past this one}}LDispatchRegistered: // for registered windows messagesASSERT(message >= 0xC000);ASSERT(sizeof(mmf) == sizeof(mmf.pfn));mmf.pfn = lpEntry->pfn;lResult = (this->*mmf.pfn_l_w_l)(wParam, lParam);LReturnTrue:if (pResult != NULL)*pResult = lResult;return TRUE;}///////////////////////////////////////////////////////////////////////////// // CWnd command handlingBOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)// return TRUE if command invocation was attempted{UINT nID = LOWORD(wParam);HWND hWndCtrl = (HWND)lParam;int nCode = HIWORD(wParam);// default routing for command messages (through closure table)if (hWndCtrl == NULL){// zero IDs for normal commands are not allowedif (nID == 0)return FALSE;// make sure command has not become disabled before routingCTestCmdUI state;state.m_nID = nID;OnCmdMsg(nID, CN_UPDATE_COMMAND_UI, &state, NULL);if (!state.m_bEnabled){TRACE(traceAppMsg, 0, "Warning: not executing disabled command %d\n", nID);return TRUE;}// menu or acceleratornCode = CN_COMMAND;}else{// control notificationASSERT(nID == 0 || ::IsWindow(hWndCtrl));if (_afxThreadState->m_hLockoutNotifyWindow == m_hWnd)return TRUE; // locked out - ignore control notification // reflect notification to child window controlif (ReflectLastMsg(hWndCtrl))return TRUE; // eaten by child// zero IDs for normal commands are not allowedif (nID == 0)return FALSE;}#ifdef_DEBUGif (nCode < 0 && nCode != (int)0x8000)TRACE(traceAppMsg, 0, "Implementation Warning: control notification = $%X.\n", nCode);#endifreturn OnCmdMsg(nID, nCode, NULL, NULL);}BOOL CWnd::OnNotify(WPARAM, LPARAM lParam, LRESULT* pResult)ASSERT(pResult != NULL);NMHDR* pNMHDR = (NMHDR*)lParam;HWND hWndCtrl = pNMHDR->hwndFrom;// get the child ID from the window itselfUINT_PTR nID = _AfxGetDlgCtrlID(hWndCtrl);int nCode = pNMHDR->code;ASSERT(hWndCtrl != NULL);ASSERT(::IsWindow(hWndCtrl));if (_afxThreadState->m_hLockoutNotifyWindow == m_hWnd)return TRUE; // locked out - ignore control notification// reflect notification to child window controlif (ReflectLastMsg(hWndCtrl, pResult))return TRUE; // eaten by childAFX_NOTIFY notify;notify.pResult = pResult;notify.pNMHDR = pNMHDR;return OnCmdMsg((UINT)nID, MAKELONG(nCode, WM_NOTIFY), ¬ify, NULL);}BOOL CCmdTarget::OnCmdMsg(UINT nID, int nCode, void* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo)CCmdTarget类详解CCmdTarget是windows消息处理的基础和核心。
windows消息机制工作原理
windows消息机制工作原理
Windows消息机制是Windows操作系统中的核心特性之一,它允许不同的应用程序之间进行通信和交互。
当一个应用程序需要与另一个应用程序进行交互时,它可以发送一个消息到目标应用程序。
目标应用程序会接收这个消息并做出相应的处理。
Windows消息机制的工作原理可以分为以下几个步骤:
1. 发送消息:当一个应用程序需要发送消息到另一个应用程序时,它会调用Windows API中的SendMessage函数或者PostMessage函数。
这些函数会将消息传递给操作系统内核,并将消息发送到目标应用程序的消息队列中。
2. 消息队列:每个应用程序都有一个消息队列,它用于存储来自其他应用程序的消息。
Windows操作系统会在后台自动地维护这些消息队列,并当应用程序准备好时通知它们有新的消息到达。
3. 消息循环:每个应用程序都有一个消息循环,它用于获取来自消息队列的消息并将其传递给相应的消息处理程序。
当操作系统通知应用程序有新的消息到达时,应用程序会从消息队列中获取消息并将其传递给消息循环。
4. 处理消息:每个应用程序都有一个消息处理程序,它用于处理来自其他应用程序的消息。
当消息循环从消息队列中获取到消息时,它会将消息传递给相应的
消息处理程序进行处理。
总之,Windows消息机制利用了操作系统层面的消息队列和消息循环来实现应用程序之间的通信和交互。
这种机制可以帮助开发者实现非常灵活的应用程序,并且非常适合多任务处理和多线程应用。
Windows消息机制简介
Windows消息机制简介【摘要】Windows消息机制是Windows编程中至关重要的一部分。
Windows消息机制中的消息是指Windows发出的一个通知,该通知告诉应用程序某个事情发生了。
而且消息都有其固定的结构信息。
另外,Windows消息可以分为队列消息和非队列消息。
队列消息是把消息投递到一个先进先出的消息队列中,而非队列消息是把消息直接发送给窗口过程。
而在消息的发送过程中,存在两种发送方式,分别是发送方式和寄送方式。
对于Windows通过发送方式将消息存入系统消息队列后,再将消息分配到对应的应用程序的消息队列,此时通过消息循环读取消息,再在消息循环中提请操作系统将该调用对应的窗口函数。
一、什么是消息消息,就是指Widows发出的一个通知,告诉应用程序某个事情发生了。
例如,当鼠标单击某应用程序的一个按钮。
这时,Widows(操作系统)给应用程序发送这个消息,通知应用程序该按钮被点击,应用程序将进行相应反应。
消息本身是作为一个记录传递给应用程序的,这个记录(一般在C/Java/汇编中称为“结构体”)中包含了消息的类型以及其他信息。
这个记录类型叫做Msg。
那么,我们先来介绍一下这个记录的结构信息。
它在Windows中的声明如下:Typedef struct tagMSG{HWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt;} MSG,*PMSG;其中各数据成员的意义表示如下,hwnd:消息将要发送到的那个窗口的句柄,用这个参数可以决定让哪个窗口接收消息。
message:消息常量标识符,也就是我们常说的消息号。
wParam:一个32位的消息参数,这个值的确切意义取决于消息本身。
lParam:一个32位的消息参数,这个值的确切意义取决于消息本身。
time:消息放入消息队列中的时间,在这个域中写入的并非当时日期,而是从Windows启动后所测量的时间值。
Windows的消息
参数point:是鼠标事件发生时鼠标光标所在的位置。 参数nFlags:指明鼠标按钮的状态以及鼠标事件发生时键盘 上某些键的状态,每一状态都可以由nFlags的一位来表示。
(3)窗口消息。在MFC应用程序中,窗口消息是由视图类、 窗口类及它们的派生类处理的。窗口消息往往带参数,并且 各消息所带的参数各不相同。
(2)鼠标消息。在Windows中,处理鼠标操作基本上有下列 三种:
单击(Click):表示按一下鼠标的左键或右键,然后释放; 双击(Double Click):表示快速连续按两下鼠标左键; 拖动(Drag):指按住鼠标的按键后,再移动鼠标。 所有这些鼠标操作,都会产生相应的消息。如下所示。
所有鼠标消息的处理函数都有很相似的原型,它们都有两个参 数。以处理鼠标左键按下消息的函数OnLButtonDown() 为例来进行说明。此函数的原型如下:
1.2 Windows程序中的消息分类
在Windows程序中,消息大致可以分为3类:标准的 Windows消息、控件消息和命令消息。
1.标准的Windows消息 标准的Windows消息又可分为三类:键盘消息、鼠标 消息和窗口消息。 键盘消息对键盘的某个键的动作相关。 鼠标消息涉及到鼠标的单击、双击、拖动等。 窗口消息一般与创建窗口、绘制窗口、移动窗口和销 毁窗口等动作有关。
2.控件消息
控件消息是指:控件或其他子窗口向父窗口 发 送 WM_COMMAND 消 息 或 控 件 类 所 发 送 的 消息。发送控件消息的控件在Visual C++中使 用惟一的ID号来进行标识,使用控件类来操纵。
ቤተ መጻሕፍቲ ባይዱ控件消息分为两类:
解释一下Windows的消息机制
解释一下Windows的消息机制Windows是一个消息(Message)驱动系统。
Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。
应用程序想要实现的功能由消息来触发,并且靠对消息的响应和处理来完成。
Windows系统中有两种消息队列:系统消息队列和应用程序消息队列。
计算机的所有输入设备由Windows监控。
当一个事件发生时,Windows先将输入的消息放入系统消息队列中,再将消息拷贝到相应的应用程序消息队列中。
应用程序的消息处理程序将反复检测消息队列,并把检测到的每个消息发送到相应的窗口函数中。
这便是一个事件从发生至到达窗口函数必须经历的过程。
必须注意的是,消息并非是抢占性的,无论事件的缓急,总是按照到达的先后派对,依次处理(一些系统消息除外),这样可能使一些实时外部事件得不到及时处理。
Windows中的消息是放在对应的进程的消息队列里的。
可以通过GetMessage取得,并且对于一般的消息,此函数返回非零值,但是对于WM_QUIT消息,返回零。
可以通过这个特征,结束程序。
当取得消息之后,应该先转换消息,再分发消息。
所谓转换,就是把键盘码的转换,所谓分发,就是把消息分发给对应的窗口,由对应的窗口处理消息,这样对应窗体的消息处理函数就会被调用。
两个函数可以实现这两个功能:TranslateMessage和DispatchMessage。
另外,需要注意,当我们点击窗口的关闭按钮关闭窗口时,程序并没有自动退出,而是向程序发送了一个WM_DESTROY消息(其实过程是这样的,首先向程序发送WM_CLOSE消息,默认的处理程序是调用DestroyWindow销毁窗体,从而引发WM_DESTROY消息),此时在窗体中我们要响应这个消息,如果需要退出程序,那么就要向程序发送WM_QUIT消息(通过PostQuitMessage实现)。
一个窗体如果想要调用自己的消息处理函数,可以使用SendMessage向自己发消息。
易语言WIN消息使用
【易语言】WIN消息大全1、窗口最大化===发送信息(274,61488,0)‘如果还是启动窗口要加上窗口名称,如:窗口1.发送信息()2、改变输入法===发送信息(8,0,0)例如:编辑框.发送信息(258,#A健,5)在编辑框输入5个A3、移动控件控件.发送信息(274,61458,0)控件.发送信息(161,2,0)4、调整控件调整左边:控件.发送信息(274,61441,0)调整右边:控件.发送信息(274,61442,0)调整顶边:控件.发送信息(274,61443,0)左上角调整:控件.发送信息(274,61444,0)右上角调整:控件.发送信息(274,61445,0)调整底部控件.发送信息(274,61446,0)左下角调整:控件.发送信息(274,61447,0)右下角调整:控件.发送信息(274,61448,0)4、控件最大化控件.发送信息(274,61488,0)5、控件最小化控件.发送信息(274,61473,0)6、关闭控件控件.发送信息(16,0,0)7、单击鼠标左键控件.发送信息(513,0,0)8、鼠标带问号(再次单击问号消失)发送信息(274,61836,0)9、清除窗口标题控件.发送信息(12,0,0)10、复制编辑框.发送信息(769,0,0)11、粘贴编辑框.发送信息(770,0,0)12、全选编辑框.发送信息(177,0,-1)13、清空内容编辑框.发送信息(12,1,0)14、按钮单击发送消息(发送按钮句柄,245,0,0)15、删除控件.发送信息(768,0,0)16、撤销控件.发送信息(772,0,0)17、剪切控件.发送信息(771,0,0)18、退出控件.发送信息(1,0,0)19、获得焦点控件.发送信息(7,0,0)20、失去焦点控件.发送信息(8,0,0)21、结束控件.发送信息(25,0,0)22、单击鼠标右键控件.发送信息(123,0,0)23、取消全选控件.发送信息(177,0,0)24、1组合框弹出列表组合框.发送信息(155,1,0)25、发送文本(Dll命令。
Windows消息机制要点
Windows消息机制要点1. 窗⼝过程每个窗⼝会有⼀个称为窗⼝过程的回调函数(WndProc),它带有四个参数,分别为:窗⼝句柄(Window Handle),消息ID(Message ID),和两个消息参数(wParam, lParam), 当窗⼝收到消息时系统就会调⽤此窗⼝过程来处理消息。
(所以叫回调函数)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, LOWORD(wParam)表⽰菜单项,⼯具栏按钮或控件的ID。
如果是控件, HIWORD(wParam)表⽰控件消息类型3> 控件通知(Notify Message)控件通知消息,这是最灵活的消息格式,其Message, wParam, lParam分别为:WM_NOTIFY, 控件ID,指向NMHDR的指针。
NMHDR包含控件通知的内容,可以任意扩展。
2) 程序定义消息(Application-Defined Messages)⽤户⾃定义的消息,对于其范围有如下规定:WM_USER: 0x0400-0x7FFF (ex. WM_USER+10)WM_APP(winver> 4.0): 0x8000-0xBFFF (ex.WM_APP+4)RegisterWindowMessage: 0xC000-0xFFFF3 消息队列(Message Queues)Windows中有两种类型的消息队列1) 系统消息队列(System Message Queue)这是⼀个系统唯⼀的Queue,设备驱动(mouse, keyboard)会把操作输⼊转化成消息存在系统队列中,然后系统会把此消息放到⽬标窗⼝所在的线程的消息队列(thread-specific message queue)中等待处理2) 线程消息队列(Thread-specific Message Queue)每⼀个GUI线程都会维护这样⼀个线程消息队列。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
发送此消息来判定combobox或listbox新增加的项的相对位置
WM_GETOBJECT = $003D;
WM_COMPACTING = $0041;
显示内存已经很少了
WM_WINDOWPOSCHANGING = $0046;
此消息有一个LBS_WANTKEYBOARDINPUT风格的发出给它的所有者来响应WM_KEYDOWN消息
WM_CHARTOITEM = $002F;
此消息由一个LBS_WANTKEYBOARDINPUT风格的列表框发送给他的所有者来响应WM_CHAR消息
当系统将要进入暂停状态时发送此消息
WM_COPYDATA = $004A;
当一个应用程序传递数据给另一个应用程序时发送此消息
WM_CANCELJOURNAL = $004B;
当某个用户取消程序日志激活状态,提交此消息给程序
WM_NOTIFY = $004E;
当某个控件的某个事件已经发生或这个控件需要得到一些信息时,发送此消息给它的父窗口
WM_INPUTLANGCHANGEREQUEST = $0050;
当用户选择某种输入语言,或输入语言的热键改变
WM_INPUTLANGCHANGE = $0051;
当the list box 或 combo box 被销毁 或 当 某些项被删除通过LB_DELETESTRING,
LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT 消息
WM_VKEYTOITEM = $002E;
WM_SETFOCUS = $0007;
获得焦点后
WM_KILLFOCUS = $0008;
失去焦点
WM_ENABLE = $000A;
改变enable状态
WM_SETREDRAW = $000B;
设置窗口是否能重画
WM_FONTCHANGE = $001D;
当系统的字体资源库变化时发送此消息给所有顶级窗口
WM_TIMECHANGE = $001E;
当系统的时间变化时发送此消息给所有顶级窗口
WM_CANCELMODE = $001F;
发送此消息来取消某种正在进行的摸态(操作)
lParam: LPARAM ; // 32位消息的特定附加信息
time: DWORD; / /消息创建时的时间
pt: TPoint; / /消息创建时的鼠标位置
end;
消息中有什么?
是否觉得一个消息记录中的信息像希腊语一样?如果是这样,那么看一看下面的解释:
Window 消息大全使用详解设为首页
收藏本站
给我写信
2003年7月25日 星期五返回首页 - 技巧大全 - 专题讲座 - 网络资源 - 站长风采 - 留言簿
为了网站建设得更好,请支持我,花几分钟时间,加入亚洲交友中心或注册幸运邮件,对你只是举手之劳...
WM_QUIT = $0012;
用来结束程序运行或当程序调用postquitmessage函数
WM_QUERYOPEN = $0013;
当用户窗口恢复以前的大小位置时,把此消息发送给某个图标
WM_EБайду номын сангаасASEBKGND = $0014;
WM_DESTROY = $0002;
一个窗口被销毁
WM_MOVE = $0003;
移动一个窗口
WM_SIZE = $0005;
改变一个窗口的大小
WM_ACTIVATE = $0006;
一个窗口被激活或失去激活状态;
发送给有焦点的窗口,如果当前都没有焦点,就把此消息发送给当前激活的窗口
WM_USERCHANGED = $0054;
当用户已经登入或退出后发送此消息给所有的窗口,当用户登入或退出时系统更新用户的具体
设置信息,在用户更新设置时系统马上发送此消息;
此消息发送给窗口当它将要改变大小或位置;
WM_PAINTICON = $0026;
发送给最小化窗口当它图标将要被重画
WM_ICONERASEBKGND = $0027;
此消息发送给某个最小化窗口,仅当它在画图标前它的背景必须被重画
WM_NOTIFYFORMAT = $0055;
公用控件,自定义控件和他们的父窗口通过此消息来判断控件是使用ANSI还是UNICODE结构
在WM_NOTIFY消息,使用此控件能使某个控件与它的父控件之间进行相互通信
发送此消息给那个窗口的大小和位置将要被改变时,来调用setwindowpos函数或其它窗口管理函数
WM_WINDOWPOSCHANGED = $0047;
发送此消息给那个窗口的大小和位置已经被改变时,来调用setwindowpos函数或其它窗口管理函数
WM_POWER = $0048;(适用于16位的windows)
当平台现场已经被改变后发送此消息给受影响的最顶级窗口
WM_TCARD = $0052;
当程序已经初始化windows帮助例程时发送此消息给应用程序
WM_HELP = $0053;
此消息显示用户按下了F1,如果某个菜单是激活的,就发送此消息个此窗口关联的菜单,否则就
此消息给这些空件的所有者
WM_MEASUREITEM = $002C;
当button, combo box, list box, list view control, or menu item 被创建时
发送此消息给控件的所有者
WM_DELETEITEM = $002D;
当窗口背景必须被擦除时(例在窗口改变大小时)
WM_SYSCOLORCHANGE = $0015;
当系统颜色改变时,发送此消息给所有顶级窗口
WM_ENDSESSION = $0016;
当系统进程发出WM_QUERYENDSESSION消息后,此消息发送给应用程序,
WM_GETHOTKEY = $0033;
应用程序发送此消息来判断热键与某个窗口是否有关联
WM_QUERYDRAGICON = $0037;
此消息发送给最小化窗口,当此窗口将要被拖放而它的类中没有定义图标,应用程序能返回一个图标或光标的句柄,当用户拖放图标时系统显示这个图标或光标
发送此消息给MDI子窗口当用户点击此窗口的标题栏,或当窗口被激活,移动,改变大小
WM_QUEUESYNC = $0023;
此消息由基于计算机的训练程序发送,通过WH_JOURNALPALYBACK的hook程序
分离出用户输入消息
WM_GETMINMAXINFO = $0024;
WM_SETCURSOR = $0020;
如果鼠标引起光标在某个窗口中移动且鼠标输入没有被捕获时,就发消息给某个窗口
WM_MOUSEACTIVATE = $0021;
当光标在某个非激活的窗口中而用户正按着鼠标的某个键发送此消息给当前窗口
WM_CHILDACTIVATE = $0022;
WM_SETTEXT = $000C;
应用程序发送此消息来设置一个窗口的文本
WM_GETTEXT = $000D;
应用程序发送此消息来复制对应窗口的文本到缓冲区
WM_GETTEXTLENGTH = $000E;
得到与一个窗口有关的文本的长度(不包含空字符)
WM_PAINT = $000F;
要求一个窗口重画自己
WM_CLOSE = $0010;
当一个窗口或应用程序要关闭时发送一个信号
WM_QUERYENDSESSION = $0011;
当用户选择结束对话框或程序自己调用ExitWindows函数
WM_SETFONT = $0030;
当绘制文本时程序发送此消息得到控件要用的颜色
WM_GETFONT = $0031;
应用程序发送此消息得到当前控件绘制文本的字体
WM_SETHOTKEY = $0032;
应用程序发送此消息让一个窗口与一个热键相关连
通知它对话是否结束
WM_SYSTEMERROR = $0017;
WM_SHOWWINDOW = $0018;
当隐藏或显示窗口是发送此消息给这个窗口
WM_ACTIVATEAPP = $001C;
发此消息给应用程序哪个窗口是激活的,哪个是非激活的;
lParam 通常是一个指向内存中数据的指针。由于W P a r a m、l P a r a m和P o i n t e r都是3 2位的,
因此,它们之间可以相互转换。
WM_NULL = $0000;
WM_CREATE = $0001;
应用程序创建一个窗口
【Window 消息大全使用详解】
消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。这个记录类型叫做TMsg,
hwnd 32位的窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、按钮、编辑框等)。
message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。
wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。