Analysis of WINDOWS Message Mechanism

Source: Internet
Author: User

1. Windows history

Chinese people like to learn from history, and the truth is true. If you know the ins and outs of a thing, it is easier to understand why things are like the current situation. Therefore, my introductory remarks usually start with a history. However, I won't go into detail in the way that is accurate to the year, month, and day. Instead, I will select several key points that have an important impact on our programming career.

Windows is a popular operating system with graphical interfaces. No matter what virtual names such as the first implemented GUI and the first commercialized GUI cannot replace windows's historical achievements, allows the most common users to easily manipulate the PC.

The first noisy version is Windows 3.0 (some people think it should be its healthier and stronger brother Windows 3.1). From that time on, we have an endless relationship with the following key roles in this article:

while(GetMessage(&msg, NULL,0, 0)){               TranslateMessage(&msg);               DispatchMessage (&msg);}

The three related functions in the above Code will be mentioned later.

The second version is not Windows 95. The major change in this version is that, in any case, it is a popular so-called 32-bit system. The reason why we need to add the so-called "three characters" is that this system is a mix of players. In 32-bit code, there are a lot of 16-bit code transplanted from the previous windows3.x.

Later this time, the key evolution process of another potential stock was over, and Windows NT 4.0 was unveiled. The operating system of this branch was fully 32-bit and became the source of the Windows 95 series, it is also our predecessor in almost all Windows desktop systems (Windows 2003/XP/2008/Vista. However, this version did not attract widespread attention from common users due to its high requirements on system hardware (at the time.

The next milestone is Windows 2000. Microsoft has merged Windows 9x/me branches and Windows NT branches. Next, Windows XP appeared. From the aspect of messages, we have made minor improvements in Windows2000. Before that, we need to create a normal, hidden, and complete window to process messages in many cases, windows 2000 introduces a special type of window for such requirements. In principle, it should reduce some resource usage.

Since then, Windows Vista was born in year 56. In fact, from Windows2000, the programming model of the Windows family, especially for native code, has basically not changed much. Generally, only new APIs or user controls are added, or new functions or styles are added to existing controls. Despite many changes in Windows Vista, the theme we are talking about today has little impact. One of the major impacts is that there is a level limit between the sender and receiver of a message. Unlike the previous steps in which messages can be transmitted at will, this is for security considerations.

2. Windows macro structure

Starting from the original version, three major functional blocks occupy the vast majority of Windows systems. These three are the well-known kernel, GDI, and user. Since Windows 95, the other two have also risen rapidly, namely the famous registry and shell.

The division of labor among these major parts is as follows: kernel, who is responsible for the kernel, is the cornerstone of anything that can be called an operating system. Its main responsibilities include: memory Management, task scheduling, and peripheral management; GDI is an operation interface for devices that can be manipulated graphically. Its main functions are to provide a coordinate system on devices, draw points, lines, shapes, fill, draw text, manage paint brush, paint brush, font and other drawing objects; user is the adhesive of the first two, allows the system to interact with users (that is, users) Through graphical operations. The scattered GDI objects are organically organized and abstracted as windows to accept user input, perform corresponding operations (not limited to arithmetic operations in a broad sense) and finally present the results to the user. Of course, user
The basic structure of the above functions can be implemented. The real implementation requires a lot of extra work, which is also the main work of shell. Registry provides users with a unified data access method unrelated to physical storage.

It is easy to see that the message function, which is used in the most natural way of Inter-window communication, should belong to the user part.

For the Windows Mobile Terminal process, rather than the abstract execution body in the desktop system. However, logically, we can still look at it like a desktop system.

3. Windows message Concept

In our general understanding, the fact of a message is a numerical value. After checking the prototype of the callback functions related to the message, we will find that the data type of the parameter indicating the message is uint, that is, the unsigned integer type. However, we usually find that messages usually contain two other types of data, one of which is wparam and the other is lparam, if the handle of the target window of the message is counted, a message and related information can be regarded as complete. Why is it a comparison? Looking at the definition of the MSG structure, we will find that there are two other data that we don't often use, which is related to a message. The complete declaration of MSG is as follows:

typedef struct {    HWND hwnd;    UINT message;    WPARAM wParam;    LPARAM lParam;    DWORD time;    POINT pt;} MSG, *PMSG;

The first four items are exactly what we have mentioned. The last two items indicate the time when the message occurred, and the other two indicate the mouse and cursor positions represented by screen coordinates when the message occurred.

From this structure, we can also see that the messages we often refer to represent a definite message value.

We may also hear such names as command messages, notification messages, and reflection messages. The first thing to declare is that this is not a scientific classification of messages in Windows systems, but a popular title in some specific scenarios. Command Message, typically wm_command message, which is usually sent by a control or menu, indicating that the user executes/sends a command. A notification message, typically wm_notify. This message is usually sent by a public control (commoncontrols), indicating that some events have occurred and need to be processed. Reflection messages are generally used in encapsulation classes or class libraries of Windows APIs. This is a general term for a type of messages. Their processing needs to go through a mechanism called reflection. The specific method of this mechanism is described in the next section.

Messages in Windows cannot be classified (if Division is required, messages defined by the system and messages defined by the application), but there is a division. Messages defined by the system are from 0x0000 to 0x03ff. Common wm_paint, wm_create, and so on are all in them. Messages from 0x0400 to 0x7fff are used for custom messages, you can use wm_user + X to define the value. The value of wm_user is 0x0400, and X is an integer. The value ranges from 0x8000 to 0 xbfff and starts from Windows 95, it is also used as a custom message range. You can use wm_app
+ The format of X is customized. According to Microsoft's suggestion, wm_app messages are used for message communication between programs, while wm_user messages are best used for a specific window class. Microsoft follows this Convention by itself. Therefore, messages of public controls, such as tvm_deleteitem, are basically wm_user class. From 0xc000 to 0 xFFFF, the message value of this segment is retained to the registerwindowmessage API. This API can accept a string and convert it into a unique message value. On the desktop system, the most common source string may be "taskbarcreated". The messages corresponding to it will be sent to all top-level windows, the notification taskbar has just been created (this may be caused by a resource management crash and restart ).

It can also be seen that the Message Value of Windows is a 16-digit number, which is a trace of us in the era of 16 systems. Another trace is the wparam and lparam data types. in the 16-bit era, wparam is a 16-bit data type. Its name indicates wordparameter and lparam is a 32-bit data type, the name is longparameter.

4. Windows Message Mechanism

4.1. Message Queue

Speaking of message mechanisms, even the most basic Windows programmers may be familiar with the term messagequeue (but not necessarily details ). For such a basic concept, the Windows operating system provides few Message Queue APIs (getqueuestatus, getinputstate, getmessageextrainfo, setmessageextrainfo), and, these APIs have a very low output rate, and even many experienced programmers have never used them. On Windows Mobile, these APIs are useless, but there is a very rare getmessagequeuereadytimestamp
The function is on the frontend.

All of this is due to the excellent encapsulation in the API layer, which reduces the concept that needs to be understood when you begin to access this platform. However, it is necessary for us to have a full understanding of the message queue.

4.1.1. System Message Queue

This is the only queue in the system. The driver of the input device (keyboard, mouse, or other) will convert the user's operation input into messages and place them in the system queue, the system then forwards the message to the Message Queue of the thread in the target window, which is waiting for processing.

4.1.2. Thread Message Queue (Application Message Queue)

The name of the application message queue is historical. In 32-bit (and later 64-bit) systems, the correct name should be the thread message queue. Every GUI thread maintains such a thread message queue. (This queue is created only when the thread calls the user or GDI function. It is not created by default ). Then, the messages in the thread message queue will be sent to the corresponding Window Process (also called the window callback function) by the message loop (sometimes called the message pump) of the thread.

4.2. Message Life Cycle

4.2.1. Message generation

There are two sources for message generation: one is the system and the other is the application. Messages generated by the system can be roughly divided into two types: one is caused by the input device, for example, wm_mousemove, and the other is the user part (or the other part in the system uses the user part) automatically generated to realize normal behaviors or management functions, such as wm_windowposchanged.

There are two methods of generation: Send and post, which correspond to two very familiar APIs, sendmessage and postmessage. Although we cannot see the code for messages produced by the system, we can roughly allocate all input messages to the application by delivery, most of other messages are sent.

As for applications, you can select a message generation method suitable for you.

4.2.2. Message Processing

In most cases, messages always have a target window. Therefore, most messages are processed by a window. The callback function of the window is used to process messages.

The callback function of a window is called a "Callback" because it is not actively called by users (programmers, instead, the system considers it to be called when appropriate. So, when is this "appropriate time? Based on the message generation method, there are two opportunities for "when appropriate.

The first time is when the dispatchmessage function is called, And the other time is when the sendmessage function is called.

In normal cases, we will take the system as an example to illustrate how to handle the left-click event of the close button of a top-level window.

Wm_nclbuttonup indicates that the left mouse button is released in a non-customer area of a window. In addition, other data of the mouse message indicates that, the position of this action is on the close button (htclose ). This is a mouse input event. As you can see from the past, it will be delivered to the Message Queue by the system.

Therefore, after a certain execution of getmessage in a message loop ends, the message is retrieved into the MSG structure. From the message loop code at the beginning of the article, we can see that this message will be translated by the translatemessage function (in fact, it is "possible") and then handed over to the dispatchmessage for full processing.

Dispatchmessage gets the MSG structure and starts a set of processes.

First, check the target window handle specified by the message. Check whether such a window exists in the system (actually in this thread). If there is no such window, it indicates that there are no candidates to take responsibility for the message, the message will be discarded.

If yes, it will directly call the callback function of the target window. Finally, we can see that the callback function we have written is out, which is one of the "proper times. Of course, in order to clarify the description, some other operations are omitted here.

In this way, for the system, a delivery message is processed and the getmessage is continued.

However, the above example is not complete yet.

We all know that for a message like wm_nclbuttonup, we usually have no time to do extra processing (the business is still busy ......). Therefore, we usually throw it into the famous garbage dump. That's right, defwindowproc. Even so, we can see that defwindowproc has actually become an integral part of our callback function. The only difference is that this function is not written by ourselves.

Defwindowproc is also very easy to process this message. It basically does not do anything substantive, but generates another message, wm_syscommand, and specifies SC _close in wparam. This time, the message is not delivered to the message queue, but sent directly.

As a result, the difficult process of sendmessage began.

The first step is to check the handle in almost the same direction as the dispatchmessage.

Step 2, The thing comes. It needs to check that the target window and itself are not in the same thread. If so, it would be easier to do. Follow the old path of dispatchmessage: Call the callback function of the target window. This is the second "right time.

But if it is not in a thread, it will be troublesome. The principle is very simple. Other threads have their own running tracks and there is no way to let them process the message immediately.

Now, how does sendmessage handle this hot potato? (Author's Note: When I write this article, I am very impulsive to write "I want to know what is going on and listen to the next decomposition)

Microsoft's Architect made a very smart choice: not to interfere with the internal affairs of other threads. I won't drag you to process my messages, and I will ship the messages to you (this shipping is an internal operation, from the outside, this message should always be considered as sent), and then -- wait.

Now, the ball hits the target thread. The target thread is also unambiguous. Since the message comes to my queue, my getmessage will follow the established process. However, it is different from the previous wm_nclbuttonup experience. Since the message is a foreign customer and sent, it takes precedence over other messages in the thread (after all, youbang is waiting). After processing, returns the result to the source thread of the message. For more information, see the description of the getmessage function.

In this example, as sendmessage (wm_syscommand) belongs to the current thread, it recursively calls the callback function in the window. Subsequent processing is derived from several other messages, such as wm_close and wm_destroy. This example is just for conceptual display, rather than completely accurate and reliable. Moreover, on Windows Mobile, there is simply no non-customer zone concept.

This is how all messages are processed in the system.

However, what should I do if postthreadmessage is delivered to the message queue? The answer is: do it yourself. The best processing location is before the translatemessage in the message loop is called.

Another problem that requires slight annotation is the message return value, which is somewhat subtle. For most messages, the returned values are meaningless. The return value is of great significance for other messages. I believe many people will be impressed with the return value of the wm_erasebkgnd message. The return value of the message directly affects whether the system wants to perform the default window background operation. Therefore, it is more secure to check what should be returned after processing a message.

This is a complete success.

4.2.3. Message priority

The above section actually implies this, and the priority of messages sent from other threads will be a little higher.

However, it should be noted that there are still a few lower priorities than normal messages. They are: wm_paint, wm_timer, and wm_quit. Only when there are no other messages in the queue, these messages will be processed, and multiple wm_paint messages will be merged to improve efficiency (Inside Story: wm_paint is actually a flag, so it seems to be "merged ").

All other messages are processed in FIFO mode.

4.2.4. What about messages not processed?

Someone will ask this question. In fact, this is almost a pseudo proposition, and there are basically no unprocessed messages. From the description in section 4.2.2, we can see that messages will always flow to a processing branch.

Therefore, I am inclined to ask the following question: if the window callback function does not process a message, what will happen to the message? In fact, this depends on the will of the real-time callback function. If you simply return a message, it is actually processed, but the processing method is "nothing is done". If you pass the message to defwindowproc, it will process several messages that you are interested in. It does not care about other messages and will return them directly.

4.3. Message deadlock

Assume there are threads a and B. Now you have the following steps:

1) thread a sendmessage is sent to thread B, and A is returned after the message is processed in thread B.

2) thread B receives a message from thread a and processes it. During the processing, thread B also sends a message to thread a and waits for the response from thread.

At this time, thread a is waiting to return from thread B and cannot process messages sent from thread B. This causes thread a and thread B to wait for each other and cause a deadlock.

Multiple Threads can also form a circular deadlock.

You can use sendpolicymessage or sendmessagetimeout to avoid such deadlocks.

(Note: The sendmessage between two threads has been specially written into a program for verification, but there is no deadlock in the result. I don't know if some new Windows systems have made special processing. Please verify it by yourself .)

4.4. Modal (Modal)

This word has brought me great confusion. I have made a lot of efforts to find out why the system builders used the word "Modal" to express such a situation, but it failed. I have to accept the word and use it. Until a few days ago, I found a brief introduction to the mode, if you are interested, you can look at it yourself: http://www.usabilityfirst.com/glossary/main.cgi? Function = display_term & term_id = 320. (Another effort I have made is to find out why handle is translated as a "handle", or, who first translated it like this, so far, there is no solution ). Windows
The modal in has several scenarios, typical of which are:

A dialog box is displayed.

Display a menu

Operation scroll bar

Move window

Change window size

To sum up my experience, that is: if a modal scenario is entered, all operations except the specific goal of the modal are prohibited. It can be understood as a mode. It is an exclusive mode, a forced mode, and a dominant mode.

In Windows, the implementation of the modal mode is actually very simple, but it only contains its own message loop. If you do not understand this story, you will feel mysterious. Then, based on this conclusion, we can do interesting (or meaningful) things. Let's take a look at the following code and predict the execution result of testmodal:

void CALLBACK RequestQuit(HWNDhwnd, UINT uMsg, UINT idEvent, DWORD dwTime);void TestModal(){               UINT uTimerId =SetTimer(NULL, 66, 1000, RequestQuit);               MessageBox(NULL, NULL, NULL,MB_OK);               KillTimer(NULL, uTimerId);}void CALLBACK RequestQuit(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime){               PostMessage(NULL, WM_QUIT,0, 0);}

For the answer, see the end of this section.

It should be noted that the modal mode is a very important and common concept in the user interface, not only in windows, but also in other user interface systems, such as Symbian.

4.5. Hook related to Message Processing)

Many people have heard or touched hooks more or less. In addition to the normal process of processing transactions, hooks provide an additional way of listening or controlling (Note: In Windows Mobile systems, hooks are not officially supported ).

(Todo: refined. However, this content can be skipped for the moment because it is more targeted at the desktop system)

4.6. so-called reflection)

As mentioned above, reflection usually appears in the encapsulation class or class library of Windows APIs. This is because Windows SDK APIs are exposed to users in the C style, the main class programming style of the C ++ language requires some meshing points.

For example, a button is a finalized control in the SDK, which basically achieves self-tolerance. To extend its functions (for example, to draw different appearances ), the system develops an interface (an interface in a broad sense, that is, an interactive contract) as two messages (wm_measureitem and wm_drawitem) sent to the owner (usually the parent window) of the button ). The principle is that the parent window of the button control is often implemented by the user, making it easier to process, without having to do anything to the button itself.

