Win32 programming basics

xiaoxiao2021-03-06  68

Because it is classic all we have to share.

It is necessary to add a little:

Send this post mainly to let friends who want to know and understand Win32 programming, or students who have just started in this area can be a bit helpful.

Of course, it is a bit selfish, that is, I am afraid of my friends.

Try to recommend: "WINDOW Program Design" Beijing Publishing House Publishing

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

// Content: A basic Win32 program // *********************************************** *****************************

#include

#include

// Function declaration

Bool Initwindow (Hinstance Hinstance, INT NCMDSHOW);

LResult Callback WinProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM);

// ******************************************************** *******************

// Function: WinMain ()

// Function: Win32 application portfolio function. Create a main window, process the message loop

// ******************************************************** *******************

INT Pascal Winmain (Hinstance Hinstance, // Current instance handle

Hinstance hprevinstance, // Previous instance handle

LPSTR LPCMDLINE, / / ​​Command line character

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 ()

// Features: 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;

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";

// Register window class

RegisterClass (& WC);

// Create a main window

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;

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

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

New Post(0)