Win32 programming basics
Although the Windows application is thousands of change, it is dazzling, but the message mechanism and window processes always have their foundation, which is equivalent to grasping the key to the problem.
If you are previously a C programmer or MFC's faithful user, as long as you learn the syntax of the C language, you have a short C program, understand the following Win32 programming foundation is not a difficult thing.
A simplest Win32 program
In the previous C language programming, a simplest program can only have two lines.
Void main (void)
{Printf "Hello World!"
The Windows program to achieve the same function is also to write dozens of lines. This is not to indicate that the Windows application efficiency is low, it is difficult to master, but the program has a richer connotation in the Windows environment. The efficiency of the Windows program is not low. In all Windows applications, there is a process initialization process. This has to be used on dozens of statements. This initialized code is similar to that of any Windows applications. . The following is an example of a program easywin that implements the simplest function, describing the basic framework of the Windows program.
Open Visual C 6.0.
Select the New menu of the File menu, in the Dialog box that appears, select the Projects section (New Project), and take the Win32 Application item below, indicating that the application is created using the Win32 environment. First fill in "C: /" in the Locatin, then fill in "easywin" in the Project Name, other by default). Click the OK button.
Select the new menu again, in the dialog box that appears, select the Files section (new file), and take the C Source file below, indicating a new C source file. Enter "easywin" in the File column on the right, and finally make sure the Add to Project check box is ticked). Click the OK button.
Enter the following source code in the EASYWIN.CPP file.
// ******************************************************** *******************
// Project: Easywin
// File: easywin.cpp (Abbreviations for .c plus plus)
// Content: A basic Win32 program // *********************************************** *****************************
#include
#include
// Function declaration
Bool initwindow (hinstance hinstance, int ncmdshow); (you can take a look at MSDN
Hinstance is a process handle;
Handle is an object handle;
CWnd is a class of MFC, all window classes derived from it;
HWnd is the handle of the window.
In fact, the handle is a 32-bit integer, and the Windows operating system is used to mark an object.
I think, in addition to CWnd is a class, others are tagged
Microsoft likes to identify the kernel object, called the handle. Such as the process: hinstance, file handle: Handle,
Window handle HWND, brush handle HPEN, etc. CWnd is a class that provides a window processing, with hwnd m_hwnd members, CWND objects are typically binded to a window handle, but provide a lot of window operations, such as setWindowText, getWindowText, .... (Int ncmdshow parameters, indicating display type, such as maximizing or minimizing)
LResult Callback WinProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM);
// (Please see the macro definition in the header file:
Typedef long long;
Typedef long Lresult;
Now you should understand that LRESULT is actually long!
Use only the type of function return value before the function!
Please note the function definition and function prototype :))
// uint is unsinge Int
// In Win 3.x, WPARAM is 16-bit, and LParam is 32-bit, and there is a significant difference. Because the address is usually 32-bit, LParam is used to pass the address, which can still be seen in the Win32 API. In the Win32 API, WPARAM and LPARAM are 32 bits, so there is nothing nature. Windows's message must refer to the help file to know the specific meaning. If it is your defined message, would you like to make these two parameters? But habits, we are willing to use LPARAM delivery address, while WPARAM delivers other parameters.
// They are used to transfer data between messages under Windows (or at the Callback function),
Simplely said is 32-bit data (that is, a small memory space), we can write various numerical information.
WPARAM is a Word type Parameter (parameter), LPARAM is a long-type parameter, the transfer of messages, and the meaning is defined by each message.
// ******************************************************** *******************
// Function: WinMain ()
// Function: Win32 application portfolio function. Create a main window, process the message loop
// ******************************************************** *******************
INT Pascal Winmain (Hinstance Hinstance, // Current instance handle
//
__cdecl, __ stdcall, __ fastcall difference
__cdecl:
C / C default call specification, parameters from right to left, by the caller responsible for parameter outlet, so the program code is better
__stdcall method is slightly large
__stdcall:
Win32 API function uses this call mode, parameter from right to left, by the caller responsible parameter outlet
__fastcall:
The first two parameters were passed to the ECX and EDX registers, and the remaining left stack from the right direction, and the caller is responsible for the argument.
/ / How to call ASM assembly code in VC:
http://dwbclz.myetang.com/articles/masmhelp/
It is unrealistic to use assembly language writing programs, which is not necessary. Probably only two situations require assembly: highly executed efficiency or need to perform the function of the system. Therefore, in most cases, we still need to use the advanced language, just use assembly languages in key parts, which requires us to know how to combine advanced languages and assembly languages. If you use the inline assembly, you will be simple, just join the ASM keyword. However, some instructions are not supported by the inner contract, which makes us have to write a real assembler file. The naming specification for assembly language and advanced languages is not the same, and must be naming the identifier in the assembly file correctly, so that it can be adjusted normally in advanced languages. The following is a brief introduction to some common naming principles: named the block
In the C language, the code segment is "_text" as a paragraph name, and the data segment is used as a paragraph name as "_data". This rule is also applicable in Pascal. Below is an example:
_Text Segment Public Use32 'Code'
_Text Ends
This program defines a code segment, and the USE32 tells the compiler to generate 32-bit code.
Named an identifier
The C language has been compiled, and a loop line is added to all the identifiers. If you want to reference the variables or functions defined in the C program in the assembly language, you must also add an underscore. If you are using a C compiler, you should pay attention to it, you must use the C link to make the identifier meet the above naming specification. Here is an example:
// This is the definition method in the C language
EXTERN "C"
{
Int hello;
}
;; This is a reference in assembly language
EXTRN _HELLO
; ... other code
; ..........
Mov _hello, 0
Function call
The name of the variable is still relatively simple, and more problems are made for the function name. Not only to add a next line, but also consider calling specifications, sometimes even clarify the naming principles of each compiler. The next name lists some commonly used call specifications (these specifications apply only to C links):
__cdecl
This call specification is relatively simple, as long as it is equipped with an underline in front of the variable name. Moreover, this call mode is the same in any compiler. The detailed rules are as follows:
Parameters from right to left in the stack
Manage parameters by the caller
Add underline as a prefix
__stdcall
Many Windows APIs use this call mode, which is more space.
Parameters from right to left in the stack
By being responsible for parameters by the caller
Add the underscore as a prefix, add @n as a suffix, where "N" is the number of bytes of the parameter. (If you use C Builder, you don't need to add a precedent suffix.
__fastcall
This is the way of calling the parameters using the register.
If you use VC, then the first two parameters are passed to the ECX and EDX registers, and the remaining left stack from the right direction; if you use C Builder, then the top three double words are transmitted by Eax, EDX and ECX registers, others From right to left in the stack.
By being responsible for parameters by the caller
Add "@" as a prefix, add "@n" as a suffix, where "N" is the number of bytes of the parameter. (If you use C Builder, you don't need to add a suffix, just "@" as a prefix)
__msfastcall
This is a special keyword that INPRISE is compatible with Microsoft's call specification. In fact, there is no need to use __fastcall in VC, in my personal experience, this way is not well optimized in VC, and the execution efficiency will decrease. Use Masm6.14 in advanced languages
We can use some convenient ways to effectively combine assembly language compilers and advanced language development environments, and use command lines every time you compile.
How to use in VC
VC provides some support, you can automatically compile the assembly file, you can follow the steps:
Select "Project | Settings ..." in the menu
Check the specified assembly file (click)
Select Custom Build Page
Enter: in Commands:
If it is a debug mode, enter:
E: / MASM32 / BIN / ML / C / COFF / ZI /FODEBUG /$ (InputName ).obj $ (InputPath)
If it is a Release mode, enter:
E: / MASM32 / BIN / ML / C / COFF /FOREASE/$ (InputName ).obj $ (InputPath)
Enter: in Outputs:
If it is a debug mode, enter:
Debug / $ (InputName) .Obj
If it is a Release mode, enter:
Release / $ (InputName) .Obj
If you don't install MASM in the E disk, you have to make a corresponding modification.
The corresponding parameters are necessary to explain again:
"/ C" means that only the compilation is not linked. "/ Coff" means a target file that generates a COFF format, which is the file format used in the VC. "/ Zi" indicates that the symbol information is required for easy debugging.
Hinstance hprevinstance, // Previous instance handle
LPSTR LPCMDLINE, / / Command line character
// I have said in Qa000377 "Tchar, CHAR, LPSTR, LPCSTR, and CHAR." The LPSTR, LPCSTR is equivalent to char *, so the assignment of this type variable is equivalent to the assignment of char *. . If you don't know the value of char *, you need to look at the book entry in the C language, such as Tan Haoqiang's "C-language programming" Chapter 9 introduces this problem. Two examples are given below, one is directly assigned, the other is indirect.
EX1: lpstr lpstrmsg = "i'm Tired."
EX2: char strmsg [] = "i'm Tired."
LPSTR LPSTRMSG = (LPSTR) STRMSG;
INT ncmdshow) // window display method
{
MSG msg;
// Create a main window
IF (!in, ncmdshow)
Return False;
// Enter the message loop:
// Take a message from the message queue of the application, send it to the message processing process.
// When checking the WM_QUIT message, exit the message loop.
While (GetMessage (& MSG, NULL, 0, 0))
{
TranslateMessage (& MSG);
DispatchMessage (& MSG);
}
// End of the program
Return msg.wparam;
}
// ******************************************************** ******************
// Function: INITWINDOW () // Function: Create a window.
// ******************************************************** ******************
Static Bool Initwindow (Hinstance Hinstance, Int Ncmdshow)
{
HWND HWND; // Window handle
WNDCLASS WC; // window structure
// Fill the window structure
Wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnwndproc = (wndProc) WinProc; / / Pointer to the window process function
wc.cbclsextra = 0; // Reserved space for window classes
Wc.cbWndextra = 0; // Reserved space for window classes
Wc.HINSTANCE = Hinstance; // Windows program instance handle, this is provided by the compiler
Wc.hicon = loading; // set an icon for all windows created based on this window class
wc.hcursor = loadingcursor (null, idc_arrow); // Set a mouse for all windows established based on this window class
wc.hbrbackground = getStockObject (White_brush); // Specify the window background color created based on this window class, use the handle of a white brush to achieve
Wc.lpsz GeneNuname = NULL;
/ / Specify the menu of the window class, assign a value in this program with NULL.
wc.lpszclassname = "easywin";
/ / Specify the name of the window class
// Register window class
RegisterClass (& WC);
// Create a main window
HWND = CREATEWINDOW (the name of the szappname, // window class, based on this window class creation window
TEXT ("The Hello Program"), // Name of the window title bar
WS_OVERLAPPEDWINDOW, // Window style
CW_USEDEFAULT, / / The X coordinate of the window location
CW_USEDEFAULT, // Y coordinate of the window position
CW_USEDEFAULT, // Window size wide
CW_USEDEFAULT, // window high
Null, // Handle of the Father Window
Handle of Null, // Window menu
Example handle of Hinstance, // Windows application
NULL); // Create a pointer to the parameter, you can use the data in it to access the program
HWND = CREATEWINDOW
"Easywin", // window name
"A basic Win32 program", // window title
WS_OVERLAPPEDWINDOW, // Window style, defined as ordinary
100, // X coordinate of the window position
100, // Y coordinate of the window position
400, // Width
300, // The height of the window
Null, // Parent Window Handle
Null, // Menu handle
Hinstance, // application instant sequence
NULL); // Create a data pointer
IF (! hwnd) Return False;
// Display and update the window
ShowWindow (HWND, NCMDSHOW);
UpdateWindow (HWND);
Return True;
}
// ******************************************************** ****************** // function: WinProc ()
// Function: Handle the main window message
// ******************************************************** ******************
Lresult Callback WinProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM)
{
Switch (Message)
{
Case WM_KeyDown: // Key Message
Switch (WPARAM)
{
Case vk_escape:
Messagebox (HWND, "ESC button is pressed!", "Keyboard", MB_OK;
Break;
}
Break;
Case WM_RBUTTONDOWN: / / mouse message
{
Messagebox (hwnd, "right mouse button!", "Mouse", mb_ok);
Break;
}
Case WM_Paint: // Window Heavy Pictures
{
Char hello [] = "Hello, I am easywin!";
HDC HDC; // HDC is a device description table handle .a handle of the device context of an Object
Paintstruct PS;
HDC = beginpaint (hwnd, & ps); // acquire device environment handle
SetTextColor (HDC, RGB (0,255)); // Set text color
Textout (HDC, 20, 10, Hello, Strlen (Hello); // Output text
Endpaint (hwnd, & ps); // Release Resources
Break;
}
Case WM_DESTROY: // Exit Message
PostquitMessage (0); // Call exit function
Break;
}
// Call the default message processing process
Return DefWindowProc (Hwnd, Message, WPARAM, LPARAM);
}
The program is entered, you can compile execution. When you mouse mouse button or press the ESC button, a dialog box will pop up to represent your operation.
In fact, this program can be seen as a framework for all Win32 applications. In all programs in the later programs, you will find that they all add code on this program.
Winmain () function
The WinMain () function is the entry point when the application starts execution, and is usually the export point when the application ends task exits. It works as the main () function of the DOS program, one thing is that the winmain () function must have four parameters, which are passed to it. The prototype of the WinMain () function is as follows:
INT Pascal Winmain (Hinstance Hinstance, // Current instance handle
Hinstance hprevinstance, // Previous instance handle
LPSTR LPCMDLINE, / / Command line character
INT ncmdshow) // window display method
The first parameter hinstance is a handle that identifies the current instance of the application. It is a Hinstance type, and Hinstance is an abbreviation of Handle of Instance, represents the handle of the instance. Hinstance is a critical data that represents this parameter on behalf of the application, which requires this parameter during the later initialization program main window.
Here is two concepts, one is an example, one is a handle. The instance represents the entire process and method executing the application. If an application is not executed, it exists on the disk, then it is not instantiated; as long as one is executed, one instance of the program is run. Handle, as the name suggests, refers to an object's handle. In Windows, there are a wide variety of handles that are 32-bit pointer variables to point to the memory occupied by the object. The use of the handle can greatly facilitate Windows to manage various objects in its memory. The second parameter is HPREVINSTANCE, which is used to identify the previous instance handle of the application. This parameter is always NULL for Win32-based applications. This is because every instance of the application has its own independent address space in the Win95 operating system, even if the same application is executed twice, in memory, each instance of each instance is allocated new memory space. So after an application is executed, there will be no possibilities in the previous instance. That is, the parameters of HPREVINSTANCE are completely unnecessary, just to provide compatibility with 16-bit Windows applications, this parameter is retained. In the previous 16-bit Windows environment (such as Windows3.2), HPREVINSTANCE is used to identify the front handle of the application related to Hinstance.
The third parameter is lpcmdline, which is a pointer to the application command line parameter string. If you click Run in the "Start" menu of Win95, enter "EasyWIN Hello", then the string points to "Hello".
The last parameter is ncmdshow, an integer used to specify the window display mode. This integer value can be SW_SHOW, SW_HIDE, SW_SHOWMAXIMIZED, SW_SHOWMIMIMIZED, etc., and will be explained in the next section.
Registration window class
An application can have many windows, but only one is a main window, which is uniquely associated with instance handles of the application. In the above routine, the function of creating the main window is initwindow ().
You typically want to fill a window class structure WndClass and then call RegisterClass () to register the window class. Each window has some basic properties, such as window borders, window title bar text, window size, and location, mouse, background color, name of the processing window message function, and so on. The process of registration is to tell the system, then call the CREATEWINDOW () function to create a window. This is also like you to customize a dress, first tell the shop owner, your body size, cloth color, and your style, then he can make a satisfied clothes for you.
In the help of VC, you can see that the WNDCLASS structure is defined:
Typedef struct _wndclass {
Uint style; // Window style *
WndProc lpfnwndproc; // Specify the far pointer of the message processing function of the window *
INT cbclsextra; // Specify the number of additional bytes after assignment to the window structure *
INT CBWndextra; / / Specify the number of additional bytes after assigning the window instance
Handle Hinstance; / / Specify the instance handle corresponding to the window process *
Hicon Hicon; // Specify the icon of the window
Hcursor hcursor; // Specify the mouse in the window
Hbrush Hbrbackground; // Specify the background painting brush of the window
LPCTSTR LPSZMENUNAME; // The menu resource name of the window
LPCTSTR LPSZCLASSNAME; / / The name of the window *
} WNDCLASS;
In systems with new interface features in Win95 and WINNT, in order to support new window interface features, there is an extension window type WNDCLASSEX, which is defined as follows: typedef struct _wndclassex {
Uint cbsize; // Specify the size of the WNDCLASSEX structure
Uint style;
WndProc lpfnwndproc;
Int cbclsextra;
Int Cbwndextra;
Handle hinstance;
Hicon Hicon;
Hcursor hcursor;
Hbrush Hbrbackground;
LPCTSTR LPSZMENUNAME;
LPCTSTR LPSZCLASSNAME;
Small icon of Hicon HiconSM; //
WNDCLASSEX;
Two structures of WNDCLASS and WNDCLASSEX are basically consistent, just two members of CBSIZE and HICONSM in the WndClassex structure. Among the members of the WNDCLASS structure, it is specifically paying special attention after the comment.
The first member style of the WNDClass structure represents the style of the window class, which is often combined by some basic style "or" operations (operating position "|"). The following table lists some common basic window style:
Style meaning
CS_HREDRAW If the width of the window client is changed, redraw the entire window
CS_VREDRAW If the window customer area changes, redraw the entire window
CS_DBLCLKS can feel the double-click message in the window
CS_NOCLOSE Disables the "Close" command in the system menu
CS_OWNDC assigns individual independent device environments for each window of the window class
CS_CLASSDC assigns a shared device environment for each window of the window class
CS_PARENTDC specifies a sub-window inheriting the device environment of its parent window
CS_SAVEBITS Saves the screen image portion covered by the window as a bitmap. When the window is moved, Windows uses the saved bitmap to rebuild the screen image.
In the Easywin application, the WNDCLASS structure is filled and registered as follows:
Wc.style = CS_VREDRAW | CS_HREDRAW;
Wc.lpfnWndProc = (WndProc) WinProc;
wc.cbclsextra = 0;
wc.cbWndextra = 0;
wc.hinstance = hinstance;
Wc.hicon = loadicon (Hinstance, IDi_Application);
Wc.hcursor = loadingCursor (NULL, IDC_ARROW);
wc.hbrbackground = getStockObject (White_brush);
Wc.lpsz GeneNuname = NULL;
wc.lpszclassname = "easywin";
It can be seen that wc.style is set to CS_VREDRAW | CS_HREDRAW, indicating that the entire window is heard as long as the height or width of the window changes.
The value of the second member lpfnWndProc is (WndProc) WinProc. The message processing function of the window is indicated is a WinProc () function. Here, to specify the far pointer of the message processing function of the window, enter the function name of the message processing function, if necessary, the mandatory type conversion should be converted into a WNDPROC.
The next CBCLSEXTRA and WC.CBWndextra are set to 0 in most cases.
Then the Hinstance member gives it the instance handle of the application from WinMain (), indicating that the window is associated with this instance. In fact, as long as it is a registration window class, the value of the member is always the instance handle of the program, and you should remember it like your back book. The following HiCon is to let you specify an icon to this window, call LoadCon (Hinstance, IDi_Application), can call the internal pre-defined flag of the system as the icon of the Idc_Application as the icon of the window.
Similarly, call LoadCursor (NULL, IDC_ARROW) to pre-define the arrow type mouse inside the system to call the window.
HBRBACKGROUND members are used to define the background of the window on the window, which is the background color of the window. Call GetStockObject (White_Brush) You can get the pre-defined white painted white painted brush as a window in the system.
The above LoadCon (), loadCursor (), getStockObject () is Windows's API function, and their usage can be used to see the help of VC, here is not more introduced.
The value of the LPSzMenuname member we give NULL, indicating that the window will have no menu. If you want your window to have a menu, you assign the LPSZMenuname member to the string of the flag menu resource.
The last member of the WNDClass structure is a unique name that allows you to give this window class, because there are many window classes in the Windows operating system, you must use a unique name to represent them. Typically, you can name your program name to name the name of this window. This name will be used in the createWindow () function of the creation window.
After filling, for the WndClass structure, call the registerclass () function to register; for the WNDCLASSEX structure, call the RegisterClassex () function to register, their prototypes are as follows:
Atom RegisterClass (const wndclass * lpwndclass);
Atom RegisterClassex (Const WndClassex * LPWCX);
If the function is successful, it returns a non-0 value, indicating that a window class named Easywin has been registered. If it fails, it returns 0.
Create a window
When the window classes are registered, there will be no windows displayed because the process of registration is just ready for the creation window. The actual creation of a window is done by calling the CreateWindow () function. The general properties of the window have been pre-defined in advance, and the parameters in CREATEWINDOW () can further specify a more specific properties of a window, in the EasyWIN program, call the CREATEWINDOW () function to create a window as follows:
HWND = CREATEWINDOW
"Easywin", // Create a name of the window class used by the window *
"A basic Win32 program", // window title
WS_OVERLAPPEDWINDOW, // window style, defined as ordinary *
100, // X coordinate of the window position
100, // Y coordinate of the window position
400, // Width
300, // The height of the window
Null, // Parent Window Handle
Null, // Menu handle
Hinstance, // application instance sector *
NULL); / / generally null
The meaning of the parameters of the CreateWindow () function already introduces in the comments above. After comments, the parameters of the asterisk mark should focus on, and other parameters are very simple, not much introduction, see the help of VC.
The first parameter is the name of the window class used to create the window, note that this name should be consistent with the name of the window class registered earlier. The third parameter is the style of the created window, the following table lists the common window style:
Style meaning
WS_OVERLAPPEDWINDOW Creates a laminated window, a border, title bar, system menu, and maximum minimum button, is a collection of the following style: WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, WS_MAXIMIZEBOX
WS_POPUPWindow Creates a pop-up window, which is a collection of styles: WS_Border, WS_POPUP, WS_SYSMENU. WS_CAPTION and WS_POPUPWINDOW style must be used together to make the window menu visible
WS_OVERLAPPED creates a stacked window, which has title bar and border, like WS_TILED style
WS_POPUP This window is a pop-up window that cannot be used at the same time as WS_CHILD
WS_BORDER window has a single line border
WS_CAPTION window has title bar
WS_CHILD This window is a child window, cannot be used with WS_POPUP
WS_DISABLED This window is invalid, that is, no response to user operations
WS_HSCROLL window has horizontal scroll bar
The WS_ICONIC window is initialized to minimize
WS_MAXIMIZE window initializes to maximize
WS_MAXIMIZEBOX window has a maximum button
WS_MINIMIZE is the same as WS_MAXIMIZE
WS_MINIMIZEBOX window has a minimization button
WS_SIZEBOX border can make a size control window
WS_SYSMENU Creates a window with a system menu, must be used at the same time as the WS_CAPTION style
WS_THICKFRAME Creates a size controlled window with the WS_SIZEBOX style.
WS_TILED creates a stacked window with title bar
WS_Visible window is visible
The WS_VSCROLL window has a vertical scroll bar
The WS_OVERLAPPEDWINDOW flag is used in the program, which is a common flag that creates a normal window. In DirectX programming, we often use WS_POPUP, and the window created with this flag does not have the title bar and system menu. If the setting window is maximized, the client area can account for full screen to meet the needs of DirectX programming.
In the parameter behind the CreateWindow () function, the instance handle of the application is still used in Hinstance.
If the window is created success, the return value is the handle of the new window, otherwise returns NULL.
Display and update the window
After the window is created, it will not be displayed on the screen. To really display the window on the screen, you have to use the showWindow () function, its prototype is as follows:
Bool ShowWindow (HWND HWND, INT NCMDSHOW);
Parameters hWnd Specifies the handle to display the window, ncmdshow represents the display mode of the window, which is specified as the value passed from the NCMDSHOW of the WinMain () function.
Since the showWindow () function is not high, when the system is busy performing other tasks, the window will not immediately display it. At this time, call the UpdateWindow () function to display the window immediately. Its function prototype is as follows:
Bool UpdateWindow (HWND HWND);
Message loop
In Win32 programming, the message loop is a considerable concept, which seems very difficult, but it is very simple. In the Winmain () function, then the initwindow () function successfully created the application main window, then start the message loop, the code is as follows: While (GetMessage (& MSG, NULL, 0, 0)))
{
TranslateMessage (& MSG);
DispatchMessage (& MSG);
}
The Windows application can receive information entered in various forms, including the keyboard, mouse action, message generated by the memory, or a message sent by other applications, and the like. The Windows system automatically monitors all input devices and puts their messages into the message queue of the application.
The getMessage () function is used to take these messages one by one by the first-first principle, put it into a MSG structure. GetMessage () function prototype is as follows:
Bool getMessage
LPMSG lpmsg, // Pointer to a MSG structure, used to save your message
HWND hWnd, / / Specify which window of the window will be obtained
UINT WMSGFILTERMIN, / / Specify the minimum value of the obtained main message value
UINT WMSGFILTERMAX / / Specifies the maximum value of the acquired main message value
);
GetMessage () Copy the obtained message to an MSG structure. If there is no message in the queue, the getMessage () function will always be idle until there is a message in the queue again. If there is already a message in the queue, it will remove one after another. The MSG structure contains a complete information of a Windows message, which is defined as follows:
Typedef struct tagmsg {
HWND HWND; // Receive the window handle of the message
Uint message; // main message value
WPARAM WPARAM; // sub-message value, its specific meaning depends on the main message value
LPARAM LPARAM; // Secondary message value, its specific meaning depends on the main message value
DWORD TIME; // Message is delivered
Point pt; // mouse position
} Msg;
The main message in this structure indicates the type of message. For example, the keyboard message or mouse message, etc., the meaning of the sub-message is dependent on the main message value, for example, if the primary message is a keyboard message, then stored in the sub-message is a keyboard. Which of the specific keys of the specific key.
The getMessage () function can also filter messages, which is used to specify which window's message queue gets messages, and other window messages will be filtered. If this parameter is null, getMessage () gets a message from the message queue of all windows of the application thread.
The third and fourth parameters are used to filter the main message value in the MSG structure, the main message value outside WMSGFILTERMIN and WMSGFILTERMAX will be filtered out. If these two parameters are 0, then all messages are received.
When and only when the getMessage () function is acquired to the WM_QUIT message, the 0 value will be returned, so that the program exits the message loop.
The effect of the translateMessage () function is to convert the virtual key message to the character message to meet the needs of the keyboard input. The DISPATCHMESSAGE () function is completed by sending the current message to the corresponding window.
Turning a message loop is actually a simple step, almost all programs are in accordance with the method of Easywin. You don't have to go through the role of these functions, just a simple photo.
Message handler
The message handler is also called a window process. In this function, different messages will be allocated to different handles with the switch statement. Windows's message handling functions have a determined style, that is, the number of parameters and types of such functions, and the type of return values have a clear specification. In the specification of the VC, the prototype of the message processing function is defined: LRESULT CALLBACK WINDOWPROC (
HWND HWND, // Receive the handle of the message window
UINT UMSG, // main message value
WPARAM WPARAM, // subsis
LParam lparam // subsis value
);
If there are other messaging functions in your program, you must also be defined in this style, but the function name can be taken casually. The WinProc () function in EASYWIN is a typical message processing function.
The four parameters of the message processing function are obtained by get the MSG structure from the message queue from the message queue and then decomposed. The second parameter UMSG and the MSG structure are consistent, representing the main message value. The program uses the Switch statement to assign different types of messages to different handles.
The WinProc () function has clearly handled 4 messages, which are wm_keydown, wm_rbuttondown (right-click message), WM_Paint (Window Heavy Pictures), WM_DESTROY (Destroy Window Message).
It is worth noting that the application sent to the window is far more than the above, like WM_SIZE, WM_MINIMIZE, WM_CREATE, WM_MOVE, etc. There are dozens of frequently used messages such as WM_Size, WM_MOVE. To mitigate the burden of programming, Windows's API provides a defWindowProc () function to handle these most common messages. After calling this function, these messages will be processed in the system default manner.
Therefore, in the switch_case statement, it is only necessary to deal with the need for a particular response message, handle the remaining messages to the DefWindowProc () function, is a wise choice, which is also one of you must do.
End message loop
When the user presses Alt F4 or click the exit button in the upper right corner of the window, the system sends a message of WM_DESTROY to the application. When processing this message, call the postquitMessage () function that sends a WM_QUIT message to the message queue of the window. In the message loop, once retrieves this message, the GetMessage () function returns false, thus ending the message loop, then the program is also over.
summary
This chapter introduces the basics of Win32 programming, and master them is necessary before performing DirectX programming.
Through the study of this article, you should learn the following knowledge:
How to create a Win32 application engineering
Use the registerclass () function to register a window class, then call the CREATEWINDOW () function immediately to create an instance of a window.
Set the type of window and contact a message handler with the window
Turn on the message cycle with a fixed mode
Understand the definition rules of the message processing function, how to define a window message processing function
In the message processing function, finally you must call the defWindowProc () function to handle those default messages.
Call the postquitMessage () function to end the message loop