Windows program Design And Windows core programming (Hellowin routine)

xiaoxiao2021-03-06  83

First, the Hellowin program establishes a window First, you need to register a window category, which requires a window message processing function to process the window message. The processing window message has brought some burden on each Windows program.

The source code is as follows: HELLOWIN.C / * ----------------------------------------- ------------------------------ HelloWin.c - Displays "Hello, Windows 98!" In Client Area (C) Charles Petzold, 1998 ---------------------------------------------------------------------------------------------------------- ------------------------- * / # include Lresult Callback WndProc (HWND, UINT, WPARAM, LPARAM); int WinAPI WinMain (hINSTANCE hInstance, hINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "HelloWin"); HWND hwnd; MSG msg; WNDCLAS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH ); Wndclass.lpszMenunam = null; wndclass.lpszclassname = szappname; if (! Registerclass (w)) {MessageBox (Null, Text ("this P ! Rogram requires Windows NT "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, // window class nameTEXT (" The Hello Program "), // window captionWS_OVERLAPPEDWINDOW, // window styleCW_USEDEFAULT, // initial x positionCW_USEDEFAULT, // initial y positionCW_USEDEFAULT, // initial x sizeCW_USEDEFAULT, // initial y sizeNULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters ShowWindow (hwnd, ICMDSHOW; UPDATEWINDOW (HWND); While (GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG);

DispatchMessage (& msg);} return msg.wParam;} LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {HDC hdc; PAINTSTRUCT ps; RECT rect; switch (message) {case WM_CREATE: PlaySound (TEXT ( "Hellion.wav"), NULL, SND_FILENAME | SND_ASYNC); Return 0; Case WM_Paint: HDC = BeginPaint (HWND, & PS); getClientRect (hwnd, & review); DrawText (HDC, TEXT ("Hello, Windows 98!") , -1, & rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); EndPaint (hwnd, & ps); return 0; case WM_DESTROY: PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} 1, The function described in connection with: Loadicon loads the icon for use. LoadCursor is used in the mouse cursor for use. GetStockObject acquires a graphic handle (in this example, it is a brush handle to draw the window background. RegisterClass registers the window category of the program window. MessageBox Displays the Message dialog. CREATEWINDOW creates a window according to the window category. ShowWindow displays the window on the screen. UpdateWindow indicates that the window is self-updating. GetMessage gets messages from the message queue. TranslateMessage translates some keyboard messages. DispatchMessage sends a message to the window message handler. Plays and play a music file. Beginpaint begins to draw a window. GetClientRect gets the size of the window display area. DrawText Display String. Endpaint ends the window. PostquitMessage inserts a "Exit Program" message in the message queue.

DEFWINDOWPROC performs a constant message processing.

Second, some parameters Description: uint unsigned int (No Magic Number Integer) 32-bit PSTR is a char * wparam as a UINT, ie unsigned int (no fixed number integer) 32-bit LPARAM is a long (this is C) Long integer) 32-bit LRESULT is a long callback _stdcall

Third, handle Description: Handle is an integer (usually 32-bit) integer, which represents an object, using this handle in other Windows functions to use the object it represents. The actual value of the handle is irrelevant to the program. However, providing your program to your WINDOWS module know how to use it to use the corresponding object. Hinstance Execute Entity (Program Self) Handle HWND Window Handle HDC Device Content Handle HICON Illustration Handle HCURSOR Hull Mouse Caspic Handle HBrush Brush Handle

Fourth, Hungarian representation

prefix

Representation type

MSG

MSG type structure

WNDCLASSWNDCLASSEX

RECT

RECT

PS

Paintstruct

c

Char or wchar or tchar

BY

BYTE (no normal) character)

n

Short

i

Int

X, Y

INT is used as X coordinates and Y coordinates, respectively.

CX, CY

INT is used as X length and Y length, and C represents "counter"

B or f

BOOL (int); f represents "flag"

w

Word (no normal negative short integer)

l

Long (long integer)

DW

DWORD (no maximum number of negative)

FN

FUNCTION (function)

s

String (string)

SZ

String ending with 0

hide

Handle

PLP pointer 16-bit Windows left the product, now with P

