Window message processing and window Message Processing
We know that an application generally consists of not only one window, but also multiple windows. For example, a button is displayed in a dialog box, where a dialog box is a window, the button is also a window. If a dialog box contains 100 buttons, that is, 100 windows, there will be more handles. Therefore, the DirectUI design method appears. All buttons and the main window are painted in the same window in different areas. Here we encountered a problem where each window exists independently, but in the previous example, we can see that each window is handled by calling the PyWndProc function. This means that messages in multiple windows are sent to the PyWndProc function for processing, which will only increase and become more complex. From the perspective of object-oriented design, can there be a better solution? This is acceptable. Because a user data field is reserved for each window in Windows, you can associate the relationship between each window and the message class by using this field. For example, window 1 calls the class of window 1 to process messages, and window 2 calls the class of window 2 to process messages, so that the independence of each window is guaranteed, do not worry that the message in window 1 will go to window 2. To this end, I declare a class Controller that uses this class to process window messages. Of course, different windows can inherit this class, and other window messages can be processed. After creating an instance like Controller, save the instance object to the GWL_USERDATA field in the window. Refer to Windows API one-day training to introduce Window Creation functions, as shown below:
HWND createmediawex (
DWORD dwExStyle, // extended window style
Maid, // pointer to the registration Class Name
Lptstr lpWindowName, // pointer to the window name
DWORD dwStyle, // window style
Int x, // horizontal position of the window
Int y, // the vertical position of the window
Int nWidth, // The window width
Int nHeight, // The window height
HWND hWndParent, // handle of the parent window
HMENU hMenu, // the handle of the menu or the identifier of the sub-Window
HINSTANCE hInstance, // handle of the application instance
LPVOID lpParam // point to the data created in the window
);
The last field lpParam of this API function is to point to the user-defined data in the window. Here, I put the pointer of the message processing class object here, each window can have its own message processing class.
The definition class Controller is as follows:
class Controller: def __init__(self): self.hWnd = HWND() def SetWnd(self, hWnd): self.hWnd = hWnd def MyWndProc(self, hWnd, Msg, wParam, lParam): if Msg == WM_DESTROY: windll.user32.PostQuitMessage(0) return 0 else: return windll.user32.DefWindowProcW(hWnd, Msg, wParam, lParam)
In class Controller, there are mainly member variables self. hWnd is used to save the handle of each window. The member function MyWndProc is used to process messages in each window. If the window is not processed, the messages are passed to the Windows System for default processing, the default message processing function is the DefWindowProcW function. Because there are a lot of messages in a window, not every window needs to process so many messages, so it is very convenient to process only what is needed.
I want to send a message to the main window from the dialog box and process the message. My code is wrong.
Your dialog box is not created, so the call is incorrect.
GetParent ()-> SendMessage (WM_COMMAND, 8 );
Change to the following:
Save the call pointer during construction. Your dialog box is called in View.
DialogDia dlg (this); // input a pointer when calling.
Dlg. DoModal ();
DialogDia: DialogDia (CWnd * pParent)
: CDialog (130, pParent)
{
M_pWnd = pParent; // declare a member variable to save the pointer.
}
Send the message as follows:
If (m_pWnd)
M_pWnd-> SendMessage (WM_COMMAND, 8 );
Cainiao's conjecture about windows, message loops, and threads
Each window corresponds to a message processing function.
The number of while (...) {...} in a message loop does not have any relationship with the number of windows and the number of message processing functions. That is, the number of message loops does not refer to the number of windows, and vice versa.
One thread has at most one message loop. If the code on this thread executes window class registration and window creation, the thread must have a message loop. Then, in the loop, DispatchMessage will be called. This function is used to find the message processing function associated with HWND. After it is found, the corresponding message processing function is called within DispatchMessage.
Either the main window or the control will have a message processing function. As long as these windows are created on a thread, the message loop of the thread will be processed by the same DispatchMessage. There are no multiple message loops and multiple dispatchmessages.
Lemonbox says "each window has its own message stack", which is not correct. This interpretation can only better affirm the paradox proposed by the landlord!
Frank7258 states that "no message loop exists in other Windows except the modal dialog box" and the meaning is unclear, which makes the description more confused.
A thread has a message loop and a thread stack (which is maintained by the Windows operating system). How can there be no message loop in the window? The Windows operating system is not responsible for calling message processing functions. Windows only finds the thread after receiving the message, and then pushes the message to the Message stack corresponding to the thread. As for the call, it is implemented by the programmer in the code, that is, write a message loop, and retrieve the messages in the message stack (through GetMessage, PeekMessage) in the loop ), then, the message processing function of the main window or control is indirectly called through DispatchMessage.
The term "message pump" is used by many books and MSDN documents. In the modal dialog box, the DialogBox, DialogBoxParam, DialogBoxInderect, and DialogBoxInderectParam (MFC is DoModal) functions create a message pump inside the function, this also explains why these functions are not returned before the dialog box is closed. The format is as follows:
DoModal (...){
// The dialog box manager is responsible for message loop.
While (...){...}
}
As long as the dialog box is not destroyed, While is always in the loop, how does DoModal exit?
For DialogBoxXXX family functions, the internal use of DLGPROC is different from the traditional WINDOWPROC. DLGPROC is maintained by the dialog box manager.
In addition, the message stack statement helps you understand and use it. In fact, strictly speaking, the message stack is incorrect, because the stack must come first and foremost. However, after a message is written into the stack, it is not the last one, but the first one is taken out. GetMessage and PeekMessage use a set of message priority policies internally to call up messages with higher priority. This is similar to thread scheduling. The scheduling policy is not publicly available by Microsoft, so we don't have to understand it. The reason for not publishing is very simple. If it is made public, the code written by many people will depend on this policy. However, Microsoft may use the new operating system version to fix System bugs or improve system performance, or the reason why the system expands to a mess and changes the priority policy for extracting messages, these policy-dependent code won't work as expected by the original code writing. Therefore, either the message stack or the message queue is correct or incorrect. This statement is intended for our communication at ordinary times. It is not professional and does not have to stick to "stacks or queues ". What do you think .... Remaining full text>