关于消息与消息队列

About Messages and Message Queues
关于消息与消息队列
--------------------------------------------------------------------------------
Unlike MS-DOS-based applications, Windows-based applications are event-driven.
与以MS-DOS为基础的应用程序不同,以Windows为基础的应用程序是事件驱动的。
They do not make explicit function calls (such as C run-time library calls) to obtain input. Instead, they wait for the system to pass input to them.
他们没有作出明确的函数调用(如C运行时库调用)获得输入。相反,他们等待系统将输入传递给他们。
The system passes all input for an application to the various windows in the application.
系统传递所有的输入给一个应用程序到各个不同的窗口
Each window has a function, called a window procedure, that the system calls whenever it has input for the window.
每个窗口都对应一个函数,称为窗口过程,当窗口有输入信息时由系统调用。
The window procedure processes the input and returns control to the system.
窗口过程处理这些输入信息,并将控制权返还给系统。
For more information about window procedures, see Window Procedures.
更多窗口过程信息,参考窗口过程

Microsoft Windows XP: If a top-level window stops responding to messages for more than several seconds, the system considers the window to be not responding.
微软Windows XP:如果顶层窗口停止响应超过几秒钟的消息,系统认为窗口没有响应。
In this case, the system hides the window and replaces it with a ghost window that has the same Z order, location, size, and visual attributes.
在这种情况下,系统隐藏的窗口,并取代鬼窗口具有相同的Z顺序,位置,大小,和视觉属性。
This allows the user to move it, resize it, or even close the application.
这允许用户移动它,改变它的大小,甚至关闭应用程序。
However, these are the only actions available because the application is actually not responding.
然而,这些应用程序是唯一可用的行动,因为实际上没有响应。
When in the debugger mode, the system does not generate a ghost window.
在调试模式时,系统不会产生鬼窗口。

This section discusses the following topics:

Windows Messages
Message Types
Message Routing
Message Handling
Message Filtering
Posting and Sending Messages
Message Deadlocks
Broadcasting Messages
Query Messages
Windows Messages

The system passes input to a window procedure in the form of messages.
系统以消息的形式将输入传递给窗口过程。
Messages are generated by both the system and applications.
系统和应用程序均产生消息。
The system generates a message at each input event — for example, when the user types, moves the mouse, or clicks a control such as a scroll bar.
系统生成的消息,在每个输入事件 - 例如,当用户类型,移动鼠标或点击控制,如滚动条。
The system also generates messages in response to changes in the system brought about by an application, such as when an application changes the pool of system font resources or resizes one of its windows.
系统还可以产生在应用程序给系统带来的变化有关的消息,如当一个应用程序改变系统字体资源池或调整大小的窗口之一,响应消息。
An application can generate messages to direct its own windows to perform tasks or to communicate with windows in other applications.
应用程序可以产生消息来指导自己的窗口,执行任务或与其他应用程序的窗口沟通。

The system sends a message to a window procedure with a set of four parameters: a window handle, a message identifier, and two values called message parameters.
系统发送给窗口过程一个具有四个参数的消息:窗口句柄,消息标识符,以及两个附加值作为消息参数值。
The window handle identifies the window for which the message is intended.
窗口句柄标识该消息的目的是窗口。
The system uses it to determine which window procedure should receive the message.
系统使用它来确定哪个窗口过程应该收到该消息。

A message identifieris a named constant that identifies the purpose of a message.
一个的消息identifieris一个名为常数,确定了消息的目的。
When a window procedure receives a message, it uses a message identifier to determine how to process the message.
当窗口过程接收到一条消息,它使用消息标识符来决定如何处理消息。
For example, the message identifier WM_PAINT tells the window procedure that the window's client area has changed and must be repainted.
例如,消息标识符的WM_PAINT告诉窗口过程,窗口的客户区已发生变化,必须重新粉刷。

Message parameters specify data or the location of data used by a window procedure when processing a message.
消息参数指定数据或由一个窗口过程处理消息时使用的数据的位置。
The meaning and value of the message parameters depend on the message.
消息参数的含义和值取决于消息。
A message parameter can contain an integer, packed bit flags, a pointer to a structure containing additional data, and so on.
消息参数可以包含一个整数,包装标志位,一个包含额外的数据结构的指针,等等。
When a message does not use message parameters, they are typically set to NULL.
当消息不使用消息参数,它们通常设置为NULL。
A window procedure must check the message identifier to determine how to interpret the message parameters.
窗口过程必须检查消息标识符来决定如何解释消息参数。

Message Types
This section describes the two types of messages:
本节介绍的两种类型的消息:

System-Defined Messages
系统定义的消息
Application-Defined Messages
应用程序定义的消息

System-Defined Messages
The system sends or posts a system-defined message when it communicates with an application.
系统发送或寄送系统定义的消息,当它与应用程序进行通信。
It uses these messages to control the operations of applications and to provide input and other information for applications to process.
它使用这些信息来控制应用程序的运作,并提供输入和其他信息供应用程序的处理。
An application can also send or post system-defined messages.
应用程序也可以发送或寄送系统定义的消息。
Applications generally use these messages to control the operation of control windows created by using preregistered window classes.
应用程序通常使用这些信息通过预注册窗口类创建的控制窗口来控制操作。