However, this interaction method is quite taboo in the C ++ world. The self-contained unit of C ++ is an object. Therefore, the encapsulation class of a button object is assumed to be cbutton and cannot be used to solve its own rendering problems, this is not in line with the law (although not impossible ).

Some people have proposed a reflection mechanism to eliminate this discord. The core is that the parent window does not directly process the messages (such as the preceding wm_drawitem) corresponding to the events handled by the Child control itself, instead, the message is sent back to the Child control.

This poses a problem. When the button receives a wm_drawitem message, it cannot be clear whether it is sent from its own subwindow (although it is not common to create a subwindow on the button, it is not impossible ), or the parent window reflects the original message. Therefore, Microsoft finally provides a solution that adds a fixed value-added value to the message value when reflecting the message. The value is ocmw.base. Although Microsoft was doing this by itself at the beginning, this value can be completely different, but later the compilers of other classes/class libraries almost kept consistent with Microsoft without exception.

After the control receives the message, it first reduces the added value to know which message is reflected and then processes it accordingly.

The answer to the small test in section 4.4: a message box shows about 1 second, and then disappears automatically. Some people write their own message boxes that are automatically closed when they exceed the limit. If you are interested, you can try and implement it yourself. (Note: you need to consider the situation that the message box is manually closed before the timer is triggered)

