MFC divides thread into winddow thread and worker thread. Before discussing Multi-thread, we only consider window thread.
The basic working method of windows programming is different from that of the console application. Basically, the program starts from WinMain () and then enters a message loop, the program waits for all the messages sent to it and then processes them one by one until the message WM_QUIT is received, the message loop ends, and the program ends. Therefore, the entire main program running process is to wait for the message, receive the message, and then process the message.
When the window is created, CreateWindow, RegisterWindow, and so on do not have to worry too much. MFC has been fully managed. Note that the HINSTANCE hInstance parameter at the beginning of the program, when dealing with DLL, it will help you solve many problems. If a Bitmap Load fails or a Dialog DoModal does not come out, you may have to ask for help from this parameter.
The function used to process a message is window procedure, and the code used to process the message is message handler. It can be the API of the current application or the API of different DLL calls. Different DLL files are called different modules. In future articles, I will detail the module state. Is a very important topic. (When the project is large)
Messages without message handler are handed over to the DefWindowProc () function for processing, so you can almost understand why.
The message includes four parameters: window handle, message ID, and wParam and lParam. Window handle can be used as the identification ID of window. Therefore, when sending a message, you can use either of the following formats:
CWnd * pWnd = ....
If (pWnd & pWnd-> GetSafeWnd ())
PWnd-> SendMessage (message, wParam = 0, lParam );
Or
SendMessage (pWnd-> GetSafeWnd (), message, wParam, lParam)
To send a Message, if SendMessage is used, the Message will be sent immediately. If PostMessage is used, the Message will be sent in the Message queue in the current order. Generally, there is no special requirement for PostMessage.
During Message processing, different message IDs are sent to different message handler for processing. Generally, the receiving format of Message handler is to use wParam to transmit a key parameter, for example, the specific ID of this operation, store a large amount of auxiliary information in lParam. It should be noted that if lParam passes a pointer (usually a CObject class or derived from CObject), the lifetime of the variable pointed to by this pointer must be long enough, because after the information is Post, the sending function may be completed. If the pointer sent is a local variable, the receiver will Crash. Of course, if it is a new variable from the sender, the receiver must delete it for him. This operation is dangerous and may not be appropriate. Sometimes the sender sends the information to N windows. It is troublesome to delete the first window and delete the second window. If the information is not deleted, it cannot be ensured that the second window will be deleted. If possible, new is not required. It is better to use member variables or constant variables.
Due to the various types of information that may be received, the conventional switch processing may appear messy in the program, so MFC uses the Message Map mechanism. The Message Map mechanism implements the ing of received information and information processing functions. Messages defined between BEGIN_MESSAGE_MAP and END_MESSAGE_MAP will be sent to the corresponding message handler one by one after receiving messages in the window.
All declarations for functions used to process information must have the afx_msg keyword. For the message to be processed by the system, ON_WN_XXX is generally followed by three parameters: WPARAM (wParam), LOWORD (lParam), and HIWORD (lParam). Unused parameters are ignored.
The following lists the macros that may be used in Message Map.
1. If the Message received by SendMessage or PostMessage between windows is to be managed by the system, ON_WM_XXX is generally used in Message Map. "XXX" is the message name. For example, the painting window is ON_WM_PAINT. For custom message ON_MESSAGE (). For example, the window pWndA sends a message to the window pWndB. PWndB-> PostMessage (WM_MYMSG1), then Window B needs to write ON_MESSAGE (WM_MYMSG1, OnMessage1) in the Message Map to process the message, and then write the OnMessage1 function as the Message handler. The WM_MYMSG1 definition should be placed in the user message, WM_USER + NNN. Note that it is best not to repeat other existing IDs. This cannot be checked automatically.
2. ON_COMMAND, ON_UPDATE_COMMAND_UI, ON_COMAND_RANGE
ON_COMMAND can be used either for menu or toolbar click processing or in accelerator. It is better to use ON_COMMAND to manage users' keyboard input than to manage ON_WN_CHAR. ON_UPDATE_COMMAND_UI is used to update the menu or toolbar. In this message handler, you can enable or disable the current menu options or toolbar button according to different requirements. ON_COMMAND_RANGE is mainly used in dynamic menu options. When N dynamic menu options are added, you can use a series of continuous IDS as their message management IDs. ON_COMMAND_RANGE defines the start and maximum values of these IDs, then the response function will know which dynamic menu option is selected.
3. ON_COMMAND_EX, ON_COMMAND_RANGE_EX
It is of little use. When multiple classes (cve-target class) need to process the same message, if ON_COMMAND_EX is used for processing a class, TRUE is returned, indicating that the message processing is complete. If FALSE is returned, other classes can continue processing.
4. ON_REGISTERED_MESSAGE
Used to confirm that the New message ID is unique in the system.
5. ON_CONTROL, ON_WM_XXX_REFLECT, ON_CONTROL_RANGE
The window is used to receive special messages from its control.