Each system-defined message has a unique message identifier and a corresponding symbolic constant (defined in the software development kit (SDK) header files) that states the purpose of the message.
每个系统定义的消息都有一个唯一的消息标识符和相应的符号常量(软件开发工具包(SDK)的头文件中定义),指出该消息的目的。
For example, the WM_PAINT constant requests that a window paint its contents.
例如,在WM_PAINT不断要求一个窗口绘制其内容。

Symbolic constants specify the category to which system-defined messages belong.
符号常量指定系统定义消息属于的类别。
The prefix of the constant identifies the type of window that can interpret and process the message.
常量的前缀标识,可以解释和处理的消息窗口的类型。
Following are the prefixes and their related message categories.
以下是前缀和他们相关的消息类别。
Prefix  Message category
ABM  Application desktop toolbar 
BM  Button control 
CB  Combo box control 
CBEM  Extended combo box control
CDM  Common dialog box 
DBT  Device 
DL  Drag list box 
DM  Default push button control 
DTM  Date and time picker control
EM  Edit control 
HDM  Header control 
HKM  Hot key control
IPM  IP address control
LB  List box control 
LVM  List view control 
MCM  Month calendar control
PBM  Progress bar 
PGM  Pager control
PSM  Property sheet 
RB  Rebar control
SB  Status bar window 
SBM  Scroll bar control 
STM  Static control 
TB  Toolbar 
TBM  Trackbar 
TCM  Tab control 
TTM  Tooltip control 
TVM  Tree-view control 
UDM  Up-down control
WM  General window 

General window messages cover a wide range of information and requests, including messages for mouse and keyboard input, menu and dialog box input, window creation and management, and Dynamic Data Exchange (DDE).
一般的窗口消息涵盖范围广泛的信息和要求,包括鼠标和键盘输入,菜单和对话框输入,窗口创建和管理动态数据交换(DDE)的消息。

Application-Defined Messages
An application can create messages to be used by its own windows or to communicate with windows in other processes.
应用程序可以创建消息用于自己的窗口或者与其他进程窗口通信。
If an application creates its own messages, the window procedure that receives them must interpret the messages and provide appropriate processing.
如果应用程序创建自己的消息,窗口过程接收,他们必须解释的消息,并提供适当的处理。

Message-identifier values are used as follows:
消息标识符值如下:
The system reserves message-identifier values in the range 0x0000 through 0x03FF (the value of WM_USER – 1) for system-defined messages.
系统储备的消息标识符值范围0x00000x03FF(WM_USER +值 -  1)为系统定义的消息。
Applications cannot use these values for private messages.
应用程序不能使用这些值的私有消息。
Values in the range 0x0400 (the value of WM_USER) through 0x7FFF are available for message identifiers for private window classes.
值范围在0x0400到0x7fff(WM_USER +值)是私有窗口类的消息标识符。
If your application is marked version 4.0, you can use message-identifier values in the range 0x8000 (WM_APP) through 0xBFFF for private messages.
如果您的应用程序被标记为版本4.0,您可以使用通过私人讯息0xBFFF(WM_APP)的范围等于0x8000的消息标识符值。
The system returns a message identifier in the range 0xC000 through 0xFFFF when an application calls the RegisterWindowMessage function to register a message.
应用程序调用RegisterWindowMessage函数注册一个消息时,系统会返回一个消息标识符范围0xC000到0xFFFF。
The message identifier returned by this function is guaranteed to be unique throughout the system.
这个函数返回的消息标识符是保证整个系统中是唯一的
Use of this function prevents conflicts that can arise if other applications use the same message identifier for different purposes.
使用此功能,防止可能出现的冲突,如果其他应用程序使用相同的消息标识符为不同的目的。
Message Routing
消息路由
The system uses two methods to route messages to a window procedure: posting messages to a first-in, first-out queue called a message queue, a system-defined memory object that temporarily stores messages, and sending messages directly to a window procedure.
该系统采用两种方法将消息路由到窗口过程:先入,先出队列发布消息称为消息队列,系统定义的临时存储消息的内存对象,还有一种是直接向窗口过程发送消息。

Messages posted to a message queue are called queued messages.
发布到消息队列中的消息,被称为排队消息。
They are primarily the result of user input entered through the mouse or keyboard, such as WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN, and WM_CHAR messages.
他们主要是通过到WM_MOUSEMOVE,WM_LBUTTONDOWN,WM_KEYDOWN,WM_CHAR消息,如鼠标或键盘输入的用户输入的结果。
Other queued messages include the timer, paint, and quit messages: WM_TIMER, WM_PAINT, and WM_QUIT. Most other messages, which are sent directly to a window procedure, are called nonqueued messages.
其他排队的消息,包括计时器,油漆,并退出消息:WM_TIMER消息,WM_PAINT消息,WM_QUIT。大多数其他的消息,这将直接发送到窗口过程,称为nonqueued消息。