5. Message nature of Windows

A special event synchronization mechanism is implemented using a variety of common inter-thread synchronization mechanisms.

6. Message manipulation in Windows

Note: The functions marked in light green are described below, indicating that they do not exist on Windows Mobile.

SendMessagePostMessage

In the process of using messages, the two functions have the highest usage. Beginners sometimes cannot understand the use cases of these two message sending functions, which is easy to misuse. So let's put it together here. In fact, the sendmessage has been introduced a lot, so the focus here will be on postmessage. Compared with sendmessage, postmessage is much easier. You only need to find the thread where the window handle is located and put the message in the message queue of the thread, I totally ignore the final fate of the message and check whether the message has been correctly handled.

This is also reflected in the differences between the return values of postmessage and sendmessage. The postmessage function returns the bool type, indicating whether the shipping operation is successful. Shipping operations may fail, although we do not want to see them at the same time. For example, if the message queue of the target thread is full (a high probability of occurrence in the 16-bit era) or worse, the target thread has no message queue at all.

Of course, postmessage also checks the validity of the window handle. However, unlike sendmessage, postmessage allows the window handle to be null. In this case, the call to it is equivalent to calling postthreadmessage to deliver a message to the thread where it is located.

From the above description, we can easily see that the essential difference between postmessage and sendmessage is that the messages sent by the former are processed asynchronously, while those sent by the latter are processed synchronously. Understanding this is very important.

