Windows message shunt

Source: Internet
Author: User

A good blog post on Windows message loop

Forgive me link: http://blog.csdn.net/hopkins9961629/article/details/588184

In Windows, how can we identify and process various messages in the system by using the message processing mechanism? This is the role of message shunt.

To put it simply, the message shunt is a piece of code. In my story, I will introduce it step by step in 7. from the initial weight of 1st to the most mature weight of 7th, it will change a lot. however, all the functions are the same. The difference is that they become more concise.

At the beginning of the program, it will be the main function, then the initial window will be generated, and the wndproc function will be called. this is a custom function, and its name will change, but its function is the same, that is, running the message shunt. the wndproc function is as follows:

Lresult callback wndproc (hwnd, uint MSG, wparam, lparam)
{

//......

Return defwindowproc (hwnd, MSG, wparam, lparam );

}

In this example, hwnd is the window handle, and MSG is the name of the message sent by the system. wparam and lparam are the message parameters sent along with the message.

The wndproc function uses the message shunt. The following describes the content of the message shunt:

When different messages appear, write the corresponding program statement.
Lresult callback wndproc (hwnd, uint MSG, wparam, lparam)
{
Switch (MSG)
{
Case wm_create:
//...
Return 0;

Case wm_paint:
//...
Return 0;

Case wm_destroy:
//...
Return 0;
}
Return defwindowproc (hwnd, MSG, wparam, lparam );
}

Dual. Use three message shunt for processing.
Lresult callback wndproc (hwnd, uint MSG, wparam, lparam)
{
Switch (MSG)
{
Case wm_create:
Return handle_wm_create (hwnd, wparam, lparam, cls_oncreate );

Case wm_paint:
Return handle_wm_paint (hwnd, wparam, lparam, cls_onpaint );

Case wm_destroy:
Return handle_wm_destroy (hwnd, wparam, lparam, cls_ondestroy );
}
Return defwindowproc (hwnd, MSG, wparam, lparam );
}
Handle_wm_create, handle_wm_paint, and handle_wm_destroy are message shunt.
The difference is that the "handle _" character is added in front of the message, and the message shunt in Windows looks like this.
Its essence is macro definition.
Three of the four parameters are obtained directly from the entry parameters of this function, namely, hwnd, wparam, and lparam.
Only the fourth parameter indicates the called function.
The message shunt is defined in the winowsx. h file. From this, we can see that the fourth parameter is the called function. Its definition is as follows:

# Define handle_wm_create (hwnd, wparam, lparam, FN) (hwnd), (lpcreatestruct) (lparam ))? 0l: (lresult)-1l)

# Define handle_wm_paint (hwnd, wparam, lparam, FN) (hwnd), 0l)

# Define handle_wm_destroyclipboard (hwnd, wparam, lparam, FN) (hwnd), 0l)

0l is a variable of the int type, and its value is 0.
Int type, you can add L or L (lower case and upper case)
Indicates the number of unsigned characters. U or u can be added to the backend (in lower case or upper case)
For float type, you can add f or F (in lower case and upper case)
For example:
128u 1024ul 1l 8lu 3.14159f 0.1f

Lresult is the data type of a system, which is defined as follows:
Typedef long_ptr lresult;

Long_ptr is also a system data type, which is defined as follows:
# If defined (_ win64)
Typedef _ int64 long_ptr;
# Else
Typedef long long_ptr;
# Endif
It can be seen that the essence of lresult is a 64-type long variable.

The essence of (lresult)-1l is not subtraction, but (lresult) (-1l), that is, forced type conversion.

The following figure shows how to replace the macro definition of the message shunt.
Lresult callback wndproc (hwnd, uint MSG, wparam, lparam)
{
Switch (MSG)
{
Case wm_create:
Return cls_oncreate (hwnd, (lpcreatestruct) (lparam ))? 0l: (lresult)-1l;
// If the message is processed, cls_oncreate should return true, causing wndproc to return 0; otherwise, cls_oncreate will return false, causing wndproc to return-1;

Case wm_paint:
Return cls_onpaint (hwnd), 0l;
// Comma expression; cls_onpaint is of the void type, and 0 is returned here;

Case wm_destroy:
Return cls_ondestroy (hwnd), 0l; // same as cls_onpaint
}
Return defwindowproc (hwnd, MSG, wparam, lparam );
}
In a comma expression, C ++ calculates each expression, but the result of the complete comma expression is the value of the rightmost expression.
Therefore, return 0.
Then, you can manually write various processing functions: cls_oncreate, cls_onpaint, and wm_destroy.

Four-fold,
Lresult callback wndproc (hwnd, uint MSG, wparam, lparam)
{
Switch (MSG)
{
Handle_msg (hwnd, wm_create, cls_oncreate );
Handle_msg (hwnd, wm_paint, cls_onpaint );
Handle_msg (hwnd, wm_destroy, cls_ondestroy );
}
Return defwindowproc (hwnd, MSG, wparam, lparam );
}

Handle_msg is also a macro, which is defined in windowsx. h as follows:
# Define handle_msg (hwnd, message, FN) Case (Message): Return handle _ # message (hwnd), (wparam), (lparam), (FN ))