V. Registration Window Type Window is established in accordance with a window type, the window type is used to identify the window message handler for processing the window message. Before building a window, you must first call register to register a window type. This function only requires a parameter, that is, a structural pointer pointing to type WNDCLASS. Two forms of Wndclass are as follows: 1, ASCII version of Wndclassa: typedef struct tagwndclassa

{

Uint style;

WndProc lpfnwndproc;

Int cbclsextra;

Int Cbwndextra;

Hinstance hinstance;

Hicon Hicon;

Hcursor hcursor;

Hbrush Hbrbackground;

LPCSTR LPSZMENUNUNAME;

LPCSTR LPSZCLASSNAME;

}

WNDCLASSA, * PWNDCLASSA, Near * NPWNDCLASSA, FAR * LPWNDCLASSA; 2, UNICODE version of the structure is defined as follows: typedef struct tagwndclassw

{

Uint style;

WndProc lpfnwndproc;

Int cbclsextra;

Int Cbwndextra;

Hinstance hinstance;

Hicon Hicon;

Hcursor hcursor;

Hbrush Hbrbackground;

LPCWSTR LPSZMENUNUNUNAME;

LPCWSTR LPSZCLASSNAME;

}

WNDCLASSW, * PWNDCLASSW, NEAR * NPWNDCLASSW, FAR * LPWNDCLASSW, FAR * LPWNDCLASSW; the only difference between the last two fields is defined as pointing to the wide string constant, rather than pointing to the ASCII string constant. The structure of the use of that version is determined according to the IFDEF Unicode in the program. The second field of the WNDCLASS structure is initialized by the following description: WNDCLASS.LPFNWNDPROC = WNDPROC; this narrative setting this window type window message handler is WNDPROC. The next field is the executive entity handle of the program (which is also one of the parameters of WinMain): wndclass.hinstance = hinstance;

Finally, a category name must be given. For a small program, the category name can be the same as the program name, that is, the "Hellown" string in the szappname variable is stored. Wndclass.lpszclassname = szappname; Next, hellowin calls RegisterClass to register this window type. Also, an old experience is: In some Windows sample programs, you may see the following program code in WinMain: if (! Hprevinstance)

{

WNDCLASS.CBSTYLE = CS_HREDRAW | CS_VREDRAW

Initialize other WNDCLASS

RegisterClass (& Wndclass);

}

This is the reason for "old difficulties". In the 16-bit Windows, if you start a new executive entity in the program being executed, WinMain's HPREVINSTANCE parameter will be the active entity code of the previous executive entity. In order to save memory, two or more executive entities may share the same window category. In this way, the window category is only registered when HPREVINSTANCE is NULL, indicating that there is no other implement entity. In 32-bit Windows, HPREVINSTANCE is always NULL. This program code will be implemented normally, and it is actually not necessary to check HPREVINSTANCE. 6. Establishing a window window type defines a general feature of the window, so many different windows can be created using the same window type. When you actually call CREATEWINDOW, you may specify more detailed information about the window. Windows programming newbies sometimes confuse the difference between the window type and the window, and why all features of a window cannot be set once. In fact, it is very convenient to separate these style information in this way. For example, all button windows can be established based on the same window type, and the window message handler associated with this window type is located inside Windows. The window type is responsible for the keyboard and mouse input of the button, and the button is defined on the appearance shape on the screen. From this point, all buttons work in the same way. But not all buttons are the same. They can have different sizes, different screen positions, and different strings. Some of these features later are part of the window definition instead of the window category. The information passed to the RegisterClass function will be set in a structure, and the information passed to the CREATEWINDOW function will be set in the function separate parameters. Below is the CreateWindows call in Hellowin.c, and each field has made a complete description:

HWND = CREATEWINDOW (Szappname, // WINDOW CLASS NAME

TEXT ("The Hello Program"), // WINDOW CAPTION

WS_OVERLAPPEDWINDOW, // WINDOW STYLE

CW_USEDEFAULT, // Initial X position

CW_USEDEFAULT, // Initial Y position

CW_USEDEFAULT, // Initial X size

CW_USEDEFAULT, // Initial y size

Null, // Parent Window Handle

Null, // WINDOW MENU HANDLE

Hinstance, // Program Instance Handle

NULL); // CREATION ParametersCreateWindow Return Value is the handle of the window, which is stored in the variable hwnd, which is defined as the HWND type. Each window in Windows has a handle, and the program is used by the handle. Many windows functions need to use hwnd as a parameter, so Windows can know which window is for the function. If a program has established a lot of windows, each window has a code. The window handle is one of the most important handles handled by the Windows program. 7. After the display window is transmitted back in the CREATEWINDOW call, this window has been established inside the Windows. That is to say, Windows has been configured with memory to save all information to specify the window in the CreateWindow call and some other information, while Windows will be based on the window handle to these messages later. However, the light is like this, and the window does not appear on the display. You also need two functions to call, one is:

ShowWindow (hwnd, icmdshow);

The first parameter is the window handle that has just been established with CREATEWINDOW. The second parameter is ICMDSHOW transmitted to WinMain as a parameter. It determines how the window is initially displayed on the screen, which is generally small, minimized or maximized. Windows Display SW_SHOWNORMAL Window is displayed by the general size display SW_SHOWMAXIMIZED window only displayed on the work list on the Sw_ShowminnoactiveShowWindow function Displays the window on the display. If the second parameter of ShowWindow is SW_SHOWNORMAL, the display area of ​​the window will be overwritten by the background drawing brush defined in the window category. Function call

UpdateWindow (HWND);

Will redraw the display area. It does this by sending a WM_Paint message sent to the Window message handler (ie, WndProc functions in hellowin.c). Behind, we will explain how WndProc handles this message. 8. After the message loop calls UpdateWindow, the window appears on the display. The program must now be prepared to read the user with information entered with the keyboard and mouse. Windows maintains a "message queue" for each Windows program currently executed. After the input event occurs, Windows converts the event into a "message" and puts the message into the program queue. The program takes out the message from the message queue by executing a piece called "message loop":

While (GetMessage (& MSG, NULL, 0, 0))

{

TranslateMessage (& MSG);

DispatchMessage (& MSG);

}

The MSG variable is the structure type MSG, and the type MSG is defined in WinUser.h as follows:

Typedef struct tagmsg

{

Hwnd hwnd;

Uint Message;

WPARAM WPARAM;

LParam Lparam;

DWORD TIME;

Point pt;

}

MSG, * PMSG;

The message loop starts with the getMessage call, which removes a message from the message queue:

GetMessage (& MSG, NULL, 0, 0)

This call passes a pointer to Windows, pointing to the MSG structure named MSG. Second, the third and fourth parameters are set to null or 0, indicating that the program receives all the messages of all the windows you build it yourself. Windows fills the various fields of the message structure with the next message removed from the message queue, each of which includes:

HWND receives the window code of the message. In the Hellowin program, this parameter is the same as the HWnd value returned by CreateWindow, because this is the only window owned by the number.

Message message identification word. This is a value for identifying the message. For each message, there is a corresponding identification word that defines the Windows header file (most of them in Winuser.h), starting with the header WM ("Window Message", Window Message). For example, the user puts the mouse within the Hellowin display area and press the left button, and Windows puts a message in the message queue, the Message field of the message is equal to WM_LButtondown. This is a constant, its value is 0x0201. WPARAM A 32-bit "Message Parameter", its meaning and value are different depending on the message. LPARAM A 32-bit message parameter, its value is related to the message. Time messages are placed in the message column. PT message places the mouse coordinates when the message queue is placed. As long as the Message field that removes the message from the message queue is not WM_QUIT (its value is 0x0012), GetMessage is transmitted back to a non-zero value. The WM_QUIT message will cause getMessage to pass back 0. Narrate

TranslateMessage (& MSG);

Pass the MSG structure to Windows to make some keyboard conversions. Narrate

DispatchMessage (& MSG);