Queued Messages
排队的消息
Nonqueued Messages
Nonqueued讯息
Queued Messages
The system can display any number of windows at a time.
该系统可以在任何时间显示任何数量的窗口。
To route mouse and keyboard input to the appropriate window, the system uses message queues.
路由鼠标和键盘输入到相应的窗口,该系统采用消息队列。

The system maintains a single system message queue and one thread-specific message queue for each graphical user interface (GUI) thread.
系统维护一个系统消息队列和一个线程,具体为每个图形用户界面(GUI)线程的消息队列。
To avoid the overhead of creating a message queue for non–GUI threads, all threads are created initially without a message queue.
为了避免创建一个非GUI线程的消息队列的开销,所有的线程创建初期,没有一个消息队列。
The system creates a thread-specific message queue only when the thread makes its first call to one of the User or Windows Graphics Device Interface (GDI) functions.
只有当线程第一次调用一个用户或Windows图形设备接口(GDI)函数,系统创建一个线程特定的消息队列。

Whenever the user moves the mouse, clicks the mouse buttons, or types on the keyboard, the device driver for the mouse or keyboard converts the input into messages and places them in the system message queue.
当用户移动鼠标,点击鼠标按钮或键盘上的类型,鼠标或键盘的设备驱动程序转换成输入消息和系统消息队列中的地方。
The system removes the messages, one at a time, from the system message queue, examines them to determine the destination window, and then posts them to the message queue of the thread that created the destination window.
系统中删除的消息,一次一个,从系统消息队列,检查他们确定的目标窗口,然后他们的创建目标窗口的线程的消息队列。
A thread's message queue receives all mouse and keyboard messages for the windows created by the thread.
一个线程的消息队列接收所有该线程创建的窗口的鼠标和键盘消息。
The thread removes messages from its queue and directs the system to send them to the appropriate window procedure for processing.
线程从队列中删除消息和指示系统,将它们发送到相应的窗口过程处理。

With the exception of the WM_PAINT message, the WM_TIMER message, and the WM_QUIT message, the system always posts messages at the end of a message queue.
特殊的如WM_PAINT消息,WM_TIMER消息,WM_QUIT消息,系统总是寄送消息到消息队列的最后。
This ensures that a window receives its input messages in the proper first in, first out (FIFO) sequence.
这将确保一个窗口接收输入信息,在适当的先入先出(FIFO)的顺序。
The WM_PAINT message, the WM_TIMER message, and the WM_QUIT message, however, are kept in the queue and are forwarded to the window procedure only when the queue contains no other messages.
然而,WM_PAINT消息,WM_TIMER消息,WM_QUIT消息,保持在队列中,只有当队列不包含任何其他的消息被转发到窗口过程。
In addition, multiple WM_PAINT messages for the same window are combined into a single WM_PAINT message, consolidating all invalid parts of the client area into a single area.
此外,在同一窗口的多个WM_PAINT消息消息合并成一个单一的WM_PAINT消息,客户区的所有无效部分合并成一个单一的区域。
Combining WM_PAINT messages reduces the number of times a window must redraw the contents of its client area.
结合WM_PAINT消息减少的次数,一个窗口,必须重绘客户区的内容。

The system posts a message to a thread's message queue by filling an MSG structure and then copying it to the message queue.
系统填充一个MSG结构然后拷贝到消息队列中。
Information in MSG includes: the handle of the window for which the message is intended, the message identifier, the two message parameters, the time the message was posted, and the mouse cursor position.
MSG中的信息包括:该消息的目的窗口,消息标识符,两个消息参数,消息的发布时间,鼠标光标位置。
A thread can post a message to its own message queue or to the queue of another thread by using the PostMessage or PostThreadMessage function.
一个线程可以发送消息到自己的消息队列或通过使用PostMessage或PostThreadMessage函数发送到另一个线程队列。

An application can remove a message from its queue by using the GetMessage function.
应用程序可以使用GetMessage函数从队列中删除消息。
To examine a message without removing it from its queue, an application can use the PeekMessage function.
审查而不从队列中取出消息,应用程序可以使用PeekMessage函数。
This function fills MSG with information about the message.
此功能与有关消息的信息填充MSG。

