Instructions for use of Windows X. h header files

Source: Internet
Author: User
Tags case statement microsoft c

 

Windows X. h header file: (all files are checked online)
Http://www.codeproject.com/win32/msgcrackwizard.asp

Part 1:
Introduction:
Windows X. H header files provide convenience for W32SDK programmers (tools ?)
Many junior and intermediate programmers often use a line-by-line switch... case statement block to write Windwos APIs in C/C ++.
When you add a large number of messages such as WM_COMMAND or WM_CHAR to the Window process (callback function, called process. It's a nightmare.
The Windows Process with thousands of lines of code is solved with a header file included in the C/C ++ 7.0 compiler and Windows SDK for Windows 3.1 release.
This header file is <windowsx. h> and contains a large number of useful macros. According to Microsoft, the convenience brought by these header files can be reused in the following areas (Groups)
:
Use the STRICT macro in the C program to perform STRICT type check.
. Use Macros in windows to simplify public operations.
. Use the control macro to communicate with the windows Control.
In windows, the message Parser (message crackers) is a convenient, portable, and type-safe method for message processing) and related parameters and return values.
The message parser wizard is used for the message parser. If you want to see
Windows X. H introduction, you can see the MS Knowledge Base Article #83456.
(Http://support.microsoft.com/default.aspx? Scid = http://support.microsoft.com: 80/support/kb/articles/q83/4/56.asp)
Well, let's talk about the advantages of the message parser, and of course why the tool provided here is so useful.
When you use the W32 SDK for programming and the windows Process (usually called WndProc) to process window and dialog box messages, use swich-case to capture the messages you need to process.
Very common practice. Suppose you want to process the WM_COMMAND, WM_KEYUP, WM_CLOSE and WM_DESTROY messages, you do this:

Lresult callback MainWndProc (HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
Switch (msg)
{
Case WM_COMMAND:
//...
Break;

Case WM_KEYUP:
//...
Break;

Case WM_CLOSE:
//...
Break;

Case WM_DESTROY:
//...
Break;

Default:
Return DefWindowProc (hwnd, msg, wParam, lParam );
}
}
This is the most common style of message processing since the birth of Windows1.0. And certainly, it works well.
But the problem is that when you add one or more complex features to your program, such as MDI and OLE public controls,
The result is a Window process with thousands of rows. You start to use PageDn and PageUp to find the Message Processing code you want to modify.

The first benefit of the message parser is that it converts a noodle-style case tag into functions that are easy to maintain and process in MFC.
The second advantage is: processing the appropriate parameters in the function. You can simply use the switch (id) instead of the original switch (LOWORD (wparam )),
Because the message parser sends you a "parsed" parameter, it is equivalent to LOWORD (wparam ).

The message processing macro HANDLE_MSG is defined in windowx. h as follows:
# Define HANDLE_MSG (hwnd, message, fn )/
Case (message): return HANDLE _ # message (hwnd), (wParam), (lParam), (fn ))
If you want to make your code "Message Parsing", you need to provide a parsing macro HANDLE_MSG and its functions to process your messages.
In the window process, the HANDLE_MSG macro requires three parameters: window handle (hwnd), message (WM_XXXX), and function for processing your message ).
To better explain this: Let's take a look at the following and convert the above Code into the following code:

Lresult callback MainWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Switch (msg)
{
HANDLE_MSG (hwnd, WM_COMMAND, OnCommand );
HANDLE_MSG (hwnd, WM_KEYUP, OnKeyup );
HANDLE_MSG (hwnd, WM_CLOSE, OnClose );
HANDLE_MSG (hwnd, WM_DESTROY, OnDestroy );
Default:
Return DefWindowProc (hwnd, msg, wParam, lParam );
}
}

Wow, this is a compact and easy-to-manage window process. Now you can define your message processing functions (OnKeyUp, OnClose, and OnDestroy)
Another real benefit is that you can directly jump to the message processing function in the visual studio IDE environment.

Image:... (see the original article)

There is a problem: when you add a message for processing, you must find the parameter definitions in windowx. h.
Because the format of message processing parameters is clear, you cannot do whatever you want. However, repeated searches in header files are tedious and error-prone.

