// A simple Win32 Application
// Use this simple example to explain how messages are transmitted in Windows.
# Include "stdafx. h"
# Include <windows. h>
// Declare Window Process Functions
Lresult callback WndProc (HWND, UINT, WPARAM, LPARAM );
// Define a global variable as the window class name
TCHAR szClassName [] = TEXT ("SimpleWin32 ");
// Main function of the application
Int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR szCmdLine,
Int iCmdShow)
{
// Window class
WNDCLASS wndclass;
// Re-paint the entire window when the width of the horizontal direction of the window and the height of the vertical direction change
Wndclass. style = CS_HREDRAW | CS_VREDRAW;
// Associate Window Process Functions
Wndclass. lpfnWndProc = WndProc;
Wndclass. cbClsExtra = 0;
Wndclass. cbWndExtra = 0;
Wndclass. hInstance = hInstance; // instance handle
Wndclass. hIcon = LoadIcon (NULL, IDI_APPLICATION); // icon
Wndclass. hCursor = LoadCursor (NULL, IDC_ARROW); // cursor
Wndclass. hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); // painter
Wndclass. lpszMenuName = NULL; // menu
Wndclass. lpszClassName = szClassName; // Class Name
// Register the window class
If (! RegisterClass (& wndclass ))
{
MessageBox (NULL, TEXT ("RegisterClass Fail! "),
SzClassName, MB_ICONERROR );
Return 0;
}
// Create a window
HWND hwnd;
Hwnd = CreateWindow (szClassName, // window class name
TEXT ("The Simple Win32 Application"), // window title
WS_OVERLAPPEDWINDOW, // window style, that is, the windows window style we usually use
CW_USEDEFAULT, // specifies the initial horizontal position of the window, that is, the X coordinate in the upper left corner of the window in the screen coordinate system.
CW_USEDEFAULT, // specifies the Initial vertical position of the window, that is, the Y coordinate in the upper left corner of the window in the screen coordinate system.
CW_USEDEFAULT, // The window width
CW_USEDEFAULT, // window height
NULL, // parent window handle
NULL, // Window menu handle
HInstance, // instance handle
NULL );
ShowWindow (hwnd, iCmdShow); // display window
UpdateWindow (hwnd); // display the window now
// Message loop
MSG msg;
/*
GetMessage () retrieves messages from the message queue and converts the acquired messages (TranslateMessage ),
For messages that can convert a virtual key code into a verification code, a WM_CHAR message is placed in the message queue,
Finally, the message is sent to the corresponding message processing function for processing.
This process is executed cyclically until the WM_QUIT message is received.
*/
While (GetMessage (& msg, 0) // retrieve the message from the Message Queue
{
TranslateMessage (& msg); // convert the message
DispatchMessage (& msg); // send a message
}
Return msg. wParam;
/* --------------- GetMessage ---------------------------------
GetMessage
Function prototype:
BOOL GetMessage (LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax );
Parameters:
LpMsg: a pointer to the MSG structure used to store messages taken from the message queue.
HWnd: Window handle. If this parameter is a non-zero value, GetMessage only retrieves messages in this window (including its subwindows). If it is zero, GetMessage retrieves messages in the entire process.
WMsgFilterMin: specify the minimum message value to be retrieved, that is, the downstream boundary parameter of the message range.
WMsgFilterMax: the upper limit parameter. If both wMsgFilterMin and wMsgFilterMax are zero, no message filtering is performed. GetMessage Retrieves all valid messages.
Return Value:
GetMessage: WM_QUIT message retrieved. The returned value is zero. In other cases, a non-zero value is returned.
Function:
This API function is used to extract a message from the message queue and put it in the variable referred to by lpMsg. (Note: If there is no message in the message queue of the retrieved window, the program will pause in GetMessage (...) Function .)
Let's talk about the GetMessage function in a more general sense:
When the program executes GetMessage (), it checks the message queue. If a message is in the message queue, It retrieves the message and fills the message in the MSG structure specified by lpMsg, returns TRUE. If there is no message in the message queue at this time (the message queue is empty), it will block the thread, that is, hand over the control to the system until there is content in the message queue, the thread will be awakened to continue the execution.
For the GetMessage () function, another note is that when the message retrieved from the message queue is WM_QUIT, the return value of the function is 0. We usually use this to exit the message loop and end the program.
---------------------------------------------------------------*/
/* ------------------ TranslateMessage ---------------------
TranslateMessage
Function prototype:
BOOL TranslateMessage (const msg * lpMsg );
Parameters:
IpMsg: pointer to the MSG structure, which is the message obtained from the message queue by the function GetMessage or PeekMessage.
Function:
This function converts a virtual key message to a character message. The character message is sent to the Message Queue of the calling thread and is read when the current thread calls the GetMessage or PeekMessage function.
What is a virtual key code? To facilitate input management and reduce program dependencies on devices, Windows maps all the buttons on the keyboard with a two-digit hexadecimal number, which is called a virtual key code. Generally, the virtual key code starts with VK _. For example, the virtual key code corresponding to the Esc key is VK_ESCAPE, the virtual key code corresponding to the Space key is VK_SPACE, And the VK_LWIN corresponds to the Windows logo key on the left.
When a key is pressed, The WM_KEYDOWN message is triggered. The wParam parameter value of the WM_KEYDOWN message is the virtual key value. This value can be used to determine which key is pressed.
Why do we need to convert a virtual key code into a verification code?
For example, if we press the 'A' key, the character we get may be 'A' or 'A' in lower case, which is determined by Caps Lock) and whether Shift is pressed at the same time. The function of the TranslateMessage () function is to automatically return an ASCII code value based on these situations without considering these issues.
Not all the virtual key values will be translated into the escape code. Letter, number keys are relative to the primary code, and such as the direction of the arrow keys, F1-F12 function keys these buttons do not have the primary code corresponding. When the virtual key code needs to be converted to an ASCII code, the TranslateMessage () function places a WM_CHAR message in the message queue. The wParam parameter value of the WM_CHAR message is the converted ASCII code value.
-------------------------------------------*/
/* -------------------- DispatchMessage -------------------
DispatchMessage
Function prototype:
LONG DispatchMessage (const msg * lpmsg );
Function:
The function is simple, that is, the message processing function that distributes messages to the window is executed.
-------------------------------------------*/
/* --------------- PeekMessage -------------
PeekMessage
Function prototype:
BOOL PeekMessage (LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg );
Parameters:
The four parameters lpMsg, hWnd, wMsgFilterMin, and wMsgFilterMax have the same meanings as the parameters corresponding to GetMessage.
WRemoveMsg: this parameter determines whether to delete a message when reading the message. Optional values include PM_NOREMOVE and PM_REMOVE. If you select PM_NOREMOVE, after the function is executed, the message remains in the Message Queue (read message); if you select PM_REMOVE, after this function is executed, the message will be removed from the Message Queue (same as GetMessage ()).
Return Value:
If there is a message in the message queue, the return value is TRUE. If there is no message in the message queue, the return value is FALSE.
Function:
PeekMessage () is also used to retrieve messages from the message queue, but it is GetMessage (), mainly in the following two points:
(1) GetMessage () can only remove messages from the message queue. That is, after GetMessage () is executed, the message will be removed from the message queue.
PeekMessage () can be used to remove messages from a message queue. You can also read messages to keep them in the message queue.
(2) When there is no message in the message queue, GetMessage () will block the thread and wait for the message. If PeekMessage () is different from GetMessage (), it will return immediately after execution, if a message exists in a message queue, the return value is TRUE. If no message exists in the message queue, the return value is FALSE.
------------------------------------*/
/* ------------------- Message loop of PeekMessage version ---------------------------
// Message loop
MSG msg;
While (true)
{
If (PeekMessage (& msg, NULL, PM_REMOVE) // retrieves a message from the Message Queue
{
If (msg. message = WM_QUIT)
Break;
TranslateMessage (& msg); // convert the message
DispatchMessage (& msg); // send a message
}
Else
WaitMessage ();
} // End of while (true)
*/
/* ------------------ WaitMessage --------------------------
WaitMessage
Function prototype:
BOOL WaitMessage (VOID );
Function:
This function is used to give control to other threads when there is no message in the message queue. This function will suspend the thread until there are new messages in the message queue.
This function is specially used with PeekMessage. When no message exists in the message queue, the thread is suspended, waiting for the arrival of new messages in the message queue, which can reduce the computing burden on the CPU.
--------------------------------------------------*/
}
// Message Processing Function
// Parameter: Window handle, message, Message Parameter, Message Parameter
Lresult callback WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// Process messages of interest
Switch (message)
{
Case WM_DESTROY:
// When the user closes the window, the window is destroyed, the program needs to end, and an exit message is sent to exit the message loop.
PostQuitMessage (0 );
Return 0;
}
// Default processing functions provided by the system for other messages
Return: DefWindowProc (hwnd, message, wParam, lParam );
}