From the above result, we can get another useful inference. In this thread, if you want to perform another job on the premise of processing messages in a window, you can post a message to this window, to trigger the subsequent work.

GetMessage

Check the message queue of the thread. If there is a message, the message will be taken out to an input MSG structure and returned. If there is no message, wait. The waiting thread is in sleep state, and the CPU is allocated to other threads in the system.

It should be noted that the messages sent by other threads will be processed locally here (that is, the corresponding window callback function is called) and will not be returned to the caller.

DispatchMessage

The ins and outs of this message have been described in more detail in the above text, so I will skip it.

TranslateMessage(TranslateAccelerator)

In essence, this function has little to do with the messaging mechanism. The vast majority of message loops appear because the vast majority of programmers do not know what this function actually does, it is just out of practice or examples given in textbooks at the beginning. The role of this function is mainly related to input. It will properly and timely translate new messages such as wm_keydown and wm_keyup, such as wm_char. If you are sure that a thread does not require user input, you can safely remove it from the loop.

The list of translateaccelerator functions can be compared with it. This function translates user input into appropriate command messages based on the specified accelerator table.

PeekMessage

Snoop a thread's message queue. This function returns immediately no matter whether there is any message in the queue. Its Parameter List is basically the same as that of getmessage, but a flag parameter is added. This flag parameter specifies the behavior of peekmessage if a message exists in the queue. If the flag contains pm_remove, peekmessage will return the new message to the MSG structure, just as the getmessage behavior. If pm_noremove is specified in the flag, no messages are taken.

