Determine GetMessage and Peekmessage

zhaozj2021-02-08  414

Determine GetMessage and Peekmessage

Bob Gunderson

MSDN Technical Group

Take: November 11, 1992

CreAmdog

Translated to: March 13, 2002

Translator's words

This article focuses on Windows handling events, messages and steps. Especially in the process of typing the system of mouse keyboard events. Through this article, you will have a more comprehensive understanding of Windows messaging mechanism.

concept

This article explains the internal operation of GetMessage and PeekMessage, and it is also the basis for the related articles of "Messages and Messages under the 16-bit MS-DOS? / Microsoft® Windows® environment". We will discuss the following topics:

· System and application queue (Translator Note: The following is "program queue")

· GetMessage and PeekMessage functions

· Message filtering

· Wm_quit message

· Concession and sleep

·

Waitmessage

The 16-bit MS-DOS / Windows environment and 32-bit Win32? / Windows NT • The environment is important and different. Although these differences are not overlooked here, we still use them as legacy issues, explained by future articles.

queue

To understand the operation of GetMessage and PeekMessage, you must first understand how Microsoft? Windows? How to store events and messages in the operating system. There are two types of queues in Windows to work as this destination, which are system queues and messages.

Hardware input: System queue

Windows has some drivers that are responsible for the interrupt service from hardware from the keyboard and mouse. In the interrupt time, the keyboard and mouse driver call some of the entry points specified in USER.EXE to report an event. These entry points are also called in the original optical pen event in Windows.

In Windows3.1, the system queue is a queue with 120 entrance space. These "small rooms" are sufficient in the general case, but if the application hangs or does not timely handle any messages in a long time, it may cause the system queue to be filled. If you really happen, any new events that try to add to the system will cause system beep. (Translator Note: In DOS, if a program takes up all system resources for a while, make the machine unable to respond, then if you hold a button, you will hear the chassis speaker. )

Sended messages and program queues

A queue will be created when an application starts. The program queue (sometimes referred to as a task queue) is often used to store a message "a window being sent to the application". The message of the unique resident program is those who have explicitly sent by PostMessage or PostAppMessage. (SendMessage never uses the system queue) PostquitMessage function does not send a message to the program queue. (WM_QUIT news will be discussed below)

By default, each program queue can keep eight messages. Under normal circumstances, this is quite sufficient because postmessage is rarely used. But if an application tries to force a lot of PostMessage to an application, such applications will use the setMessageQueue function to increase the length of the message queue. You must be careful to use the SetMessageQueue function, because you will remove the current program queue whenever you first delete the current queue, and create a new queue that is expected. At this time, any messages in the old queue will be destroyed. Therefore, it must be called before all other application programming interfaces (APIs) in your Winmain routine, or after the application is called with PeekMessage.

How does GetMessage and PeekMessage work in Windows, GetMessage and PeekMessage perform the same code. And the biggest difference between the two is reflected in the case where no messages returns to the application. In this case, PeekMessage returns an empty value to the application, and GetMessage will sleep at this time. There are still some other differences between them, we will discuss it below, but they are quite necessary.

GetMessage and PeekMessage logic

The following steps describe the GetMessage and PeekMessage utility code in Windows 3.1.

Tip: The steps below are sorted in accordance with the priority of the message type. For example, the message sent is always returned before the keyboard and the mouse message, and the keyboard and the mouse will be reversed before the Paint message, and so on.

1. Check if there is a message in the program queue for the "Task" service service. If so, first delete this message in the team and return it to the application. Then, getMessage and PeekMessage in the application call some code to receive this message from the program queue, which is generated by the dynamic link library (DLL) called by the application. Remember, only messages sent by PostMessage will often stay in this queue.

2. Check this message with all messages and form handle filters. If this message does not match the specified filter, leave this message in the program queue. If there are other messages behind this message in the queue, it turns to the processing of the next message.

3. If there is no message in the program queue, the events in the system queue are scanned. This process is quite complex, and we will be in the "Scan System Query" section below. Generally speaking, the event in the system queue is for this application, and the system is converted into a message and returns the message into this application (it will not be placed in the application queue). Note that the process of this scanning system queue may cause the current active application to control the right to other applications.

4. If there is no waiting event in the system queue, verify all forms related to the current application (task) to determine the update area. When a part of a form needs to be redrawged, an update area is created above that form part. This area combines all updated areas in this form and stores in the internal form structure. If GetMessage or PeekMessage found that some forms have some unprocessed update areas, a WM_PAINT message will be generated and returned to the application. WM_PAINT never resides in any queue. At this point, an application will continue to receive a WM_PATIN message for a form until the update area is cleared by beginpaint / endpaint, validaterect, or validatergn.

5. If there is no form in this task that needs to be updated, getMessage and PeekMessage will give this control, unless the PeekMessage call is set to the PM_Noyield property.

