In-depth Windows Kernel-message mechanism in C ++

Source: Internet
Author: User

In-depth Windows Kernel-message mechanism in C ++

In the article "message mechanism of programming ideas", we talk about the concepts and Simulation of message mechanisms. This article will further discuss the message mechanism in C ++.

Exploring core principles from simple examples

Before speaking, let's take a look at a simple example: create a window and two buttons to control the background color of the window. The effect is as follows:


Figure 2:

 

Win32Test. h

# Pragma once # include
  
   
# Include
   
    
// Resource ID # define ID_BUTTON_DRAW 1000 # define ID_BUTTON_SWEEP 1001 // register the window class ATOM AppRegisterClass (HINSTANCE hInstance); // initialize the window BOOL InitInstance (HINSTANCE, int ); // message processing function (also called Window Process) lresult callback WndProc (HWND, UINT, WPARAM, LPARAM); // (white background) button event void OnButtonWhite (); // (gray background) button event void OnButtonGray (); // draw event void OnDraw (HDC hdc );
   
  

Win32Test. cpp

# Include stdafx. h # include Win32Test. h // character array length # define MAX_LOADSTRING 100 // global variable HINSTANCE hInst; // the current instance TCHAR g_szTitle [MAX_LOADSTRING] = TEXT (Message process ); // window title TCHAR g_szWindowClass [MAX_LOADSTRING] = TEXT (AppTest); // window class name HWND g_hWnd; // window handle bool g_bWhite = false; // whether it is a white background // The WinMain entry function int APIENTRY _ tWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {UNRE FERENCED_PARAMETER (hPrevInstance); UNREFERENCED_PARAMETER (lpCmdLine); // register the window class if (! AppRegisterClass (hInstance) {return (FALSE);} // initialize the application window if (! InitInstance (hInstance, nCmdShow) {return FALSE;} // message loop MSG; while (GetMessage (& msg, NULL, 0, 0) {TranslateMessage (& msg ); dispatchMessage (& msg);} return (int) msg. wParam;} // register the window class ATOM AppRegisterClass (HINSTANCE hInstance) {WNDCLASSEX wcex; wcex. cbSize = sizeof (WNDCLASSEX); wcex. style = CS_HREDRAW | CS_VREDRAW; wcex. lpfnWndProc = WndProc; wcex. cbClsExtra = 0; wcex. cbWndExtra = 0; wcex. h Instance = hInstance; wcex. hIcon = LoadIcon (NULL, IDI_APPLICATION); wcex. hCursor = LoadCursor (NULL, IDC_ARROW); wcex. hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); wcex. lpszMenuName = NULL; wcex. lpszClassName = g_szWindowClass; wcex. hIconSm = NULL; return RegisterClassEx (& wcex) ;}// Save the instantiation handle and create the BOOL InitInstance (HINSTANCE hInstance, int nCmdShow) {hInst = hInstance; // save handle to the global variable g_hWnd = CreateWind Ow (g_szWindowClass, g_szTitle, WS_OVERLAPPEDWINDOW, 0, 0,400,300, NULL, NULL, hInstance, NULL); // create the button HWND hBtWhite = create1_wex (0, LButton, L white, WS_CHILD | WS_VISIBLE | BS_TEXT, 100,100, 50, 20, g_hWnd, (HMENU) ID_BUTTON_DRAW, hInst, NULL); HWND hBtGray = create1_wex (0, LButton, L gray, WS_CHILD | WS_VISIBLE | BS_CENTER, 250,100, 50, 20, g_hWnd, (HMENU) ID_BUTTON_SWEEP, hInst, NULL); if (! G_hWnd) {return FALSE;} ShowWindow (g_hWnd, nCmdShow); UpdateWindow (g_hWnd); return TRUE;} // (window) message Processing lresult callback WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) {case WM_COMMAND: wmId = LOWORD (wParam ); // wmEvent = HIWORD (wParam); switch (wmId) {case when: OnButtonWhite (); break; case ID_BUTTON_SWEEP: OnButtonGray (); break; default: return DefWindowProc (hWnd, message, wParam, lParam);} break; case WM_PAINT: hdc = BeginPaint (hWnd, & ps); OnDraw (hdc); EndPaint (hWnd, & ps); break; case WM_DESTROY: PostQuitMessage (0); break; default: return DefWindowProc (hWnd, message, wParam, lParam);} return 0 ;} // event processing // event void OnButtonWhite () {g_bWhite = true; InvalidateRect (g_hWnd, NULL, FALSE) When hBtWhite is pressed ); // refresh window} // event void OnButtonGray () {g_bWhite = false when hBtGray is pressed; InvalidateRect (g_hWnd, NULL, FALSE ); // refresh window} // draw events (re-draw images upon each refresh) void OnDraw (HDC hdc) {POINT oldPoint; SetViewportOrgEx (hdc, 0, 0, & oldPoint ); RECT rcView; GetWindowRect (g_hWnd, & rcView); // get the canvas size of the handle HBRUSH hbrWhite = (HBRUSH) GetStockObject (WHITE_BRUSH); HBRUSH hbrGray = (HBRUSH) GetStockObject (GRAY_BRUSH ); if (g_bWhite) {FillRect (hdc, & rcView, hbrWhite);} else {FillRect (hdc, & rcView, hbrGray);} SetViewportOrgEx (hdc, oldPoint. x, oldPoint. y, NULL );}

In the preceding example, the message flow process is as follows:


