Windows Messaging Mechanism 1

Source: Internet
Author: User
Tags getmessage

Windows applications typically include Windows, which primarily provide a visual way for users to interact, and windows are always created within a thread. Windows systems manage interactions through messaging mechanisms, messages are sent, saved, processed, and a thread maintains its own set of message queues (messages queue) to maintain exclusivity among threads. The characteristics of the queue are nothing more than FIFO, which can implement an asynchronous demand response process.

PS Common Error Understanding:

1) Each window has its own message queue (I added)

What is the message like?

The message is defined by a struct called MSG, including the window handle (HWND), message ID (UINT), parameters (WPARAM, LPARAM), and so on:

struct msg{    hwnd hwnd;    UINT message;    WPARAM WPARAM;    LPARAM LPARAM;    DWORD time;    Point pt;};

The message ID is the type identifier of the message, defined by the system or application, and the message ID divides the message type. It is also possible to see that the message corresponds to a particular window (window handle). (This is not entirely true, in fact we can send a message to a window, we can also send a message to a thread, at this time, the message is not the corresponding window handle, the handle is empty, to process such a message, must be after getmessage or postmessage, to determine whether the window handle is empty , if it is empty, it is necessary to process the thread message, no further dispatchmessage () to dispatch the message, because the dispatch message function to see the message window handle is empty, directly discard the message, do not distribute, because there is no window process to process the message, so there is no need to distribute "reference 4")

How is the message categorized? What does the prefix mean?

The message ID is just an integer, and the Windows system pre-defines a number of message IDs, separated by different prefixes, such as wm_*,cb_* and so on.

See the following table for details:

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

An application can define its own message, and its value range must be greater than wm_user.

How do I pass any parameters through a message?

The message mechanism of the Windows system contains 2 parameters of the long integer type: WPARAM, LPARAM, which can hold pointers, that is, can point to any content.

The content of the message varies, and the message handler is specially handled according to the type of message, knowing what the parameters are passed.

When a message is passed online range, between threads, the value of the pointer is valid because it is in the same address space. However, the cross-process situation can not directly use pointers, so the Windows system provides Wm_settext, Wm_gettext, Wm_copydata and other messages for special processing, The contents of the pointer are placed in a temporary memory-mapped file (memory-mapped files), through which shared data between threads is implemented.

What is the relationship between Message Queuing and threads? What is the structure of Message Queuing like?

The Windows system itself maintains a unique message queue so that it can be sent to individual threads, which is how it is implemented inside the system.

For threads, however, each thread can have its own message queue, which corresponds to thread one by one. When online Cheng Gang is created, Message Queuing is not created, but the Windows system considers it necessary to create a message queue for the thread when GDI's function calls occur.

Message Queuing is contained in a structure called Threadinfo, with four queues:

Sent message queueposted message queuevisualized Input queuereply message Queue

Multiple queues are maintained because different messages are processed and processed in different order.

Does the thread and window correspond to one by one? If you want two different windows to react differently to a message, but they belong to the same thread, is it possible?

A window is created by a thread, and a thread can create multiple windows. The window can be created by the CreateWindow () function, but only if a registered window class is required (Windows Class), and each window class needs to specify a window handler function at the time of registration (Windows Procedure), a function that is a callback function, is used to process the message. It is possible for a thread to create a window corresponding to a different window class.

Thus, as long as you register multiple window classes, each window can have its own message handler, and at the same time, they belong to the same thread.

How do I send a message?

The message is sent through a function call, more commonly used PostMessage (), SendMessage (), and some post* or send* functions. The caller of the function is the person who sent the message.

What difference does it have? SendMessage () requires the recipient to process the message immediately, and then return after processing is complete. When PostMessage () sends a message to the receiver queue, it returns immediately, and the caller does not know the processing of the message.

Their prototypes are as follows:

LRESULT SendMessage (    hwnd hwnd,     UINT umsg,     WPARAM WPARAM,     LPARAM LPARAM); LRESULT PostMessage (    hwnd hwnd,     UINT umsg,     WPARAM WPARAM,     LPARAM LPARAM);

SendMessage () requires immediate processing, so it directly invokes the window's message handler (Windows Procedure) and returns the processing result when completed.

However, this is limited to the case within the thread, which cannot be set to a handler function when cross-threading, but only sends the message to the receiving thread's queue sent message queue. If the receiving line is impersonating is processing another message, then it will not be interrupted until it proactively gets the next message in the queue, and it will get the message and start processing, and when finished he will notify the sending thread of the result (guess by the replymessage () function).