After removing a message from its queue, an application can use the DispatchMessage function to direct the system to send the message to a window procedure for processing.
从队列中删除的消息后,应用程序可以使用DispatchMessage函数指挥系统消息发送到窗口过程进行处理。
DispatchMessage takes a pointer to MSG that was filled by a previous call to the GetMessage or PeekMessage function.
DispatchMessage函数需要MSG指针,首先利用GetMessage或PeekMessage函数填充MSG结构。
DispatchMessage passes the window handle, the message identifier, and the two message parameters to the window procedure, but it does not pass the time the message was posted or mouse cursor position.
DispatchMessage函数传递窗口句柄,消息标识符和两个消息参数传递到窗口过程,但它并不传递消息的发布时间或鼠标光标的位置。
An application can retrieve this information by calling the GetMessageTime and GetMessagePos functions while processing a message.
应用程序可以在处理消息是利用GetMessageTime和GetMessagePos函数检索这些信息。
A thread can use the WaitMessage function to yield control to other threads when it has no messages in its message queue.
一个线程可以在没有消息在消息队列中时使用WaitMessage函数将控制权交给其他线程。
The function suspends the thread and does not return until a new message is placed in the thread's message queue.
函数挂起线程,并不返回,直到一个新的消息放置在线程的消息队列。
You can call the SetMessageExtraInfo function to associate a value with the current thread's message queue.
可以调用SetMessageExtraInfo函数联系当前线程的消息队列中的一个值。
Then call the GetMessageExtraInfo function to get the value associated with the last message retrieved by the GetMessage or PeekMessage function.
然后调用GetMessageExtraInfo的功能得到的最后一条消息由GetMessage或PeekMessage函数检索相关的值。
Nonqueued Messages
Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue.
Nonqueued消息立即发送到目标窗口过程,绕过系统消息队列和线程消息队列。
The system typically sends nonqueued messages to notify a window of events that affect it.
系统发送nonqueued消息,通知一个窗口事件影响。
For example, when the user activates a new application window, the system sends the window a series of messages, including WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR.
例如,当用户启动一个新的应用程序窗口,系统发送一系列的消息,包括WM_ACTIVATE,WM_SETFOCUS,WM_SETCURSOR消息,窗口。
These messages notify the window that it has been activated, that keyboard input is being directed to the window, and that the mouse cursor has been moved within the borders of the window.
这些消息通知窗口,它已被激活,正在向窗口,键盘输入,鼠标光标已在窗口的边界内移动。
Nonqueued messages can also result when an application calls certain system functions. For example, the system sends the WM_WINDOWPOSCHANGED message after an application uses the SetWindowPos function to move a window.
Nonqueued的消息也导致当应用程序调用某些系统功能。例如,系统发送WM_WINDOWPOSCHANGED的消息后,应用程序使用SetWindowPos函数移动窗口。
Some functions that send nonqueued messages are BroadcastSystemMessage, BroadcastSystemMessageEx, SendMessage, SendMessageTimeout, and SendNotifyMessage.
发送nonqueued消息的某些功能是BroadcastSystemMessage,BroadcastSystemMessageEx的话,SendMessage,SendMessageTimeout,并SendNotifyMessage。

Message Handling
消息处理
An application must remove and process messages posted to the message queues of its threads.
应用程序必须清除和处理发送到线程消息队列的消息。
A single-threaded application usually uses a message loop in its WinMain function to remove and send messages to the appropriate window procedures for processing.
一个单线程的应用程序通常使用一个消息循环,在WinMain函数,删除和发送邮件到相应的窗口处理程序。
Applications with multiple threads can include a message loop in each thread that creates a window.
多线程的应用程序可以包括在每个线程创建一个窗口的消息循环。

The following sections describe how a message loop works and explain the role of a window procedure:
以下各节描述一个消息循环是如何工作的,并解释了窗口过程中的作用:
Message Loop
消息循环
Window Procedure
窗口过程

Message Loop
A simple message loop consists of one function call to each of these three functions: GetMessage, TranslateMessage, and DispatchMessage.
一个简单的消息循环包含一个函数调用这三个功能:GetMessage函数,TranslateMessage和DispatchMessage。
Note that if there is an error, GetMessage returns -1 -- thus the need for the special testing.
请注意,如果有一个错误,GetMessage函数返回-1  - 因此需要特殊的测试。

Show Example

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);
    }
}
The GetMessage function retrieves a message from the queue and copies it to a structure of type MSG.
GetMessage函数从队列中检索消息,并将其复制到MSG类型的结构。
It returns a nonzero value, unless it encounters the WM_QUIT message, in which case it returns FALSE and ends the loop.
它返回一个非零值,除非遇到WM_QUIT消息,在这种情况下,它返回FALSE并结束循环。
In a single-threaded application, ending the message loop is often the first step in closing the application.
在单线程应用程序,结束消息循环,往往是在关闭应用程序的第一步。
An application can end its own loop by using the PostQuitMessage function, typically in response to the WM_DESTROY message in the window procedure of the application's main window.
应用程序可以使用PostQuitMessage函数,通常在回应WM_DESTROY消息在应用程序的主窗口的窗口过程结束自己的循环。
If you specify a window handle as the second parameter of GetMessage, only messages for the specified window are retrieved from the queue.
如果你指定一个窗口句柄作为第二个参数,GetMessage函数,只有指定的窗口消息从队列中检索。
GetMessage can also filter messages in the queue, retrieving only those messages that fall within a specified range.
GetMessage函数也可以过滤队列中的消息,仅检索属于指定范围内的这些消息。
For more information about filtering messages, see Message Filtering.
关于过滤消息的更多信息,请参阅邮件筛选。

A thread's message loop must include TranslateMessage if the thread is to receive character input from the keyboard.
一个线程的消息循环必须包括TranslateMessage如果该线程需要从键盘接收输入的字符。
The system generates virtual-key messages (WM_KEYDOWN and WM_KEYUP) each time the user presses a key.
该系统生成的虚拟键消息(WM_KEYDOWN和WM_KEYUP)每次用户按下一个键。
A virtual-key message contains a virtual-key code that identifies which key was pressed, but not its character value.
虚拟键消息包含虚拟键代码标识哪个键被按下,而不是它的字符值。
To retrieve this value, the message loop must contain TranslateMessage, which translates the virtual-key message into a character message (WM_CHAR) and places it back into the application message queue.
检索此值,消息循环必须包括TranslateMessage转换成字符消息(WM_CHAR消息)的虚拟键的消息,并放入应用程序的消息队列。
The character message can then be removed upon a subsequent iteration of the message loop and dispatched to a window procedure.
随后的消息循环迭代后可以删除字符消息,并派遣到窗口过程。

