The Windows message loop of those things

Source: Internet
Author: User

This article will combine some of the information on the Internet and their own experience, insight, the Windows message mechanism for a simple analysis, there is no place to welcome correct AH!!


First, indicate what role some messages are in the Windows system:

Messages are messages in the message mechanism that are used by worker threads to communicate with the UI thread, form and form, and a process to another thread's form. He is the blood of the Win32 program, through which the whole system can be linked together.

The message corresponds to a UINT value of the system, also known as unsigned 32-bit values, such as Wm_user, WM_PAINT, and so on, which we would normally customize. It uniquely defines an event that sends a notification to Windows telling the application something has happened. For example, clicking the mouse, resizing the window, and pressing a key on the keyboard will cause Windows to send a message to the application's message queue (described below), and the application will then take the message out of the message queue and respond accordingly. During this process, the operating system will also "send messages" to the application, and the so-called send message--------is actually a function of the operating system called a specialized processing message, this function is called the window process.

Here again, such events as mouse click events, keyboard events, and so on, require system-dependent systems to translate these hardware signals into specific messages, which require the driver layer to convert these hardware signals into event notification cores, and the kernel to convert messages into message queues (which will be followed). This is what everyone says about the event mechanism: hardware-to-message conversion.

The message itself is passed to the application as a record that contains the type of message and other information. For example, for a message that results from a mouse click, the record contains the coordinates of the mouse click. This record type, called MSG,MSG, contains message information from the Windows Application Message queue, and the MSG struct in Windows is defined as follows:

typedef struct tagmsg{       hwnd    hwnd;            The window handle that accepts the message is a       UINT message    ;         The message constant identifier, which is what we usually call the message number       WPARAM  WPARAM;          The specific additional information for the 32-bit message, the exact meaning depends on the message value       LPARAM  LPARAM;          The specific additional information for the 32-bit message, the exact meaning depends on the message value       DWORD time   ;            Time when the message was created point   pt;              The position of the mouse/cursor in the screen coordinate system when the message was created}msg;

An HWND is a handle to a form that a message belongs to, where the message is actually a thread, so the HWND can be empty when the message is sent to the specified thread through PostThreadMessage, indicating that the message does not belong to any form)

Message Queuing: System Message Queuing is created at system startup to receive messages converted from hardware events, and the RIT thread divides events into message queues for each application thread.Each UI thread has a message queue, not one message queue per form! What is a UI thread? Simply put, when a thread calls GDI (Graphics Device Interface) and the user function in the Win32 API, the operating system sees it as a UI thread and creates a message queue for it. Adding a thread's message processing loop at this time can be a UI thread. I can refer to a blog post that I have reproduced to detail the UI thread and Windows Message Queuing

1. System Message Queuing

When the operating system is started and initialized, the thread raw input thread (RIT) starts and creates the system hardware input queue (Hardware input queues) (SHIQ). For external hardware events (mouse or keyboard), the hardware driver converts the event into a message and stores it in Shiq, while the RIT thread is specifically responsible for handling messages in Shiq and distributing the message to the corresponding thread's message queue.

2. Thread Message Queuing

For each GUI program developed with MFC, they have a cmy***app, the class inherits from CWinApp, and CWinApp inherits from CWinThread, CWinApp is a GUI thread, the system maintains a threadinfo structure for it,

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

?
1234 Sent Message queue for sending messagesPosted Message Queue registrationvisualized input Queue enter message QueueReply Message Queue response Messages

Sent Message Queue: It holds messages that other programs send to the thread through SendMessage
Posted Message Queue: It holds messages that other queues send to the thread through PostMessage
Visualized Input queue: Saves messages that are distributed by the system queue, such as a mouse or keyboard message.

Reply Message Queue: Saves the result after sending a message to the form, such as when the SendMessage operation ends, the receiving message sends a Reply message to the sender's Reply queue to wake the send queue.

How are these queues generated? Threads are kernel objects, so let's look at how the thread information is defined, what it contains, and the definition of the Threadinfo struct as follows, and we can draw some information:



Message loop: When a line threads belongs to its own queue, the thread needs to have a looping function that goes through the message queue to fetch the message and process the message. The default main function in the new application project with VS is a message loop function (which you might be familiar with):
Main Message Loop:while (GetMessage (&msg, NULL, 0, 0)) {if (! TranslateAccelerator (Msg.hwnd, hacceltable, &msg)) {TranslateMessage (&msg);D ispatchmessage (&msg);}}

