Opened. NET message loop (GetMessage () cannot get any messages, it goes into idle (idle) state and goes to sleep (not busy waiting). When Message Queuing is no longer empty, the program will automatically wake up.

Source: Internet
Author: User
Tags getmessage message queue

Opened. NET message loop of Mystery (-)

http://hi.baidu.com/sakiwer/item/f17dc33274a04df2a9842866

Those who have fought under the Win32 platform must remember how many sleepless nights were spent trying to figure out the concept of a "message loop". Although we no longer need it in the process of writing application code, it is still necessary to have a deep understanding of the message flow mechanism inside the Windows platform.

In the early days of writing programs directly with the Win32/win16 API, the message loop was the first idea we had to understand. Now, no matter what set of application frameworks (MFC, VCL, VB,. NET framework) You use on Windows, even the application framework above UNIX, Linux, MACOSX , it's not easy to see the message loop. In fact, the message loop still exists, just wrapped up by these applicationframework, buried deep in a corner.

This article attempts to evoke memories of the message loop and also attempts to explain how the message loop is encapsulated in the. NET Framework's Windows Forms. Although Windows Forms hides all this, it leaves plenty of room for us to handle WIN32 messages on our own.

Traditional Windows programs

Traditional Windows programs, only using the Win32 API to compose, here is a program example, in order to save space, I will be many of the program code omitted:

Program Entry point

int Apientry _tWinMain (hinstance hinstance, HInstance hprevinstance,

LPTSTR lpcmdline, int ncmdshow) {
MSG msg;
if (! InitInstance (HINSTANCE, ncmdshow)) {
return FALSE;
}

Main message loop:

while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&MSG); DispatchMessage (&MSG);
}
return (int) Msg.wparam;
}

Functions: WndProc (HWND, unsigned, WORD, LONG)
Purpose: Handles the message of the main window.

LRESULT CALLBACK WndProc (
HWND hwnd, UINT message, WPARAM WPARAM, LPARAM LPARAM) {
int Wmid, wmevent; Paintstruct PS;
HDC hdc;
Switch (message) {
Case WM_COMMAND:
Wmid = LoWord (WParam);
Wmevent = HiWord (WParam);
Anatomy Menu Selection Item:
Switch (wmid) {
Case Idm_about:
DialogBox (HInst, (LPCTSTR) Idd_aboutbox,hwnd, (Dlgproc) about);
Break
Case Idm_exit:
DestroyWindow (HWND);
Break
Default
Return DefWindowProc (HWnd, Message,wparam,lparam);
}
Break
Case WM_PAINT:
HDC = BeginPaint (hWnd, &ps);

TODO: Add any drawing program code here ...
EndPaint (HWnd, &ps);
Break

Case Wm_destroy:
PostQuitMessage (0);
Break
Default
Return DefWindowProc (HWnd, Message,wparam, LParam);
}
return 0;
}

The message processing routines for the [about] block.

LRESULT CALLBACK About (HWND hdlg, UINT message,

WPARAM WPARAM, LPARAM LPARAM) {
Switch (message) {
Case WM_INITDIALOG:
return TRUE;
Case WM_COMMAND:
if (LoWord (wParam) = = IDOK | | LoWord (wParam) = = IDCANCEL) {
EndDialog (Hdlg, LoWord (WParam));
return TRUE;
}
Break
}
return FALSE;
}
1, from within the _tWinMain, the program into the main message loop;

2. The message loop obtains a message from the message queue (in messages queues) (by calling GetMessage ()). Each executing program has a message queue that belongs to itself;

3, the message loop according to the message content to determine which message should be sent to which Windows Procedure (WndProc),. This is called Message distribution (msg Dispatch). Typically, each window or control has a Windows Procedure that handles the behavior of that type of window/control;

4. Windows procedure determines which function should be called based on the content of the message (using switch/case syntax);

5, Windows procedure processing finished, control back to the message loop. Continue the action of 2, 3, 4, 5;

6. When the message queue is empty, GetMessage () cannot get any messages, it enters the idle state and goes to sleep (not busy waiting). When Message Queuing is no longer empty, the program will automatically wake up ., continue the action of 2, 3, 4, 5;

7, when the obtained message is wm_quit,getmessage () will get 0 of the return value, thus leaving the message loop, the program ends. The program uses the call PostQuitMessage () to place the wm_quit into the message queue, resulting in a later end, rather than simply jumping out of the loop to the end.

Although named queue, the. However, messages in Message Queuing are not always FIFO (first Out,fifo), with some exceptions:

. as long as there is wm_quit in the message queue, the wm_quit is removed first, causing the program to end.

. WM_PAINT and Wm_timer are only removed when there is no other message. and multiple WM_PAINT may be merged into one, Wm_timer is the same.

. using TranslateMessage () to process messages can cause new messages to be generated. For example: TranslateMessage () can identify wm_keydown (press the button) plus Wm_keyup (press release) to produce WM_CHAR (character input).

Opened. NET message loop (ii)

http://hi.baidu.com/sakiwer/item/23dea1cc848f1a12b77a2466

What is message

The mouse moves, the keys are pressed, and the windows are closed. These all produce messages. In the Windows operating system, messages are present in the following data structure (defined in the WinUser.h archive):.