Also post the MSG structure to Windows. Then, Windows sends the message to the appropriate window message handler for processing. That is, Windows will call the window message handler. In Hellown, this window message handler is the WndProe function. After processing the message, WndProc returns to Windows. At this point, Windows is still in the DISPATCHMESSAGE call. After ending the DISPATCHMESSAGE call, Windows returns to Hellowin and then starts the message loop from the next GetMessage call. Nine, the first message receiving the window message handler receipt of the window message processing program - is also the first message of the WndProc selection process - is WM_CREATE. WNDPROC receives this message when Windows processes the CreateWindow function in WinMain. That is, when hellowin calls CREATEWINDOW, Windows will do some work that it must do. In these work, Windows calls WNDPROC and sets the first parameter to the window handle, and the second parameter is set to WM_CREATE. WNDPROC processes the WM_CREATE message and transmits the control back to Windows. Windows can then return from the CREATEWINDOW call to Hellowin, continue to process the next step in WinMain. Typically, the window message handler is initialized once during WM_CREATE processing. Hellowin played an audio file called Hellion.wav in the process of this message. It uses a simple Plays and Sound function to do this. In this example, I specified the first parameter is a file name, and the sound is played in synchronously, that is, the Playsound function call returns immediately when the audio file starts playing, and will not wait for its completion. Under this method, the program can continue to initialize. WndProc ends the processing of the entire WM_CREATE by returning 0 from the window message handler. The WM_DESTROY message is another important message. This message indicates that Windows is close to the window according to the user's instruction. This message occurs when the user clicks on the Close button or in the system function table of the program. Hellowin responds to WM_DESTROY messages by calling postquitMessage: postquitmessage (0);

This function is inserted into a WM_Quit message in the program's message queue. As mentioned earlier, GetMessage returns a non-0 value for all messages removed from the message queue from WM_QUIT. When getMessage gets a WM_QUIT message, it returns 0. This will cause the WinMain to exit the message loop and terminate the program. Then the program performs the following description:

Return msg.wparam;

The WPARAM field of the structure is the value passed to the PostQuitMessage function (usually 0). The RETURN will then exit WinMain and terminate the program. Ten, serialization messages and non-sequenced messages We have already mentioned that Windows sends a message to the window, which means that Windows calls the window message handler. However, the Windows program also has a message loop, which calls GetMessage to remove the message from the message queue, and call DispatchMessage to send messages to the window message handler. Then, the Windows program is waiting for the message (similar to the same keyboard input in a normal program), then send the message to a certain place? Or, do it receive messages directly from the program? In fact, both situations exist. The message can be divided into "serialized" and "non-sequential". Serialized messages are placed in the program message queue from Windows. In the message loop of the program, it is reused and assigned to the window message handler. Non-serialized messages are sent directly to the window message handler when Windows calls the window. That is, the serialized message is "transmitted" to the message queue, rather than serialization, "Send" to the window message handler. In any case, both the window message handler will obtain all messages of the window - including serialized and non-sequentialized. The window message handler is the "Message Center" of the window. The serialization message is basically the result of the user input to hit the key (such as a WM_KEYDOWN and WM_KEYUP messages), the characters generated by the keystroke (WM_CHAR), the mouse movement (WM_MOUSEMOVE), and the mouse button (WM_LBUTTONDOWN) are given. The serialization message also includes a clock message (WM_TIMER), updated message (WM_PAINT), and exit message (WM_QUIT). Non-serialized messages are other messages. In many cases, non-serialized messages come from calling a specific Windows function. For example, when WinMain calls CREATEWINDOW, Windows will establish a window and send a WM_CREATE message to the window message handler in the process. When WinMain calls ShowWindow, Windows will send a WM_SIZE and WM_SHOWWINDOW message to the window message handler. When WinMain calls UpdateWindow, Windows will send a WM_PAINT message to the window message handler. The 伫 伫 message signal sent when the keyboard or mouse input is input, and can also appear in the inlet message. For example, when selecting a functional entry with a keyboard or mouse, the keyboard or mouse message is gratiating, and the WM_COMMAND message selected by the functional entry may be non-serialized. This process is obviously complicated, but fortunate is that most of them are solved by Windows, things that are not our program. From the perspective of the window message handler, these messages are in an orderly, synchronous manner. The window message handler can handle them or not. When I said the news is in an orderly synchronization method, I said that the first message is different from the hardware interrupt. When processing a message in a window message handler, the program will not be suddenly interrupted by other messages. Although the Windows program can perform multi-performing, each executed message queue is only for the window message handler executes the window processing message in this execution. In other words, the message loop and the window message handler are not executed concurrent.

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

New Post(0)