The message parsing wizard tool is used to solve this problem: it allows you to paste the required function parameters,
If you just draft a template, he will also write a templated window or dialog box process (?? This sentence has doubts)
Message fowarding: Another feature of WINDOWSX. H (message forward ?)
Another characteristic of WINDOWSX. H is the possibility of message precursor,
It is the appropriate WPARAM and LPARAM values used to extract the message processing parameters to other function calls (such as PostMessage, SendMessage, and CallWindowProc.
Suppose we want to use SendMessage to send a WM_COMMAND message to the parent window, "simulate" a double-click on the IDC_USERCTL control (by sending the BN_DBLCLK notification code)
We usually do this:

SendMessage (hwndParent, WM_COMMAND,
MAKEWPARAM (IDC_USERCTL, BN_DBLCLK), // The lower 16 bits of WPARAM are the control ID and the higher 16 bits are the notification codes.
(LPARAM) GetDlgItem (hwnd, ID_USERCTL); // LPARAM is the control handle
This is quite complex syntax. SendMessage requires that the lower word of the WPARAM parameter is the Control ID, the higher word is the notification code, and the LPARAM parameter is the control handle.

API functions.
The preceding code can be converted to the Message macro FORWARD_WM_xxxxx of WINDOWSX. H.
For each message, the function parameters created by the message parsing wizard are packaged in the same way to the macro,
And the parameter (LPARAM/WPARAMs) passed to your handler "decompressed ).
For example, for a WM_COMMAND message in the myWnd window, the message parser wizard generates the following function prototype:

Void myWnd_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codenostrap)

Then, these parsed parameters are also used in the message precursor macro. In this way, the messy SendMessage call can be simplified:

FORWARD_WM_COMMAND (hwndParent, IDC_USERCTL,
GetDlgItem (hwnd, ID_USERCTL), BN_DBLCLK, SendMessage );

It is simple and feasible to use all the messages supported by the message parser. (Part 1 is complete)

Before using the message shunt to process a message, 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 a n d, you will find the part in the file that contains the following code lines:

/* Void Cls_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codenotasks )*/
# Define HANDLE_WM_COMMAND (hwnd, wParam, lParam, fn )/
(Fn) (hwnd), (int) (LOWORD (wParam), (HWND) (lParam), (UINT) HIWORD (wParam), 0L)
# Define FORWARD_WM_COMMAND (hwnd, id, hwndCtl, codenoctl, fn )/
(Void) (fn) (hwnd), WM_COMMAND, MAKEWPARAM (UINT) (id), (UINT) (codenoworkflow), (LPARAM) (HWND) (hwndCtl ))
The first line is the comment line that shows the prototype of the function to be compiled. The next row is the macro h a n d l e _ w m _ *, which we have discussed. The last line is the message forwarder (f o r w a r d e r ). Suppose that you want to call the default Window Process when processing the w m _ c o m a n d message and let it do things for you. This function should look like this:

Void Cls_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT codenostrap ){

// Do some normal processing.

// Do default processing.

FORWARD_WM_COMMAND (hwnd, id, hwndCtl, codenostrap, DefWindowProc );

}

F o rwa r d _ w m _ * macro re-constructs the distributed message parameters into the equivalent w P a r a m and l P a r a m. Then the macro calls the function you provided. In the preceding example, the macro calls the 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 an f o rwa r d _ w m _ * macro to help merge parameters.

Note the differences between Windows. h and Windows X.

2. tchar. h header file
Http://msdn2.microsoft.com/zh-cn/library/c426s321 (VS.80). aspx

3. CmnHdr. h header file

It contains macro and link program commands.

To create a sample program in this book, you must set the switch options of the Compilation Program and the linked program.
In the header file of cmhdr. h.

Because we cannot put all the settings in this header file, we have made some changes to the Project Settings of each sample program. For each Project, the Project Settings dialog box is displayed, and the following changes are made.
"In the G e n e r a l column, set the Output Files directory so that all the final. e x e and. d l Files are under the same directory.
"In the C/C ++ column, select the Code Generation entry and select Multithreaded DLL for the Use Run-Time Library field.

Note that the above two changes should be made to the establishment of D e B u g and R e l e a s e of each project.

All sample programs must contain C m H d r. h header file, which must be included before other header files. this is because CmnHdr. the h header file contains some link program commands, such as # define _ WIN32_WINNT 0x0500 (which is an option for Windows. before h, Microsoft Windows
The new function provided in 2000. Otherwise, the Compilation Program will generate an error. Microsoft uses the _ w I n 3 2 _ w I N T symbol to protect these functions, in this way, applications developed by programmers can run on multiple versions of Windows 98 and Windows NT.

Unicode creation option.

All the examples compiled by the author can be compiled either by a n s I or by U n I c o d e. When compiling these programs for the x 8 6 c p u architecture, a n s I is the default option so that the program can be executed on Windows 98. However, for other c p u architecture setup programs, you need to use U n I c o d e, so that the program can occupy less memory and run faster.

To establish the U n I c o d e version for the x 8 6 Architecture, you only need to remove the annotator of the line of code that defines u n I C O D E and recreate the program. By defining the u n I C O D E macro in CmnHd r. h, you can easily control how to build the sample program. For details about U n I c o d e, see Chapter 2nd.