The DispatchMessage function sends a message to the window procedure associated with the window handle specified in the MSG structure.
DispatchMessage函数发送一个消息到窗口过程处理MSG结构中指定的窗口。
If the window handle is HWND_TOPMOST, DispatchMessage sends the message to the window procedures of all top-level windows in the system.
如果窗口句柄是HWND_TOPMOST,DispatchMessage函数将消息发送到系统中的所有顶层窗口的窗口过程。
If the window handle is NULL, DispatchMessage does nothing with the message.
如果窗口句柄是NULL,DispatchMessage函数不做任何处理。

An application's main thread starts its message loop after initializing the application and creating at least one window.
应用程序的主线程启动后初始化应用程序和创建至少一个窗口的消息循环。
Once started, the message loop continues to retrieve messages from the thread's message queue and to dispatch them to the appropriate windows.
一旦启动,消息循环持续从线程的消息队列中检索消息,并派遣他们到相应的窗口。
The message loop ends when the GetMessage function removes the WM_QUIT message from the message queue.
消息循环结束时,GetMessage函数从消息队列中删除WM_QUIT消息。

Only one message loop is needed for a message queue, even if an application contains many windows.
只有一个消息循环需要一个消息队列,即使应用程序包含很多窗口。
DispatchMessage always dispatches the message to the proper window;
DispatchMessage函数总是分派到适当的窗口的消息;
this is because each message in the queue is an MSG structure that contains the handle of the window to which the message belongs.
这是因为每个队列中的消息是一个MSG结构包含该消息所属的窗口句柄。

You can modify a message loop in a variety of ways.
你可以在各种不同的方式修改消息循环。
For example, you can retrieve messages from the queue without dispatching them to a window.
例如,你可以从队列中检索消息但不派遣他们到一个窗口,
This is useful for applications that post messages not specifying a window.
这是该职位的消息不指定一个窗口的应用程序非常有用。
You can also direct GetMessage to search for specific messages, leaving other messages in the queue.
也可以直接GetMessage函数来搜索特定的消息,留在队列中的其他消息。
This is useful if you must temporarily bypass the usual FIFO order of the message queue.
这是有用的,如果你必须暂时绕过通常的消息队列FIFO顺序。

An application that uses accelerator keys must be able to translate keyboard messages into command messages.
使用快捷键的应用程序必须能够转化为命令消息键盘消息。
To do this, the application's message loop must include a call to the TranslateAccelerator function.
要做到这一点,应用程序的消息循环必须包括TranslateAccelerator函数的调用。
For more information about accelerator keys, see Keyboard Accelerators.
如需更多关于快捷键的详细信息,请参阅键盘加速器。

If a thread uses a modeless dialog box, the message loop must include the IsDialogMessage function so that the dialog box can receive keyboard input.
如果一个线程使用一个无模式对话框,消息循环必须包括IsDialogMessage函数使对话框可以接收键盘输入。

Window Procedure
窗口过程
A window procedure is a function that receives and processes all messages sent to the window.
窗口过程是一个函数,接收和处理所有发送到窗口的消息。
Every window class has a window procedure, and every window created with that class uses that same window procedure to respond to messages.
每个窗口类都有一个窗口过程,并用这个类创建的每个窗口使用同一窗口过程响应消息。

The system sends a message to a window procedure by passing the message data as arguments to the procedure.
作为过程的参数的信息数据通过系统发送一条消息到窗口过程。
The window procedure then performs an appropriate action for the message;
然后窗口过程对消息进行适当的处理;
it checks the message identifier and, while processing the message, uses the information specified by the message parameters.
它检查消息标识符,并在处理消息时,使用的消息参数指定的信息。
A window procedure does not usually ignore a message.
一个窗口过程通常不忽略消息。
If it does not process a message, it must send the message back to the system for default processing.
如果不处理的消息,它必须将消息发送回系统默认处理。
The window procedure does this by calling the DefWindowProc function, which performs a default action and returns a message result.
窗口过程通过调用DefWindowProc函数,它执行的默认操作,并返回一个消息结果。
The window procedure must then return this value as its own message result.
窗口过程,然后返回这个值作为它自己的消息的结果。
Most window procedures process just a few messages and pass the others on to the system by calling DefWindowProc.
大多数窗口程序处理短短的消息和其他传递到系统调用DefWindowProc函数。

Because a window procedure is shared by all windows belonging to the same class, it can process messages for several different windows.
因为属于同一类的所有窗口共享一个窗口过程,它可以处理几个不同的窗口消息。
To identify the specific window affected by the message, a window procedure can examine the window handle passed with a message.
受该消息影响,以确定特定的窗口,窗口过程可以检查与信息传递的窗口句柄。
For more information about window procedures, see Window Procedures.
关于窗口程序的更多信息,请参见窗口程序。