WaitMessage

This function is used to wait for a message to arrive. The thread is in sleep state during the waiting period. If a new message arrives, it is returned immediately.

After learning about peekmessage and waitmessage, in theory, we can write our own getmessage.

SendNotifyMessage

This function is very interesting, and its behavior belongs to the dish type. If the target thread is its own thread, it is sendmessage. Once it is found that the target thread is another thread, it is similar to postmessage and does not wait until the processing of the target window is completed. However, it is similar because the message sent by the target thread is still considered as sent.

Sendmessagetimeout

This function is the most powerful function in the sendmessage family (relative to postmessage. With the standard sendmessage function, it adds many additional control options and a timeout setting. For example, it can be specified. If the target window has no response, it will be returned immediately. You can also specify that if the response time of the target window exceeds the specified Timeout time, it will also be returned, instead of waiting infinitely. We know that sendmessage will be stubbornly waiting. (Insider information: sendmessage is actually a shortest encapsulation of sendmessagetimeout)

SendMessageCallback

Unlike sendmessagetimeout, this function extends the standard sendmessage in another direction. Its behavior is similar to sendpolicymessage, except that a subsequent processing function in the thread can be specified after the other party finishes processing the message. After careful observation, we can find that sendpolicymessage is actually a special case of this function.

This function is rarely used. In fact, the author has hardly seen the need to use it. There are some discussions and testing code for this function on the Internet, but there is little practical value. (I'm afraid this is one of the reasons why Windows Mobile does not implement this function .)

PostQuitMessage

The name of this function is confusing. In fact, it does not deliver any messages, but secretly sets a flag inside the system. When getmessage is called, it will detect this flag. If this flag is set and no other qualified shipping messages exist in the queue, getmessage returns false to terminate the message loop.

However, some people may have such doubts. We know that when the window handle of postmessage is null, it is equivalent to postthreadmessage (getcurrentthreadid (),...), So why do we need to introduce such a separate API instead of postmessage (null, wm_quit, 0, 0? Some people give the reason that this API appeared in the 16-bit windows era and there was no thread concept yet. If you think about this answer carefully, it seems to be an alternative, because we can regard process execution as a thread. The real cause may be some clues from the previous article. Pay special attention to the description of "no other qualified delivery messages in the queue.

PostThreadMessage

Deliver messages across threads. We know that message queues belong to threads. Therefore, you can deliver messages without specifying the target window but only specifying the target thread. Messages delivered to the target threadUsuallyWill be retrieved by getmessage. However, because no target window is specified, it will not be distributed to any window callback function.

Note the common characters in the preceding section. This is because in general, we call getmessage in the form of getmessage (& MSG, null, 0, 0). However, the second parameter is a window handle. If a valid window handle is specified, getmessage only retrieves the shipping message related to the window. If such a call is placed in the main message loop of the thread, a message backlog may occur (this is related to the number of windows you have created in this thread ). Fortunately, so far I have not seen anyone using getmessage.

BroadcastSystemMessage[Ex]

Generally, all the messages we come into contact with are sent to the window. In fact, the message receiver can be diverse, and it can be an application) installable driver, networkdriver, and system-level device driver, the broadcastsystemmessage API can be used to send messages to the above system components.

InSendMessage[Ex]

This function is used to check whether messages are sent from other threads when processing a message. Its application scenarios are extremely limited, unless you plan to limit the sources and production methods of some messages.

ReplyMessage

The description of this function in msdn is very simple. It has only a few words and is almost obscure. It can be inferred from the sample code segment that the message receiving thread (target thread) can call this function to make the message sending thread (source thread) the end Wait Status continues.

According to Microsoft's documentation, its official recommendation is: when processing messages that may come from other threads, if the processing of a step calls the function that causes the thread to hand over the control (original article: any function that causes the thread to yield control ), you should first call the insendmessage class function for determination. If true is returned, you should immediately use replymessage to reply to the source thread of the message.

"Will cause the thread to hand over the control function". The example provided by msdn is dialogbox, which allows me to make my own speculation that such a function includes at least the function that will lead to a certain mode scenario.

As for "messages that may come from other threads", the reality in the Windows world is that almost any message will come from other threads.

After years of observation, I can conclude that there are countless codes that have not been judged by the above process, and there are almost no serious adverse consequences exposed. This gives me reason to guess that Microsoft may have implicitly handled this situation within the system. In addition, there is no replymessage API in Windows Mobile.

GetMessagePosGetMessageTime

These two functions are used to access the other two information of the currently processed message, corresponding to the corresponding domain in the MSG structure. They exist because window callback and message processing functions generally do not transmit the two data.

MsgWaitForMultipleObjects[Ex]

This is an API that will be forgotten when it comes to message-related content. It is a cross-region of traditional ITC, IPC, and Windows message mechanisms. However, on the Windows platform, if you have not understood and mastered this function, it cannot be called an expert.

This function reveals the following details that are rarely noticed:

1. Messages and kernel objects are inextricably linked

2. Messages and kernel objects can be processed in a similar way.

If sendmessagetimeout is the most powerful message sending mechanism on the Windows platform, msgwaitformultipleobjects [Ex] is the most powerful waiting mechanism, which is waitmessage and waitfor... Function Family. Based on our conclusion that the combination of waitmessage and peekmessage can replace getmessage, we can also say that msgwaitformultipleobjects [Ex] is the most powerful message loop engine.

A careful description of this function will go beyond the scope of the message mechanism, so I will leave the work of studying it for you to practice.

7. Windows Message analysis

7.1. Differences between sendmessage and postmessage

Please consider how to organize an interview examiner to answer this question. J

7.2. Do messages sent by sendmessage not enter the message queue?

Tip: consider cross-thread scenarios.

This statement is not completely correct. When a message sent by sendmessage spans the thread boundary, the message is actually added to the Message Queue of the target thread. However, in the thread queue, messages sent by other threads are preferentially processed.

7.3. What is the difference between postmessage (wm_quit) and postquitmessage ()?

Tip: consider the case where the message queue is not empty when one of the preceding calls occurs.

7.4. is the classic message loop at the beginning of the article correct?

Tip: Pay attention to the returned value of getmessage.

For a long time, even Microsoft's example was written in this way. However, this writing is not correct. The reason is very simple. getmessage does not only return true for the receiving message, but does not return false if it fails to be obtained (in case of a wm_quit message). It also produces errors. -1 is returned when an error occurs. This makes the classic loop an endless loop when the getmessage error occurs. Microsoft's suggestion is that when getmessage returns-1, it jumps out of the loop and ends the program.

 

Note: This article is a training handout from a few years ago. Some of the content in this article is incomplete and has not been supplemented so far.

Related Article

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.