Window definition and Level 4 warning
In this section, I make sure that the warning level is set to 3, and C m nH d r. h contains the standard Wi n d o w s. h header file. When Wi n d o w s. h is included, a 4th warning is set when I compile other code. On the 4th warning level, the Compilation Program sends a "warning" to the content that I don't think is problematic ", in this way, I explicitly tell the compiler to ignore some benign warning errors by using the # pragma warning command.

Pragma message help macro
 
Use the chMsg macro, for example, # pragma chMSG (Fix this later ).Let the compilation program output the name of the source code file and the row number that appears in p r a g m. When Microsoft Visual Developer Studio is used, double-click this line in the output window and the exact position of the corresponding file is automatically located. In addition, the c h m s g macro does not require quotation marks on text strings ..

ChINRANGE and chDIMOF macros
The chINRANGE macro is used to check whether a value is between the other two values.
ChDIMOF only returns the number of elements in an array.,This macro uses the s I z e o f operator to calculate the number of bytes of the entire array, and then divide the number by the number of bytes occupied by a data item in the array to obtain the result.

ChBEGINTHREADEX macro
The multi-threaded sample program uses the _ B e g I n t h r e a d e x function in the Microsoft C/C ++ runtime function library, instead of the C r e a t e T h r e a d function of the operating system. I used this function because the _ B e g I n t h r e a d e x function is ready for the new thread, enable the new thread to use functions in the C/C ++ runtime function library, and ensure that the C/C ++ Runtime library information of each thread is cleared when the thread returns.
Although the parameter values of the _ B e g I n t r e a d e x function are the same as those of the C r e a t e T h r e a d function, however, the data types of the two parameters do not match.
In order to avoid program compilation warning, I am in C m n H d r. h defines A c h B e g I N T H RE A D E X macro and performs all these conversions for me:

ChMB macro
The c h m B macro only displays a message box. The title of the message box is the full path name of the executable code of the calling process.

ChASSERT and chVERIFY macros
When I develop these sample programs, I use the c h A S E RT macro in the whole code to find potential problems. This macro tests whether the expression identified by x is t r u e. If not, a message box is displayed indicating the failed file, row, and expression. In the release and establishment of the program, this macro does nothing. The c h v e r I F Y macro is similar to the c h A S E RT macro. The difference is that whether it is debug build or release build
Build), c h v e r I F Y all need to test the expression.

ChHANDLE_DLGMSG macro

When you use message shunt through the dialog box, Microsoft's Wi n d o w s X should not be used. h a n d l e _ m s g macro in the header file, this macro cannot return t r u e or fa l s e to indicate whether the message is processed by the dialog box. The c h h a n d l e _ d l m s g macro I defined will notify the return value of the window message and properly process the return value for use in A dialog box.

ChSETDLGICONS macro

Since most sample programs use a dialog box as the main window, you must manually change the dialog box icon so that it is correctly displayed in Ta s k B a r (Task Bar) the task switching window and program title. When the dialog box receives A message w m _ I n I t d I a l o g, it always calls the c h s e t d l g I C O N S macro, to set the icon correctly.

OS version check inline functions

Most sample programs in this book can run on all platforms, but some programs require features not supported by Windows 95 and Windows 98, some programs require some features that are only provided in Windows 2000. Each program needs to check the version of the host system during initialization. If you require a more suitable operating system, a notification is displayed.

For programs that cannot run on Windows 95 or Windows 98, you will see that, in the program's _ t Wi n M a I n function, there is A call to the Wi n d o w s 9 x N o t a l o w e d function. For example programs that require Windows 2000, you will see a pair of c in the _ t Wi n M a I n Letter of the program
H Wi n d o w s 2 0 0 R e q u I r e d function call.

Check whether the host system supports Unicode
There is one way to know that my program is created for U n I c o d e, but it may run on Windows 98. So I created a CUnicodeSupported C ++ class. The constructor of this class only checks whether the host system has good support for U n I c o d e. If not, a message box is displayed and the process ends.

The reader will see that in C m n H d r. h, I have created a global static instance for this class. When my program starts, the C/C ++ runtime startup code calls the constructor of this object. If the constructor detects that the operating system fully supports U n I c o d e, the constructor returns and the program continues to execute. By creating a global instance for this class, I do not need to add special code in the source code module of each sample program. For non-U n I c o d e programs, do not declare or instantiate the above C
++ Class. Let the program only run.

Force link program search (w) WinMain to enter the point function
I am in C m n H d r. h adds a p r a g m a, and forces the link program to find (w) Wi n M a I n to enter the vertex function, even if a Win32 ConsoleA p l I C a t I o n project is created using Visual c ++.

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.