Message Filtering
消息过滤
An application can choose specific messages to retrieve from the message queue (while ignoring other messages) by using the GetMessage or PeekMessage function to specify a message filter.
应用程序可以选择特定的消息,从消息队列中检索(而忽略其他消息)通过GetMessage或PeekMessage函数指定一个消息过滤器。
The filter is a range of message identifiers (specified by a first and last identifier), a window handle, or both.
该过滤器是一个消息标识符(第一个和最后一个标识符指定),一个窗口句柄,或两者兼而有之的范围。
GetMessage and PeekMessage use a message filter to select which messages to retrieve from the queue.
GetMessage和PeekMessage的使用消息筛选器选择从队列中检索消息。
Message filtering is useful if an application must search the message queue for messages that have arrived later in the queue.
信息过滤是非常有用的,如果一个应用程序必须寻找消息队列的队列中后,已经抵达的消息。
It is also useful if an application must process input (hardware) messages before processing posted messages.
它也是有用的,如果一个应用程序必须处理输入(硬件)消息,前处理发布的消息。
The WM_KEYFIRST and WM_KEYLAST constants can be used as filter values to retrieve all keyboard messages;
作为过滤值的WM_KEYFIRST和WM_KEYLAST常量可用于检索所有的键盘消息;
the WM_MOUSEFIRST and WM_MOUSELAST constants can be used to retrieve all mouse messages.
WM_MOUSEFIRST和WM_MOUSELAST常数可以用来检索所有的鼠标消息。

Any application that filters messages must ensure that a message satisfying the message filter can be posted.
必须确保满足邮件过滤器的消息可以发布任何应用程序过滤器的消息。
For example, if an application filters for a WM_CHAR message in a window that does not receive keyboard input, the GetMessage function does not return. This effectively "hangs" the application.
例如,如果在一个窗口WM_CHAR消息,不接收键盘输入的应用程序过滤器,GetMessage函数不返回。这将有效地“挂起”的应用。

Posting and Sending Messages
抛出和发送邮件
Any application can post and send messages.
任何应用都可以张贴和发送邮件。
Like the system, an application posts a message by copying it to a message queue and sends a message by passing the message data as arguments to a window procedure.
像系统,应用程序复制到一个消息队列和消息发送的消息数据作为参数传递到一个窗口过程的消息。
To post messages, an application uses the PostMessage function. An application can send a message by calling the SendMessage, BroadcastSystemMessage, SendMessageCallback, SendMessageTimeout, SendNotifyMessage, or SendDlgItemMessage function.
发布消息,应用程序使用PostMessage函数。应用程序可以通过调用SendMessage函数,BroadcastSystemMessage,SendMessageCallback,SendMessageTimeout,SendNotifyMessage,或子控件功能发送邮件。

Posting Messages
An application typically posts a message to notify a specific window to perform a task.
一个应用程序通常消息通知一个特定的窗口来执行任务。
PostMessage creates an MSG structure for the message and copies the message to the message queue. The application's message loop eventually retrieves the message and dispatches it to the appropriate window procedure.
PostMessage的创建了一个消息的MSG结构的消息复制到消息队列。最终的应用程序的消息循环检索的消息,并分派到相应的窗口过程。

An application can post a message without specifying a window.
应用程序可以发布消息,没有指定一个窗口。
If the application supplies a NULL window handle when calling PostMessage, the message is posted to the queue associated with the current thread.
如果应用程序利用PostMessage发送了一个窗口句柄为空的消息,该消息江北发送到单签线程所属的队列。
Because no window handle is specified, the application must process the message in the message loop.
因为没有指定的窗口句柄,应用程序必须处理的消息,在消息循环。
This is one way to create a message that applies to the entire application, instead of to a specific window.
这是一个方法来创建适用于整个应用程序的消息,而不是一个特定的窗口。

Occasionally, you may want to post a message to all top-level windows in the system.
有时,您可能要发布的消息系统中的所有顶层窗口。
An application can post a message to all top-level windows by calling PostMessage and specifying HWND_TOPMOST in the hwnd parameter.
应用程序可以通过调用PostMessage的和指定的hwnd参数HWND_TOPMOST发表的所有顶层窗口发送消息。
A common programming error is to assume that the PostMessage function always posts a message.
一个常见的编程错误是假设PostMessage函数总是成功post一个消息。
This is not true when the message queue is full.
这是不正确的,当消息队列已满。
An application should check the return value of the PostMessage function to determine whether the message has been posted and, if it has not been, repost it.
应用程序应该检查,以确定是否已发布消息的PostMessage函数的返回值,如果它一直没有,重新发送。