Figure 3: Message Flow Process
This is consistent with Figure 1 (message mechanism principle) in message mechanism of programming thoughts. This is the core part of Windows message mechanism and is also the core part of Windows API development. Both Windows and Windows programs are message-based and event-driven.
RegisterClassEx registers a window. You must register a unique identifier with the windows system before calling CreateWindow to create a window.

 

while (GetMessage(&msg, NULL, 0, 0)){    TranslateMessage(&msg);    DispatchMessage(&msg);}

This while loop is a message loop that continuously retrieves messages from the message queue and distributes messages through DispatchMessage (& msg. Message Queue is defined in the Windows operating system (we cannot see the corresponding defined code). For every running Windows application, the system creates a message queue for it ", the application queue is used to store messages in various Windows that may be created by the program. DispatchMessage transmits the message to the window function (namely, the message processing function) for processing, that is, the WndProc function. WndProc is a callback function. In the registration window, wcex. lpfnWndProc is passed to the operating system. Therefore, after DispatchMessage is sent, the operating system calls the window function (WndProc) to process the message. For more information about callback functions, see callback functions.
Each window should have a function responsible for message processing, and the programmer must be responsible for designing this so-called window function WndProc.LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)The four parameters in are the relevant information of the message (the handle from which the message comes from, the message type, etc.). In the function, switch/case are used to process different messages based on different types. After receiving a message of the corresponding type, you can call the corresponding functions for processing, such as OnButtonWhite, OnButtonGray, and OnDraw. This is the prototype of event processing. DefWindowProc is called in default, and DefWindowProc is the default message processing function defined by the operating system. This is because all messages must be processed, and messages not processed by applications must be handed over to the operating system for processing.

Message definition and type

Windows messages are prefixed with WM _, which means "Windows Message", such as WM_CREATE and WM_PAINT. The message is defined as follows:

Typedef struct tagMsg {HWND hwnd; // The Window handle UINT message that receives the message; // message constant identifier, which is also known as the message number WPARAM wParam; // The specific additional information of a 32-bit message. The exact meaning depends on the message value LPARAM lParam; // The specific additional information of a 32-bit message. The exact meaning depends on the message value DWORD time; // The time when the message was created, POINT pt; // The cursor/cursor position in the screen coordinate system when the message was created} MSG;

There are three types of messages:
1. Command Message (WM_COMMAND): Command message is a command that the programmer needs to perform some operations on the program. All messages generated by the UI object are such command messages, which may come from menus, acceleration keys, or toolbar buttons and are displayed as WM_COMMAND.
2. Standard window message: Except for WM_COMMAND, all messages starting with WM _ are in this type. Standard window messages are the most common messages in the system. They are the messages used by the operating system and windows that control other windows. For example, CreateWindow, DestroyWindow, and MoveWindow will trigger window messages, move the mouse, and click, and keyboard input all belong to these messages.
3. Notification: this message is generated by the control to notify its parent window (usually a dialog box window) of a certain situation. When something happens to the child control in a window, which requires notifying the parent window, it will be playing now. The notification message is only applicable to standard window controls such as buttons, list boxes, Combo boxes, and edit boxes, as well as Windows public controls such as tree views and list views.

Queue messages and non-queue messages

In Windows, there is a system message queue. For every running Windows application, the system creates a "message queue" for it, that is, the application queue, stores messages of various Windows that may be created by the program.
(1) queue message (Queued Messages)
The message is saved in the message queue first, and the message is obtained from the Message Queue through the message loop and distributed to various window functions for processing. For example, the mouse and keyboard messages belong to such messages.
(2) Non-queue message (NonQueued Messages)
The message is directly sent to the window function for processing without passing through the message queue. Such as WM_ACTIVATE, WM_SETFOCUS, WM_SETCURSOR, and WM_WINDOWPOSCHANGED.

Difference between PostMessage and SendMessage

The message sent by PostMessage is a queue message, which will Post the message to the Message Queue. The message sent by SendMessage is a non-queue message and is directly sent to the window for processing, messages are returned only after they are processed.


Figure 4: Message Queue

  <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxwPs6q1qTD99Xi0ru5/bPMo6zO0sPHv8nS1LjEtq/Su8/Cyc/fingerprint + DQo8cHJlIGNsYXNzPQ = "brush: java;"> #define ID_BUTTON_TEST 1002

2. Do not use SendMessage or PostMessage to send messages in OnButtonWhite.
// Event when hBtWhite is pressed

Void OnButtonWhite () {g_bWhite = true; InvalidateRect (g_hWnd, NULL, FALSE); // refresh the SendMessage (g_hWnd, WM_COMMAND, ID_BUTTON_TEST, 0) window; // PostMessage (g_hWnd, WM_COMMAND, ID_BUTTON_TEST, 0 );}

3. Add the ID_BUTTON_TEST judgment in the message loop.

while (GetMessage(&msg, NULL, 0, 0))    {        if (LOWORD(msg.wParam) == ID_BUTTON_TEST)        {            OutputDebugString(LThis is a ID_BUTTON_TEST message.);    // [BreakPoint1]        }        TranslateMessage(&msg);        DispatchMessage(&msg);    }

4. Add the ID_BUTTON_TEST judgment in the window processing function WndProc.

case ID_BUTTON_TEST:    {        OutputDebugString(LThis is a ID_BUTTON_TEST message.);        // [BreakPoint2]    }    break;case ID_BUTTON_DRAW:    OnButtonWhite();    break;case ID_BUTTON_SWEEP:    OnButtonGray();    break;

Using breakpoint debugging, we found that the ID_BUTTON_TEST message sent by SendMessage only enters BreakPoint2, while the ID_BUTTON_TEST message sent by PostMessage enters BreakPoint1 and BreakPoint2.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.