Message Mechanism in VC (3) (Transfer from PCVC Forum)

zhaozj2021-02-16  94

The method of processing of MFC messages is initially read in the MFC in the MFC, and the influence of the rooted C in the mind, we may naturally think that one of the three major characteristics of C : virtual mechanisms to achieve message delivery, But after analysis, we see that things don't think about what we think, in the MFC message is processed by a so-called message mapping mechanism.

why? Detailed reason is given in the "Visual C Technical Insider" (4th edition) of Pan Aimin teacher (4th edition). I briefly said. About 110 messages in the CWND class, there are other MFC classes, and there is too much news, and every derived class used in the program in C has a vTable, each virtual function is There is a 4-byte size entry address in vtable, so that each specific type of window or control is required, the application requires a 440KB size table to support the virtual message control function.

If the above window or control can be barely implemented, what is the message for the menu command message and button? How do we deal with different menus and buttons? This message mapping system in the MFC library avoids the use of large VTABLE, and can process a variety of applications for command messages that can be processed while processing conventional Windows messages.

To put it bluntly, the message mechanism in the MFC is a huge message and the corresponding table of its handle function, and then add some program code inside the application framework for this table. This can avoid programming in SDK The cumbersome CASE statement used.

The base class of the MFC message map CCMDTARGET must be derived from the CCMDTARGET class if you want your control to map mapping. The CCMDTARGET class is the basis of the MFC handling command message. MFC designs many member functions and some member data for this class. Basically to resolve message mapping issues, all response messages or events are derived from it, for example: application classes, framework, document classes, view classes And a wide variety of controls, etc., there are still many. However, 2 functions in this class are very important to message mapping, one is a static member function Dispatchcmdmsg, and the other is the virtual function oncmdmsg. DispatchCmdmsg is specifically used inside the MFC to distribute Windows messages. ONCMDMSG is used to transmit and send messages to update the status of the user interface object. CCMDTARGET's default implementation of OnCMDMSG: Search the message processing function of the specified command message in the message mapping array of the class and base class in the current command target (THIS). Here, use the virtual function getMessageMap to get the message map of the command target class mapping portal array _MessageEntries, and then match the command message ID in the array, the control notification code also the same message mapping entry. Where GetMessageMap is a virtual function, so you can confirm the exact class of the current command target. If you find a matching message mapping entry, use DispachCMDMSG to call this processing function; if you do not find it, use the _getBaseMessageMap to get the base class mapping array, find until you find or search for all the base classes (to ccmdtarget) If finally is not found, return FASLE. Each command target class derived from the ccmdtarget can overcmDMSG, use it to determine if a command can handle, if not, by calling the next command target's oncMDMSG, the command is sent to the next command target processing. Typically, when derived class overcmdmsg, the overcard mdmsg of the base class is to be called. In the MFC framework, some MFC command target classes overcmdmsg, such as the Frame window class overwrite the function, implements the MFC standard command message transmission path. If necessary, the application can override onCMDMSG, change the sending regulations in one or more classes, and implement a different transmission path to send a specified sector with the standard framework. For example, in the following cases, this can be processed: pass the command to a non-MFC default object in a class to interrupt the transmission order; in a new non-default object or in a command target that may be transmitted. The content of the message map is generated by classwizard, we can see that the message mapping is basically divided into 2 Most: There is a macro Declare_Message_Map () in the header file (.h), he is placed at the end of the class. It is a public attribute; the corresponding part is that the message mapping table is added in the implementation section (.cpp), the content is as follows: begin_MESSAGE_MAP (current class, current class base class) // {{AFX_MSG_MAP (CMAINFRAME) message Entry item //}} AFX_MSG_MAP END_MESSAGE_MAP () But only two items are still not enough to complete a message, if a message work, must have the following three parts: 1. Add corresponding functions in the definition of the class Declaration; 2. Add corresponding message mapping entry items in the message mapping table of the class; 3. Add corresponding functional bodies in the implementation of the class;

The addition of the news has been the above, and we will do our most familiar, the most commonly used work: Add a message. There are two ways to add MFC messages: Auto / Manual, we take these two ways as an example, say how to add messages. 1. Use the Class Wizard to automatically add automatically to the menu to select View -> Class Wizard, you can also use the right mouse button to select Class Wizard, which can also activate the Class Wizard. Select the Message Map tab, select the class we want to add messages from the Class Name Combination box. In the Object IDS list box, select the name of the class. At this point, the Messages list box displays most of the class (if not all) overloads the member function and window message. The class overload is represented in the upper part of the list, is represented by the case of the actual fiction member function. Other window messages, with uppercase letters, describe the message ID that the actual window can respond. Select the message we add, click the Add Function button, Class Wizard automatically adds the message. Sometimes, the message we want to add should appear in the Message list, but it is not found, what should I do? Don't worry, we can use the Class Wizard to extend the message list. In this page, find the Message Filter combo box, you can change the options in the Messages list box in the home page. Here, we choose Window, thereby display all window messages. In one case, you want to add the message can appear in the Message list box, if not, then look down :) 2, manual Add message processing function If we still can't see the message we want in the Messages list box, then the message may be ignored or created by the system. In this case, you must add it to yourself. According to the three components of the message work mentioned earlier: 1) Add a declaration of the process function in the class. Her, next to //}} AFX_MSG line, pay attention: To start with AFX_MSG. Typically, the best place to add a process function declaration is the table below the Class Wizard maintained in the source code, but the {{}} {{}} in its domain is marked. Anything in these parentheses will be destroyed by Class Wizard. 2) Next, locate //}} AFX_MSG_MAP line is found in the user class. The line is added to it. Similarly, it is also placed outside {{}} 3) Finally, an entity of the message processing function is added to the file.

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

New Post(0)