Sending Messages
发送消息
An application typically sends a message to notify a window procedure to perform a task immediately.
通常一个应用程序发送消息,通知窗口过程立即执行任务。
The SendMessage function sends the message to the window procedure corresponding to the given window.
SendMessage函数将消息发送到窗口过程,对应给定的窗口。
The function waits until the window procedure completes processing and then returns the message result.
函数等待,直到窗口过程完成处理,然后返回消息的结果。
Parent and child windows often communicate by sending messages to each other.
父母与子女的窗户经常通过发送消息互相沟通。
For example, a parent window that has an edit control as its child window can set the text of the control by sending a message to it.
例如,有编辑控件作为其子窗口的父窗口可以通过发送消息设置控件的文本。
The control can notify the parent window of changes to the text that are carried out by the user by sending messages back to the parent.
控件可以通过发送消息通知父窗口文本被用户更改了。

The SendMessageCallback function also sends a message to the window procedure corresponding to the given window.
SendMessageCallback功能也相应给定的窗口的窗口过程发送消息。
However, this function returns immediately.
然而,这个函数立即返回。
After the window procedure processes the message, the system calls the specified callback function.
窗口过程处理消息后,系统调用指定的回调函数。
For more information about the callback function, see the SendAsyncProc function.
关于回调函数的更多信息,看到SendAsyncProc的功能。

Occasionally, you may want to send a message to all top-level windows in the system.
有时,您可能希望将消息发送到系统中的所有顶层窗口。
For example, if the application changes the system time, it must notify all top-level windows about the change by sending a WM_TIMECHANGE message.
例如,如果应用程序改变了系统时间,它必须通过发送WM_TIMECHANGE消息通知有关改变所有的顶层窗口。
An application can send a message to all top-level windows by calling SendMessage and specifying HWND_TOPMOST in the hwnd parameter.
应用程序可以将消息发送给所有的顶层窗口调用SendMessage和HWND_TOPMOST在hwnd参数指定。
You can also broadcast a message to all applications by calling the BroadcastSystemMessage function and specifying BSM_APPLICATIONS in the lpdwRecipients parameter.
您还可以广播消息到所有应用程序,通过调用BroadcastSystemMessage功能,并指定在lpdwRecipients参数BSM_APPLICATIONS。

By using the InSendMessage or InSendMessageEx function, a window procedure can determine whether it is processing a message sent by another thread.
通过使用InSendMessage或InSendMessageEx功能,窗口过程可以判断,无论是处理由另一个线程发送消息。
This capability is useful when message processing depends on the origin of the message.
这种能力是非常有用的,当消息处理消息来源的依赖。

Message Deadlocks
消息死锁
A thread that calls the SendMessage function to send a message to another thread cannot continue executing until the window procedure that receives the message returns.
一个线程调用SendMessage函数发送消息到另一个线程不能继续执行,直到窗口过程收到的消息返回。
If the receiving thread yields control while processing the message, the sending thread cannot continue executing, because it is waiting for SendMessage to return.
如果接收线程产量控制在处理消息时,发送线程不能继续执行,因为它正在等待SendMessage函数返回。
If the receiving thread is attached to the same queue as the sender, it can cause an application deadlock to occur. (Note that journal hooks attach threads to the same queue.)
如果接收线程连接到相同的队列作为发件人,它可能会导致应用程序发生死锁。 (请注意,期刊挂钩线程附加到相同的队列。)
Note that the receiving thread need not yield control explicitly; calling any of the following functions can cause a thread to yield control implicitly.
请注意,接收线程不需要明确的产量控制;调用任何以下功能可以导致线程隐产量控制。

DialogBox
DialogBoxIndirect
DialogBoxIndirectParam
DialogBoxParam
GetMessage
MessageBox
PeekMessage
SendMessage

To avoid potential deadlocks in your application, consider using the SendNotifyMessage or SendMessageTimeout functions.
在您的应用程序,以避免潜在的死锁,可以考虑使用的SendNotifyMessage或SendMessageTimeout功能。
Otherwise, a window procedure can determine whether a message it has received was sent by another thread by calling the InSendMessage or InSendMessageEx function.
否则,一个窗口过程可以判断是否已收到的消息是由另一个线程发出呼吁的InSendMessage或InSendMessageEx功能。
Before calling any of the functions in the preceding list while processing a message, the window procedure should first call InSendMessage or InSendMessageEx.
窗口过程调用任何在上述列表中的功能,同时处理消息之前,应首先调用InSendMessage或InSendMessageEx。
If this function returns TRUE, the window procedure must call the ReplyMessage function before any function that causes the thread to yield control.
如果这个函数返回TRUE,窗口过程之前必须调用任何功能,导致线程产量控制ReplyMessage功能。
Broadcasting Messages
广播消息
Each message consists of a message identifier and two parameters, wParam and lParam.
每个消息包含一个消息标识符和两个参数,wParam和lParam。
The message identifier is a unique value that specifies the message purpose.
消息标识符是一个唯一的值指定消息的目的。
The parameters provide additional information that is message-specific, but the wParam parameter is generally a type value that provides more information about the message.
参数提供更多的信息,是具体的消息,但是wParam参数通常是一个类型的值,提供有关该消息的更多信息。