6. When returning, check if there is a timer expiration in the current task. If so, create a WM_TIMER message and return. It not only happens on the timer that returns a WM_TIMER message to the form, but also occurs on the timer that calls a timer processing process. To learn more, please see the article in Microsoft Developer Network (MSDN) CD (including technical articles, windows articles, core and driver articles "Timers and Timing in Microsoft Windows" (Translator Note: If the reader Ability to recognize my job, I will spare no effort to translate this article about the timer). 7. If the application does not have a timer event service, and an application is being terminated, the code will try to reduce the local memory of the graphics device interface (GDI). Some applications, such as drawing applications (like PaintBrush?), Allocated a lot of stack of memory for GDI. When these objects are released when the application is terminated, the GDI local memory stack is filled with idle space. In order to restore these idle spaces, in GetMessage / PeekMessage processing, Localshrink will be called in the GDI memory in this point. This is completed once, (each) an application will terminate.

8. At this moment, the code will be bifurcated to two roads. First, the code is arbitrarily returned to a valid message, and the other is the message, event, and the code will eventually go. Determine which one of PeekMessage and GetMessage is called.

PEEKMESSAGE. If PeekMessage is called, and set the PM_NOYIELD tag, PeekMessage returns an null value at the moment, and this empty return value indicates that there is no message to be processed. If the PM_NOYIELD tag is not set, PeekMessage will give the control right at this moment. It won't sleep, but it will be single to other opportunities for other ready-to-have applications. (See "Concession and Sleep Different) When the step returns, PeekMessage directly returns control to the application, and returns an null value, which indicates that the application does not have to handle.

At this moment, getMessage will make the application sleep, wait until some events need to wake up the application. Control will not return to the application that calls getMessage until the application that the application must deal with. Once this application is in a sleep state, the cycle inside the getMessage will return to the beginning (step 1).

Wh_getiment measure

Before getMessage and PeekMessage returns a message to the called application, it is a test that verifies whether there is a WH_GetMessage hook. If there is a already installed, the hook will be called. This hook will not be called if PeekMessage does not discover the available messages and return an null value. In the hook processing, you can't learn that it is a getMessage called or peekMessage is called.

Scanning system queue

In summary, events in the system queue are only a record of hardware events. The main task of those code scanning system queues is to create messages from these events and determine which form will receive this message.

When the code first finds an event in the system queue first, it will not be removed immediately. Because the mouse and keyboard events are just two events in the queue, the code will be branched (the translator Note: Similar to the Switch statement in the C language) and handles each type of event separately. Handling mouse events in the system queue

Below is the step of handling the mouse event.

1. First, the corresponding form of the event screen coordinates will be calculated. This calculation (calling form Click Test) starts with desktop form, scan each form (including sub-form) from head to the tail, until a form containing this mouse coordinate point, and this window There are no sub-forms that contain this coordinate point.

Figure 2. Forms of mouse event Click Test

For example: If the arrow in Figure 2 represents the current mouse position, any mouse behavior, like a mouse button, will generate an event that generates messages in the B form.

2. If a form is captured using setCapture, the System Queen Scanning code will be tested by a normal click to returns all mouse messages to the captured form. For example, if setCapture is called in the A form in FIG. 2, all mouse behaviors in the position indicated by the arrow will generate the message in Form A, not form B.

3. If this is processed is a "mouse button" event (any mouse button), the code will detect whether the event will be converted to double-click event. You can find a description of the dual-click transformation in "Ask Dr. GUI # 5" in Microsoft Developer Network (Translator Note: MSDN) CD (Technical Articles, Ask Dr. GUI). In essence, if the increment of the time and distance is in the allowable range, the event will generate a double-click message in the allowable range, otherwise it will generate a standard "Press" event. All mouse events will generate a standard mouse message, and double-click the test only in the mouse event, which contains the CS_DBLCLKS type.

4. A message is constructed from a mouse event.

5. If the mouse click test to determine that the event occurs in a form of non-client, such as a border or title bar, then the constructed message is mapped to its corresponding non-client message. For example: a WM_MOUSEMOVE event is encompassed as a WM_NCMOUSEMOVE message.

6. Check this message with all the specified message filters. (See "Message Range Filtering and Filter Filter" below) If the message does not match the filter, you will be re-started to start the System Queen Scan code to see the next message in the queue.

7. If the mouse message needs to travel to another task than the current task, the event is left in the system queue, and if the task that will handle the message is in sleep, it will be awakened. This newly awakened task will not run immediately at this moment, will only mark it as ready. If the message goes to other tasks and does not have the event to be processed in the system queue, the System Queen Scan will return to the getMessage / PeekMessage primary code. Please refer to "Unlike Sleep Different" to get more information.

8. If the mouse hook is installed, it will be called at this moment. If the mouse hook returns a non-zero value, the mouse event is ignored and deleted from the system queue and then starts "System Queen Scan" code from the head. If the hook returns zero, continue processing.

9. If the message is a "mouse button" message, "System Queen Scan" will activate the form as follows before returning this message.

It is always looking for the "final top parent" of the form along the parent chain until it meets. It uses SendMessage to send a WM_MouseActivate message to the "final top parent" of the form.

• The value returned from WM_MouseActvate will be tested below:

a) If the returned value is empty, ma_activate or ma_activateAndeat, the ActivateWindow function will be called to activate the "final top parent".