During the processing of the receive thread, the sending thread suspends waiting for SendMessage () to return. However, if there are other threads sending messages to the sending thread at this point, it can respond, but is limited to non-queue type (non-queued) messages.

This mechanism can cause deadlocks, so there are other functions such as sendmessagetimeout (), Sendmessagecallback () to avoid this situation.

PostMessage () does not need to be synchronized, so it is relatively simple, it is only responsible for sending messages to the queue, and then immediately return to the sender, then the processing of the message is again controlled.

Can messages not go into the queue? What message does not enter the queue?

OK. In fact, MSDN divides the message into queue type (Queued message) and non-queue type (non-queued message), which is only a different route, but will eventually be handled by the message handler function.

Queue-type messages include hardware inputs (wm_key*, etc.), wm_timer messages, WM_PAINT messages, and so on, some examples of non-queue types are Wm_setfocus, wm_active, wm_setcursor, etc., which are sent directly to the handler function.

In fact, according to MSDN and the message routing process can be understood as, Posted message queue messages are true queue-type messages, and through SendMessage () sent to the message, even if it entered the sent message queue, Because of the synchronous processing required by SendMessage, these messages should also count as non-queue messages. Perhaps, the Windows system will handle the special process, forcing the message to bypass the queue.

Who will send the message? How is the hardware input being responded to?

Messages can be sent by the Windows system or by the application itself; can be sent to or from within a thread. The main focus is to see the caller of the Send function.

For hardware messages, the Windows system starts with a thread called raw Input thread, referred to as RIT. This thread is responsible for handling messages inside the system Hardware Input Queue (SHIQ), which are sent by the hardware driver. RIT is responsible for distributing the messages in the Shiq to the thread's message queue, and how does Rit know who to send them? If this is a mouse event, look at which window the mouse pointer refers to, and if it is the keyboard, see which window is currently active. Some special keys will be different, such as Alt+tab,ctrl+alt+del, RIT can ensure that they are not affected by the current thread and deadlock. RIT can only be associated with one thread at a time.

It is possible that the Windows system also maintains a queue that is distributed to the thread, other than the Shiq field, or directly to the window's handler function.

What does the message loop look like? When does a thread hang? When do you wake up?

Imagine a typical Windows application that starts after it displays a window that waits for the user to manipulate and react.

It is actually in a loop that waits for messages, and the loop keeps getting the message and processing it, and when there is no message, the thread hangs into the wait state. This is what is usually called a message loop.

A typical message loop is as follows (note that there are no cases of getmessage error handling):

 while 0 0 ) = FALSE) {     translatemessage (&msg);     DispatchMessage (&msg);   }

Here GetMessage () takes a message from the queue and passes through TranslateMessage (), mainly translating the virtual key message (WM_KEYDOWN, etc.) into a character message (WM_CHAR, etc.).

DispatchMessage () invokes the message handler function. Here's a bit of flexibility, and after the message is taken out of the queue, you can do something special without distributing it.

Here's a look at the details of GetMessage ():

BOOL GetMessage (          lpmsg lpmsg,    hwnd hwnd,    UINT wmsgfiltermin,    uint Wmsgfiltermax);

GetMessage () takes the message out of the queue and fills it in the MSG structure with a parameter return. If the message at this time is wm_quit, the identity thread needs to end, then GetMessage () returns false, then the while loop terminates. Returns true to indicate that other messages are being taken and that the contents of the content can continue to loop and run. If return-1 indicates an error GetMessage ().

Several other parameters are used to filter the message, you can specify the window to receive the message, and determine the type range of the message.

It is also necessary to mention that a concept is the thread of the Wake Flag, which is an integer value, stored in the Threadinfo inside and 4 message queue peers. Each of its bits represents a switch, such as Qs_quit, Qs_sendmessage, and so on, which are switched on or off depending on the situation. GetMessage () relies on these switches when processing.

The processing flow of GetMessage () is as follows:

1. Handle the messages in the sent message queue, which are sent primarily by the SendMessage () of other threads, because they cannot invoke the handler function of this thread directly, and the handler function is called directly when this thread calls SendMessage (). Once GetMessage () is called, all sent message will be processed and getmessage () will not return;