A message broadcast is simply the sending of a message to multiple recipients in the system.
一个消息广播是简单的消息发送到系统中的多个收件人。
To broadcast a message from an application, use the BroadcastSystemMessage function, specifying the recipients of the message.
广播消息从一个应用程序,使用BroadcastSystemMessage功能,指定邮件的收件人。
Rather than specify individual recipients, you must specify one or more types of recipients.
而非指定个别受助人,你必须指定一个或多个类别的受助人。
These types are applications, installable drivers, network drivers, and system-level device drivers. The system sends broadcast messages to all members of each specified type.
这些类型的应用程序,安装驱动程序,网络驱动程序,系统级设备驱动程序。系统广播消息发送到各指定类型的所有成员。

The system typically broadcasts messages in response to changes that take place within system-level device drivers or related components.
该系统通常广播系统级设备驱动程序或相关组件内发生的变化,采取响应的消息。
The driver or related component broadcasts the message to applications and other components to notify them of the change.
驱动程序或相关组件广播消息,通知应用程序和其他组件的变化。
For example, the component responsible for disk drives broadcasts a message whenever the device driver for the floppy disk drive detects a change of media such as when the user inserts a disk in the drive.
例如,负责磁盘驱动器组件广播消息时的软盘驱动器设备驱动程序的检测,如当用户插入一个磁盘驱动器中的媒体的变化。

The system broadcasts messages to recipients in this order: system-level device drivers, network drivers, installable drivers, and applications.
系统广播消息来领取这个顺序:系统级设备驱动程序,网络驱动程序,安装驱动程序和应用程序。
This means that system-level device drivers, if chosen as recipients, always get the first opportunity to respond to a message.
这意味着,系统级设备驱动程序,如果选择为受助人,总是得到响应消息的第一个机会。
Within a given recipient type, no driver is guaranteed to receive a given message before any other driver.
在一个特定的收件人类型,没有驱动程序保证收到任何其他的驱动程序之前给定的消息。
This means that a message intended for a specific driver must have a globally-unique message identifier so that no other driver unintentionally processes it.
这意味着,用于特定的驱动程序的消息必须有一个全球唯一的消息标识符,所以没有其他的驱动程序无意对其进行处理。

You can also broadcast messages to all top-level windows by specifying HWND_BROADCAST in the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function.
您还可以向所有顶层窗口广播消息指定HWND_BROADCAST在SendMessage,SendMessageCallback,SendMessageTimeout,或SendNotifyMessage功能。

Applications receive messages through the window procedure of their top-level windows.
应用程序收到消息,通过他们的顶层窗口的窗口过程。
Messages are not sent to child windows. Services can receive messages through a window procedure or their service control handlers.
消息不发送到子窗口。服务可以通过一个窗口程序或服务控制处理程序收到的消息。

Note  System-level device drivers use a related, system-level function to broadcast system messages.
注意:系统级设备驱动程序使用一个相关的,系统级的功能,广播系统消息。

Query Messages
查询消息
You can create your own custom messages and use them to coordinate activities between your applications and other components in the system.
你可以创建自己的自定义消息,并用它们来协调您的应用程序和系统中的其他组件之间的活动。
This is especially useful if you have created your own installable drivers or system-level device drivers.
如果您已经创建了你自己安装的驱动程序或系统级设备驱动程序,这是特别有用。
Your custom messages can carry information to and from your driver and the applications that use the driver.
你的自定义消息可以携带信息,从您的驱动程序和驱动程序的应用程序使用。

To poll recipients for permission to carry out a given action, use a query message. You can generate your own query messages by setting the BSF_QUERY value in the dwFlags parameter when calling BroadcastSystemMessage.
轮询收件人开展一个给定的行动的权限,使用一个查询信息。通过设置dwFlags参数BSF_QUERY值调用BroadcastSystemMessage时,您可以生成自己的查询信息。
Each recipient of the query message must return TRUE for the function to send the message to the next recipient.
每个查询消息的收件人必须为函数返回TRUE,消息发送到下一个收件人。
If any recipient returns BROADCAST_QUERY_DENY, the broadcast ends immediately and the function returns a zero.
如果任何收件人返回BROADCAST_QUERY_DENY,广播立即结束该函数返回一个零。

Windows 95/98/Me: You can create installable drivers that broadcast and process messages. An installable driver is a DLL that exports a DriverProc function. The driver receives messages through its DriverProc function and can broadcast messages using BroadcastSystemMessage. Installable drivers are typically used to support multimedia devices, such as sound boards, but can be used for other devices and purposes too.
在Windows 95/98/Me:您可以创建安装驱动程序,广播和处理消息。安装的驱动程序是一个DLL出口DriverProc的功能。驱动程序收到消息通过其DriverProc功能,可以使用BroadcastSystemMessage广播消息。安装驱动程序通常用于支持多媒体设备,如音响板,但可用于其他设备和目的。

Windows 95/98/Me: Network drivers are DLLs that provide the underlying support for applications that use the network functions to connect to and browse network resources. System-level device drivers are system-specific executable components that provide direct access to and management of the hardware devices of the computer. The details regarding how these components process system messages is beyond the scope of this overview.
在Windows 95/98/Me:网络驱动程序的DLL,使用网络功能连接到并浏览网络资源的应用提供底层支持。系统级设备驱动程序提供直接访问和管理计算机硬件设备的系统特定的可执行组件。关于这些组件如何处理系统消息的细节超出了本概述的范围。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值