typedef struct TAGMSG {
HWND hwnd;
UINT message;
WPARAM WPARAM;
LPARAM LPARAM;
DWORD time;
Point pt;
} MSG;
There are six messages in the message, respectively:

. HWND: The number of the unique HWND for the window/control. The message loop sends the message to the correct destination based on this information.

. Message:windows the ID of the pre-defined message kind.

. WParam and lparam: Some messages themselves need to carry more information, which is placed in WParam and lparam.

. Time and PT: When the message occurred and the mouse position.

how the. NET Framework encapsulates message loops

The. NET Framework's Windows Forms encapsulate the message loop to make it easier for us to use. The classes (class) mentioned in this section are all part of the System.Windows.Forms namespace (namespace).

Briefly summarized as follows:The message loop is encapsulated into the run () static method of the application class, and Windows procedure is encapsulated in the NativeWindow and control classIndividual message processing actions are encapsulated into the control class's ONXYZ () (for example, OnPaint ()). We can overwrite (override) onxyz () to provide our own program. can also be exploited. NET event mechanism, on the XYZ event, add our event handler function (Handler). The ONXYZ () of the control class actively invokes the processing function of the XYZ event.

Note that because the event handler for XYZ is called by the ONXYZ () method of the control class, when you overwrite the onxyz () method, do not forget to call the control class's ONXYZ () (unless you have special needs), otherwise the XYZ event handler function will not work. Just call base. ONXYZ (), you can call the ONXYZ () method to the control class as follows:

protected override void OnPaint (PaintEventArgs e) {
Base. OnPaint (e);//TODO: Join Form1.onpaint implementation
}
We can use the ONXYZ () override of the control class to determine what to do when the message occurs. Similarly, we can even override the control with the NativeWindow class's WndProc () to define Windows Procedure.

Remind you again, because the ONXYZ () series method is called by the control class's WndProc (), so when you overwrite WndProc (), do not forget to call the control class's WndProc (unless you have special needs), otherwise onxyz () The series method (and the XYZ event handler function) will not work. Just call base. WndProc (), you can call the WndProc () of the control class as follows:

protected override void WndProc (ref Message m) {
Base. WndProc (ref m);//todo: Join the Form1.wndproc Practice
}
You may also notice that WndProc () needs a parameter for the message class, which is the result of the MSG being encapsulated as a. NET version.

example of a Windows Forms

In order to make the reader more aware of the actual situation, I use the following example example to illustrate:

Namespace windowsapplication1{
A summary description of the Form1.
public class form1:form{
The variables required by the design tool.
Private Container components = null;
Public Form1 () {
AutoScaleBaseSize = new Size (5, 15);
ClientSize = new Size (292, 266);
Name = "Form1";
Text = "Form1";
Paint + = new Painteventhandler (this. Form1_paint);
Paint + = new Painteventhandler (this. FORM1_PAINT2);
}
The primary entry point for the application.
[STAThread]
static void Main () {
Application.Run (New Form1 ());
}
protected override void OnPaint (PaintEventArgs e) {
Base. OnPaint (e); 2
}
private void Form1_paint (object sender, PaintEventArgs e) {
3
}
private void Form1_paint2 (object sender, PaintEventArgs e) {
4
}
protected override void WndProc (ref Message m) {
Base. WndProc (ref m); 1
}
}
}
1. In main (), use Application.Run () to display the Form1 window and enter the message loop. During the execution of the program, Application.Run () has not ended.

2. The OS puts a WM_PAINT message in the message queue of this process so that the window is displayed.

3. WM_PAINT is removed from the message loop within Application.Run () and distributed to WndProc (). Due to polymorphic (polymorphism) factors, the call (Invoke) to the WndProc () is Form1 WndProc (), that is, in the above program Annotated (comment) 1, rather than call to Control.wndproc ( )。

4. At the end of Form1.wndproc (), there is a call to base. WndProc (), which is actually called to Control.wndproc ().

5, Control.wndproc () learned from the message parameter that this is WM_PAINT, so call OnPaint (). Due to polymorphic factors, this call to the OnPaint () is a Form1 OnPaint (), that is, the above program annotation 2 place, rather than call to Control.OnPaint ().

6. At the end of Form1.onpaint (), there is a call to base. OnPaint (), which is actually called to Control.OnPaint ().

7. We have registered Form1_paint () and Form1_paint2 () in the Form1 constructor (constructor) as the Paint event handler
(Event Handler). Control.OnPaint () will go in sequence to call these two functions, that is, the above program in the comments 3 and 4 of the place.

Why do you know so much? Thanks to the tools, now the programmer is very happy, can be in the paste of the case to write a program. However, such programmers may not be competitive, after all, the component (component) Drag and drop (drag and drop) to the screen, and then set the component properties of the work, it is not too much difficulty. Only in-depth understanding of the internal principles, in order to make their own technology mastery, but also to let the programmer's road to go more robust and longer. dev.yesky.com/msdn/323/2339323.shtml

http://blog.csdn.net/jiangxinyu/article/details/8080393

Uncovered. NET message loop (GetMessage () cannot get any messages, it goes into idle (idle) state and goes to sleep (not busy waiting). When Message Queuing is no longer empty, the program automatically wakes up)

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.