2. Processing the message in the posted message queue, where a message is received, GetMessage () copies it to the MSG structure and returns TRUE. Note that there are three messages wm_quit, WM_PAINT, Wm_timer will be specially handled, they are always placed in the last side of the queue, until no other messages are processed, continuous WM_PAINT messages will even be merged into one to improve efficiency. As you can see from the three messages that are discussed later, there is not much use of send or post messages to the queue.

3. Handle the qs_quit switch, which is set by the PostQuitMessage () function to indicate that the thread needs to end. Why not send or post a wm_quit message here? It is said that one of the reasons is to handle the special case of memory shortage, in which case the send and post are likely to fail, and the next is to ensure that all sent and posted messages are processed before the thread ends, because the program is running correctly, or data is lost? Unknown.

If Qs_quit is turned on, GetMessage () populates a wm_quit message and returns FALSE.

4. Processing messages in the virtualized input queue, mainly including hardware input and system internal messages, and returns true;

5. Processing sent Message Queue again, from MSDN without explanation. Is it possible to have a new sent Message when checking for steps 2, 3, and 4? Or to ensure that the following two messages are deferred;

6. Handle the qs_paint switch, which is only related to the validity of the window owned by the thread (Validated), is not affected by WM_PAINT, when the window is not valid need to redraw the switch will open. When Qs_paint is open, GetMessage () returns a WM_PAINT message. Processing Qs_paint is placed behind, because repainting is generally slow, which helps to improve efficiency;

7. Processing the qs_timer switch, similar to Qs_paint, returns the WM_TIMER message, because it is placed behind the qs_paint because it has a lower priority, and if the timer message requires repainting but the priority is higher than the paint, then paint has no chance to run.

If any message in GetMessage () is handled, GetMessage () does not return, but it suspends the thread and does not consume CPU time.

Similar waitmessage () functions are also useful.

There is also a peekmessage (), whose prototype is:

BOOL PeekMessage (          lpmsg lpmsg,    hwnd hwnd,    UINT wmsgfiltermin,    uint Wmsgfiltermax,    uint WREMOVEMSG);

It is handled in the same way as GetMessage (), but with one more parameter wremovemsg, you can specify whether to remove messages from the queue. The biggest difference should be that when there is no message to process, PeekMessage () is not pending the arrival of the waiting message, but returns false immediately.

Wm_destroy, Wm_quit, wm_close What's the difference between messages?

And the other two messages are about the window, WM_CLOSE will be sent first, the general situation when the program receives the message can be a chance to ask the user whether to confirm the close window, if the user is confirmed to call DestroyWindow () Destroy window, this time will send Wm_destroy message, At this point the window is no longer displayed, the WM_DESTROY message can be sent PostQuitMessage () to set the qs_quit switch, the WM_QUIT message will be returned by the GetMessage () function, but the thread's message loop may also be about to end.

What is the routing of messages within a window? What is the relationship between a window and its controls?

A window can have a parent property, and for a parent window, the window that belongs to it is called a child window. Control or dialog boxes (Dialog) are also windows, and they generally belong to a parent window.

All windows have their own handle (HWND), and when the message is sent, the handle is already specified. So when a child window receives a message, its parent window does not receive this message, unless the child window is forwarded manually.

More detailed windows and controls are discussed in another article.

Ps:

A very detailed description of the message of the relationship is contained in the latest new "Revelation of Windows Programming".

The author simulates the realization of SendMessage (), PostMessage () PeekMessage (), GetMessage (), which is equivalent to giving out the source code, at a glance!

Who's going to handle the news? Can message handlers send messages?

Handled by the message handler function (Window Procedure). A message handler is a callback function whose address is registered at the time the window class is registered and can only be called within the thread.

The prototype is:

typedef LRESULT (callback* WNDPROC) (HWND hwnd, UINT umsg, WPARAM WPARAM, LPARAM LPARAM);

The inside of a processing function is typically a switch-case structure that is processed for different message types. The Windows system also pre-defines a default handler for all Windows DefWindowProc (), which provides the most basic message handling, typically called when no special processing is required (that is, the default branch of switch).

A set of Windows created by the same window class shares a message handler, so be careful with the local variables of the window instance when writing the processing function.

The handler can send a message, but you can imagine that a loop might occur. In addition, the processing function is often called recursively, so reduce the use of local variables to avoid recursive too deep is the stack overflow.

Finally, the problem of handling functional specificity will be discussed in another article.

Windows Messaging Mechanism (EXT) 1

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.