Message shunt, child control and API macro

xiaoxiao2021-03-06  70

The Windowsx.h file is a set of #define instructions, and a group of macros for us is built. Windowsx.h's macro is divided into three groups: message shunt, child control and API macro

First, message shunt

Message Cracker makes the window process more easier. Typically, the window process is implemented with a large SWITCH statement, using a message shunt to divide the SWITCH statement into a small function, each window corresponding to a function. This makes the code easier to manage. Another problem with the window process is that each message has WPARAM and LPARAM parameters, and the meaning of these parameters is also different depending on the message. In some cases, if W M _ C O M M A N D message, W p A R A m contains two different values. The high character of the W p A r a m parameter is a notification code, and the low word is the I D of the control. Or is it over? I always forgot the order. If you use a message shunt, you don't have to remember or check this. The reason why the message shunt is named because they deliver any given messages. In order to handle W M _ C O m M A N D, you only need to write such a function:

Void CLS_ONCOMMAND (HWND HWND, INT ID, HWND HWNDCTL, UINT CODENOTIFY)

{

Switch (id) {

Case id_somelistbox:

IF (CODENOTIFY! = lbn_selchange) BREAK;

// do lbn_selchange processing.

Break;

Case id_somebutton:

Break;

.

.

}

}

How easy is this! The splitter views the W P A R A M and L P A R A M parameters of the message, separated the parameters, and calls your function. In order to use a message shunt, you must make some modifications to your Sw i t c h statement for your window. Take a look at the following window process:

LResult WndProc (HWND HWND, UINT UMSG, WPARAM WPARAM, LPARAM LPARAM) {

Switch (UMSG) {

Handle_msg (HWND, WM_COMMAND, CLS_ONCOMMAND);

Handle_msg (hwnd, wm_paint, cls_oncommand);

Handle_msg (hwnd, wm_destroy, cls_oncommand);

DEFAULT:

Return (DEFWindowProc (HWND, UMSG, WPARAM, LPARAM);

}

}

H A N D L E_ M s G Macro is defined in Wi N D O W S x. H is this:

#define handle_msg (hwnd, message, fn) /

Case (Message): /

Return Handle_ ## Message ((HWND), (WPARAM), (LPARAM), (FN));

For W M _ C O m M A N D, the pre-processing program extends this line of code to the following code:

Case (WM_COMMAND):

Return Handle_WM_Command ((HWnd), (WPARAM), (LPARAM), (CLS_ONCOMMAND);

Define each H a n d L e _ w m _ * macro in Windowsx.h, the actual message shunt. They are divided into W P A R A M parameters and L p A R a m parameters, perform all necessary conversions, and call the appropriate message function, such as the C L S_O N C O m M a N D D function held in front. The definition of Handle _ WM _ Command macro is as follows: #define handle_wm_command (hwnd, wparam, lparam, flam, fn) / ((hwnd) (INT), (HWND) (LPARAM), UINT) HiWord (WPARAM)), 0L)

When the pre-processing program extends this macro, the result is a portion of the contents of the W P A R A M and L P A R A M parameters into their respective portions and the C L S_O N C O m M A n d function is called. Before using a message shunt to handle a message, you should open the Wi N D O W S x. H file and search for the message to be processed. For example, if you search for w m_ c o m M a n d, you will find the part of the file containing the following line:

/ * VOID CLS_ONCOMMAND (HWND HWND, INT, HWND HWNDCTL, UINT CODENOTIFY) * / # Define Handle_WM_COMMAND (HWND, WPARAM, LPARAM, FN) / ((fn) ((10) (INT) (h l) , (Hwnd) (WPARAM), 0L) #define Forward_WM_COMMAND (HWnd, ID, HWndCTL, CODENOTIFY, FN) / (VOID) ((HWND), WM_COMMAND, MAKEWPARAM (((( UINT) (ID), (UINT)), (lParam) (hwnd) (hwnd) (hwnd)) The first line is a comment line, show the function prototype to write. The next line is H a n d l e _ w m _ * macro, we have discussed. The last row is a message transponder (F O R w A R D E R). Assume that you want to call the default window process when you handle W M _ C O M M A N D message, and let it do for you. This function should look like this:

Void CLS_ONCOMMAND (HWND HWND, INT ID, HWND HWNDCTL, UINT CODENOTIFY) {

// do some normal processing.

// Do Default processing.

Forward_WM_Command (HWND, ID, HWNDCTL, CODENOTIFY, DEFWINDOWPROC);

}

F o rwa r d _ w m _ * macro will restructively restructured Message Parameters Equivalent W P A R A M and L P A R A M. Then this macro calls you the function you provide. In the above example, the macro is called D e f Wi N D O W P R O C function, but you can simply use S E N D M E S A G E or P O S T M E S A G E. In fact, if you want to send (or register) a message to any window in the system, you can use a F o RWA R D _ w m _ * macro to help merge each parameter.

Second, child control macro

Child Control Macro makes it easier to send a message to a child control. These macro f o rwa r o _w m _ * macro is very similar. Definition of each macro begins with a control type (this control is the control to send messages to it), followed by a lower horizontal line and message name. For example, sending a list box to a list box, using the macro in Wi N D O W s x. H: #define listbox_getcount (hwndctl) /

((int) SendMessage ((hwndctl), lb_getcount, 0, 0L))

I want two things about this macro. First, it uses only one parameter H W N D C T L, which is the window handle of the list box. Because the L b _ g e t C O U N t message ignores W P A R A m and L P A R A M parameters, you don't have to manage these parameters. You can see that the macro is only transmitted. Second, when S e n d m e s S A g e returns, the result is converted to I n t, so you don't have to provide your own conversion. With regard to the sub-control macro, I don't like it, it is the handle of these macros to use the control window. Many times, you have to send a message to a control, and this control is a child control of a dialog. So finally you always call G E T D L G i T E M, generate such code: int N = listbox_getcount (getdlgitem (HDLG, ID_Listbox));

Compared to using S e n d l g i t e m m m M m M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M Mun's operations, but your program will contain some extra code. This is due to the additional call to G E T D L G I T E M. If you need to send a few messages to the same control, you may want to call a g e t d l g i t e m, save the handle of the child window, then call all the macros you need, see the following code:

HWND HWNDCTL = Getdlgitem (HDLG, ID_Listbox);

INT n = listbox_getcount (hwndctl);

Listbox_addstring (hwndctl, "another string");

.

.

If you design your code in this way, your program will run faster, because this will not call G E T D L G I T E M repeatedly. If your dialog has many controls and the control you want to find is at the end of the z-order, G E T D L G i TEM may be a very slow function.

Third, API macro

A P i macros simplifies some common operations, such as establishing a new font, selecting font to the device environment, saving the original font handle. The form of the code is as follows:

HFONT HFONTORIG = (HFONT) SelectObject (HDC, (HGDiobj) HFontNew);

This statement requires two conversions to get compilation without compiling warning errors. There is a macro in Wi N D O W s. H, it is designed for this purpose:

#define SelectFont (HDC, HFONT) /

((HFONT) SelectObject ((HGDiobj) (HFONT) (HFONT))

If you use this macro, the code line in your program becomes:

Hfongt Hfontorig = SELECTFONT (HDC, HFontNew);

转载请注明原文地址:https://www.9cbs.com/read-120103.html

New Post(0)