b) If the returned value is MA_NOACTIVATE or MA_NOACTIVATEANDEAT, the form is not activated.

Note: MA_ACTIVATEANDEAT and MA_NOACTIVATEANDEAT will cause the "Mouse Key Press" Event from the system queue to be deleted, without generating a mouse presses the message.

c) Finally, a WM_SETCURSOR message is sent to the form, allowing the form of the form to set the outline of the pointer.

10. If the mouse hook is called, and the current mouse event is deleted from the system queue, the "computer training" (CBT) is checked. If there is a CBT hook installed, it will bring the HCBT_CLICKSKIPPED hook code to call it.

11. The button status table contains three portions for tracking the status of the mouse button. These buttons are assigned to virtual key code (vk_lbutton, vk_rutton, and vc_mbutton), and they and getKeyState use to deactivate the mouse button or press. Before returning to the mouse message, the System Queen Scanning code will set the button status table and remove the message from the system queue from the system queue. If PeekMessage is called, the PM_NOREMOVE is pulled, the button status table will not be modified.

Handling keyboard events in the system queue

1. Check if the CTRL button is pressed and the current event is the ESC key. If yes, the user-Direct Form-Displays the task manager form. A WM_SYSCOMMAND message will be sent to the activated form, and the parameter wparam is SC_Tasklit. Then the keyboard is removed from the system queue, and the System Queen Scanning code will start again. If this activated form is a system module or a "hard" system module message box (such as an "int" 24-hour system error message box, or a MessageBox function using MB_ICONHAND and MB_SYSTEMMODAL parameters) Will be discarded.

2. Next, try to see the current event is not a print screen key to press the event. If so, any activated form or the entire desktop will be made as a bitmap snapshot, saved to the clipboard. If the ALT key is pressed, an image of an activation form is copied into the clipboard; if not, the entire desktop is copied. The Print Screen button is then pressed from the system queue, and the System Queen Scanning code will re-start. If a "hard" system module message box is displayed, this operation is ignored.

3. The next step is detected. Using the program manager, the user can define the key event used to run an application. These keystrokes are called hotkeys. If the current event is a button event, it will be tested to match the defined hotkey. If you find a match, a WM_SYSCOMMAND message will be sent to the activated form, and the parameter wparam is SC_HOTKEY. Then the keyboard is removed from the system queue, and the System Queen Scanning code will start again. If this activated form is a system module or a "hard" system module message box that is displayed, the test is skipped.

4. In general, all keyboard messages (such as WM_KeyDown, WM_CHAR, etc.) go to a form with input focus. If this form with input focus is associated with another currently executed task, the event is left in the system queue, and the task with "focus-focused form" will be woken up (if you sleep). The System Queen Scanning code will return to the primary getMessage / PeekMessage code like any event to be processed. See "Unlike Sleep Different" and "Application How to Wake" to get more information. 5. If you encounter no form having an input focus, the keyboard message directly towards the currently activated form, without being translated into a system key message (such as WM_SYSKEYDOW, WM_SYSCHAR, etc.).

6. Check this message with all the specified message filters. (See "Message Range Filtering and Filter Filter" below) If the message does not match the filter, you will be re-started to start the System Queen Scan code to see the next message in the queue.

7. If the event is returned to the current task, it will be deleted from the system queue unless PeekMessage is specified as a PM_NOREMOVE tag. See "PeekMessage PM_NOREMOVE tag" below for more information on removing events from the queue.

8. If a keyboard hook is installed, it will be called at this moment. If the event is deleted from the system queue, the hook call will accompany the hc_action property; if the event is not deleted from the system queue, the hook call will have the hc_norem property.

9. If the keyboard hook is called, and the current button event is deleted from the system queue, check the existing CBT hook. If a CBT hook is installed, it will call it and carry the HCBT_KEYSKIPPED hook code.

10. Finally, the message is returned to the primary getMessage / PeekMessage code.

PeekMessage with PM_NOREMOVE

By default, after each message is returned to the application, PeekMessage and GetMessage will remove messages and events from the system queue. However, sometimes an application may need to scan existing messages in the queue and do not delete them. For example, an application is doing some processing processes, which is expected to "one, and the available messages are found as soon as possible."

(Until it, to be continued)

转载请注明原文地址:https://www.9cbs.com/read-492.html

New Post(0)