Is there a feeling of déjà vu:)
GetMessage (&msg, NULL, 0, 0)
This sentence gets a message from the message queue, and NULL means that it is obtained whenever a message is in the queue, or you can specify a message to get a particular form. This function is blocked, and the message will wait until a message is reached. See the MSDN GetMessage documentation for details after the message is processed: Call the TranslateAccelerator function to convert the accelerator message and send it out, if the TranslateMessage function is not successfully calledConvert messages such as wm_keyup,wm_keydown into corresponding WM_CHAR messages. Call DispatchMessage to pass the message to the processing function of the form. The specific processing function where: 1, first we can get to the message through GetMessage 2, remember those years how we register the form class? Remember the registration Form class needs to pass a lresult CALLBACK WndProc (HWND hwnd, UINT message, WPARAM WPARAM, LPARAM LPARAM) function? This function is the processing function of the form message:
  Function:wndproc (HWND, UINT, WPARAM, LPARAM)////  PURPOSE:  Processes messages for the main window.////  wm_command-process the application menu//  Wm_paint-paint the main window//  wm_destroy-post a quit message and Return////lresult CALLBACK WndProc (HWND hwnd, UI NT message, WPARAM WPARAM, LPARAM LPARAM) {int wmid, wmevent; Paintstruct PS; HDC hdc;switch (message) {case Wm_command:wmid    = LoWord (wParam); wmevent = HiWord (WParam);//Parse the menu selections : Switch (wmid) {case Idm_about:dialogbox (HInst, Makeintresource (Idd_aboutbox), hWnd, about); Break;case Idm_exit:d Estroywindow (HWND); Break;default:return DefWindowProc (hwnd, message, WParam, LParam);} Break;case WM_PAINT:HDC = BeginPaint (hWnd, &ps);//Todo:add any drawing code here ... EndPaint (hwnd, &PS); Break;case wm_destroy:postquitmessage (0); Break;default:return DefWindowProc (hwnd, message, WParam, LParam);} return 0;}

Perhaps you would ask, is the message loop above not a dead loop? So how do we get out?

Do you remember how we closed the window: by calling the Dialog::close () function, you would actually send a WM_DESTROY message to the form, as you can see from the code above, that the logic for handling the message is actually invoking the Postquitemessage function. This function will send a wm_quit message like a form, and a closer look at the return value of the GetMessage function shows that only getmessage will return 0 when the message is received, and the other is a non-0 value, so the message loop exits at this point.

So how does the message find the corresponding thread based on the handle of the form?

Since the form is a special handle that is a kernel resource, the system binds it to a specific thread handle when it is created, so you can pass the system function:HWND FindWindow (LPCSTR lpclassname,lpcstr Lpwindowname); the corresponding handle is found from the kernel based on the name of the form. And that's why the message is a thread, not a form, because one thread corresponds to a message queue and multiple forms.

Know how to collect and handle the news, how can I send a message? Message function Family:

The prototype of the SendMessage is as follows: LRESULT SendMessage (HWND hwnd,uint msg,wparam wparam,lparam LPARAM),

This function mainly sends a message to one or more windows and waits until the message is processed before it is returned. Note, however, that if the window that receives the message is part of the same application, the window function is immediately called as a subroutine, and if the window that receives the message is created by another thread, the window system switches to the appropriate thread and invokes the corresponding window function. This message will not be put into the target application queue. The return value of the function is returned by the window function of the window that receives the message, and the value returned depends on the message being sent.
The prototype of PostMessage is as follows: BOOL PostMessage (HWND hwnd,uint msg,wparam wparam,lparam LPARAM),

This function places a message in the message queue of the thread that created the HWND window, which returns control without waiting for the message to be processed. Note that if the HWND parameter is Hwnd_broadcast, the message is sent to all overlapping windows and pop-ups in the system, but the child window does not receive the message, and if the HWND parameter is NULL, The function is similar to calling the PostThreadMessage function by setting the dwThreadID parameter to the flag of the current thread.


From the above 2 representative functions, we can see the difference between the way the message is sent and the way it is sent: The message being sent is processed immediately, the function is returned after processing, and the message sent is not processed immediately, he is placed in a FIFO queue, Waits until the application is empty, but returns immediately after the function has placed the message.

In fact, there is not much difference between sending a message to a window processing process and directly invoking the window processing, and the only difference is that you can ask the operating system to intercept all messages being sent, but not to intercept direct calls to the window processing process.
Messages sent by mail are usually corresponding to user input events, because these events are not very urgent and can be processed slowly, such as a mouse, a keyboard message is sent, and a button message is sent.
Broadcast messages are less used, and the Broadcastsystemmessage function is prototyped as follows:
Long Broadcastsystemmessage (Dworddwflags,lpdword lpdwrecipients,uint uimessage,wparam WParam,LPARAM LPARAM); The function can send a message to the specified recipient, which can be an application, an installable driver, a network driver, a system-level device-driven message, and any combination of them. It should be noted that if the dwflags parameter is bsf_query and at least one recipient returns Broadcast_query_deny, the return value is 0, and if no bsf_query is specified, the function sends the message to all recipients and ignores its return value.

BOOL postthreadmessage (DWORD idthread,uint msg,wparam wparam,lparam iparam);A message that sends a message to a specific thread that can not belong to which form. This also makes the message not only for the window interface, but also for the entire system
MFC message mechanism: Personal view, MFC is actually encapsulated some system message API, and add some message definition macro library, detailed information can refer to the blog MFC message mechanism.
write this is mainly for personal note-taking, and exercise the ability to write articles, there is a problem, please lightly spray:)





The Windows message loop of those things

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.