The macro is to convert itself into a macro in the form of handle_xxxxmessage according to different message (# used to connect the front and back strings, then, use the corresponding macro to execute the Message Processing code.
To put it bluntly, the message is replaced by #, which is a symbol of replacement.
If there is no #, it becomes handle_message. In this way, the macro will not be replaced.
If one is used separately, it will be replaced, such as hwnd and FN.

For example, write in the actual code:
Handle_msg (hwnd, wm_create, cls_oncreate)
After conversion, it becomes:
Case (wm_create): Return handle_wm_create (hwnd), (wparam), (lparam), (cls_oncreate ))
This is exactly the same as dual.

The above four duplicates are the basic use of the message splitter, but they are incomplete. The message splitter is mainly used in message processing in the dialog box.
Here, window subclass is a commonly used method, which can also be implemented through message shunt,

Fifth
Lresult callback dlg_proc (hwnd, uint MSG, wparam, lparam)
{
Switch (MSG)
{
Handle_msg (hwnd, wm_initdialo, cls_oninitdialog); // The handle_msg macro cannot be used directly.
Handle_msg (hwnd, wm_command, cls_oncommand); // The handle_msg macro cannot be used directly.
}
Return false;
}
Because it is a window subclass, at last, false is returned to indicate that if there is no agreed response message,
The parent window is returned. If yes, true is returned, which is different from the first four.
In general, the dialog box process function should return true when the message is processed. if the message is not processed, false is returned.
If the dialog box returns false, the dialog box manager Prepares the default dialog operation for this message.

However, there are errors because some messages need to be processed separately. For the list of messages processed separately, see the setdlgmsgresult macro.

Sixth
This is a small problem. You need to use the setdlgmsgresult (hwnd, MSG, result) Macro.

Lresult callback dlg_proc (hwnd, uint MSG, wparam, lparam)
{
Switch (MSG)
{
Case wm_initdialo:
Return (setdlgmsgresult (hwnd, MSG, handle_wm_initdialo (hwnd), (wparam), (lparam), (FN )));

Case wm_command:
Return (setdlgmsgresult (hwnd, MSG, handle_wm_command (hwnd), (wparam), (lparam), (FN )));
}
Return false;
}
Here, the second message shunt is used directly, and the other message shunt is discarded.

This macro is defined as follows:
# Define setdlgmsgresult (hwnd, MSG, result)
(
(
(MSG) = wm_ctlcolormsgbox |
(MSG) = wm_ctlcoloredit |
(MSG) = wm_ctlcolorlistbox |
(MSG) = wm_ctlcolorbtn |
(MSG) = wm_ctlcolordlg |
(MSG) = wm_ctlcolorscrollbar |
(MSG) = wm_ctlcolorstatic |
(MSG) = wm_compareitem |
(MSG) = wm_vkeytoitem |
(MSG) = wm_chartoitem |
(MSG) = wm_querydragicon |
(MSG) = wm_initdialog
)?
(Bool) (result ):
(Setwindowlongptr (hwnd), dwlp_msgresult, (lparam) (lresult) (result), true)
)

This format is used to express the message clearly. This is a three-expression. First, we examine the message type.

If the message processed during the dialog box happens to be one of the returned values, the result is returned truthfully;
Do not be blinded by the previous bool. The bool definition in the header file is actually an int type,
If you want to return other values other than true or false, you can do the same;

In this way, our cls_oninitdialog can return its bool value correctly,
After cls_oncommand is processed, a true value can be returned by the comma expression after it is processed, indicating that the message has been processed.

No. 7
We can also include cases as follows.

Lresult callback dlg_proc (hwnd, uint MSG, wparam, lparam)
{
Switch (MSG)
{
Chhandle_dlgmsg (hwnd, wm_initdialog, cls_oninitdialog );
Chhandle_dlgmsg (hwnd, wm_command, cls_oncommand );
}
Return false;
}

Chhandle_dlgmsg is a macro defined by Niu Ren. It also contains the case.
# Define chhandle_dlgmsg (hwnd, message, FN) Case (Message): Return (setdlgmsgresult (hwnd, umsg, handle _ # message (hwnd), (wparam ), (lparam), (FN ))))

In this way, the statements in the program
Switch (umsg)
{
Chhandle_dlgmsg (hwnd, wm_initdialog, dlg_oninitdialog );
Chhandle_dlgmsg (hwnd, wm_size, dlg_onsize );
Chhandle_dlgmsg (hwnd, wm_command, dlg_oncommand );
}

It is translated:
Switch (umsg)
{
Case (wm_initdialog ):
Return (setdlgmsgresult (hwnd, umsg, handle_wm_initdialog (hwnd), (wparam), (lparam), (dlg_oninitdialog ))));

Case (wm_size)
Return (setdlgmsgresult (hwnd, umsg, handle_wm_size (hwnd), (wparam), (lparam), (dlg_onsize ))));

Case (wm_command)
Return (setdlgmsgresult (hwnd, umsg, handle_wm_command (hwnd), (wparam), (lparam), (dlg_oncommand ))));
}

In this way, the message shunt is introduced.

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.