NO MFC Programming 07 - Make an optimized message pump

zhaozj2021-02-16  44

The message pump is also a message loop, which should have one of the Windows programs that are based on event-based. Message Loop is the heart of the program, ensuring the normal operation of the program, which is probably as the structure below.

While (TRUE) {// internal processing}

It can be seen that it should be a constant loop, breaking its loop, can be used using Break.

The primary task of the message (handling) loop is of course the message in the detection message queue. You have two options, which is to use the peekMessage () or getMessage () function. However, these two functions are different, explain it below.

Remember the SLEEP () function? The previous tutorial is used to let the program suspend the implementation of a specific period of time. When you sleep, you will not bring any operational burden to the CPU, which is more scientific than the cycle.

GetMessage () is the principle, when you perform getMessage (), if there is a message in the message queue, it gets MSG and returns true. But if there is no news? It will take a little while sleep. When is it awake? Of course, when the system sends a message to your message queue, when is it returned, you can't predict as a program designer!

So, should it return to 0? Not right, a special case, if the code of the message it gets is wm_quit (wm_quit == 18), it returns 0, then you can use Break.

PeekMessage () is different, it is never lazy! There is a message in the queue, it returns true; there is no message, it returns false. Its logic is then simple!

WaitMessage () is specially prepared for PeekMessage (). In general, WaitMessage () is called when it is empty in the message loop. What is it used? Just like its name, wait for the message. Well, sleep, wait! (This can reduce CPU calculation burden)

When you come back, the message code is equal to WM_QUIT (WM_Quit == 18), you can use Break.

The following two example functions are actually the same, which one will you choose to do your message loop?

MSG msg; // Define the message carrier postquitMessage (0); // Send WM_QUIT to make the interrupt loop

// Use getMessage () case while (True) {if (! GetMessage (& MSG, NULL, 0, 0)) Break; // Other Processes}

PostquitMessage (0); // Send WM_QUIT to make interrupt cycles

// Example of using PeekMessage () {IF (PEEKMESSAG, NULL, 0, 0, PM_Remove) {if (msg.Message == WM_QUIT) Break; // Other Processing} else waitorage (); }

I will definitely choose the second because I can develop more independently. (A tip: Game program program usually makes its core computing part into a function, used instead of waitmessage () function)

The above example describes the basic framework of a message cycle, but I believe you know, it will not be as simple as it is. However, it will not be too complicated. Just add more than two functions, it is translateMessage () and DispatchMessage (). Translate is the meaning of transformation, what is the use of the entire function? Yes, it is to translate the virtual keycase to a character code (MSDN): Translates Virtual-Key Messages INTO Character Messages. What is Virtual-key? In fact, I have used it before detecting the global keyboard, which is the encoding of different keypad on the keyboard, used to distinguish each key button. Then the character code is actually a subset of the ASCII code. Implementation is that when the identification message needs to be transformed into a character code message, the function will post a message in the message queue (WM_CHAR == 258), because it is used to use the POST method, the sending message is to the most front. The virtual key to which to be transformed is acquired from the WPARAM of the original message, and the transformed character code is placed in the WPARAM of the WM_CHAR message.

For example, when the A key is pressed, it will issue a WM_KEYDOWN message, and with a virtual key code to help us know which key is pressed. However, the situation is pressed, more than one, according to different factors, may be uppercase "a", may also be lower-written "A", completely depending on whether it is opened to open the uppercase input (Caps Lock) and Press the Shift key at the same time. TranslateMessage () will automatically identify these situations, ensuring that the character code of the WM_CHAR message is the desired effect.

An example: If the key "7" is pressed, there is a SHIFT key, then the "7" ASCII code is not "7" ASCII code in the WPARAM of the transformed WM_CHAR message is "&" ASCII code.

There is no virtual key code (such as VK_Lshift) that corresponds to the ASCII code, is only copied directly to the WPARAM of the WM_CHAR message.

(I don't think of a simple function, I have to explain so many consecutive levels, not to say, "

In order to verify the above, I have modified the previous circle part of the detection system message.

Long i = 19, k = 0; // i is the initial value of the circulation coefficient, K is used to record how many messages have been accepted

While (i) // Cycle Coefficient I exits {IF (PEEKMESG, NULL, 0, 0, PM_REMOVE)) {

WSPrintf (TEMP, "detected the% LD number message / n" "first parameter wparam =% ld;" "Second parameter lparam =% ld; / n" (system time) msg.Time =% ld; " "The handle involved) msg.hwnd =% ld / n / n", msg.message, msg.wparam, msg.lparam, msg.time, msg.hwnd; lstrcat (result, temp); k ; // Added to the result string after IF (TranslateMessage (& MSG)) // Newly join the translateMessage () function {WSPRINTF (TEMP, "/ n Note! The% LD number is translate or" "" WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP related "/ N / n / n", msg.Message); LSTRCAT (Result, Temp); // Add to Result String}} // End Of (peekmessage (...

I - // The cycle factor is reduced by 1, with 0 exit}

Through the sense of understanding, I think translateMessage () actually resends WM_CHAR when appropriate! However, if not it, many windows don't work. I don't know why, let's leave it.

Then the next is the DispatchMessage () function, view the explanation of MSDN, which is desencing the message processing function assigned to the window.

This is not difficult to explain, but you must first explain the window processing function (Window Procedure), one program can create multiple windows at the same time, which has different processing methods for the message, so you have to define your own message processing. WINDOW Procedure.

However, the message sent to these windows is unified to the same message queue. In the same message structure, msg.hwnd is in the message structure indicates which window is related to which window is associated with this guarantee message assignment process, Will not go wrong!

In this window, the "edit" class created, its message processing function has been pre-defined, and later introduces the method you define it, it is to invoke the registerclassex () function to be implemented. Temporarily sell a Cat, don't want to make it anymore.

The source program of the optimized message pump is given below:

// file name: WinMain.cpp

#define Win32_Lean_and_mean // Say No To Mfc !!

#include

CHAR TEMP [77] = "Hello World";

Char title [] = "Sample __copyright -` Sea Breeze "; // name: WinMain () Main Entrance // ------------------------- - --------- Int WinApi Winmain (Hinstance Hinstance, Hinstance Hprevinstance, LPSTR LPCMDLINE, INT NCMDSHOW) {

// *

// create the following using CreateWindowEx () function is a temporary window, use the hWnd temporarily stored handle HWND hWnd = CreateWindowEx (WS_EX_TOPMOST | WS_EX_TOOLWINDOW, "Edit", "1231", WS_OVERLAPPEDWINDOW, 120,120, 280,180, NULL, NULL, hInstance, NULL);

ShowWindow (hwnd, sw_show); // Let this window can be seen

MessageBox (NULL, "created a test window, press OK to continue testing!", Title, mb_ok | mb_topmost); // * /

Msg msg; / / define a structure of load messages

// Optimized Message Cyclic While (TRUE) {IF (PeekMessage (& MSG, NULL, 0, 0, PM_Remove) {if (Msg.Message == WM_QUIT) Break;

/ / Once you press the SHIFT button, send an exit message if (msg.Message == WM_KEYDOWN &WN &WPARM == VK_SHIFT) PostquitMessage (TRUE);

TranslateMessage (& MSG); else waitmessage ();} // end of while (true)

DestroyWindow (hwnd); // To destroy the window before exiting the program

MessageBox (NULL, "Test ended by OK", title, mb_ok | mb_topmost);

EXITPROCESS (0); return null;}

This program is not too long, the content is the most common thing!

Maybe you still don't know, in fact, a message pump is included in the messagebox () function. If you call the function, your message queue may be emptied!

... `Sea Breeze October 17, 2002 PM 6:01

----------------------------

At this moment, the hidden voice of the neighborhood came from the corridor "呔! 呔! 黄 招! 黄 射 射, 万 穿 穿!"

I can't help but laugh. Now the child is really powerful!

Songs are now listening to: Romant Sword Heart Ending - It's Gonna Rain

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

New Post(0)