[Development Summary] MFC/COM technology application (8)

Source: Internet
Author: User

I. Learn from the New-MFC framework

1) rtti & Dynamic create

Brief description:

Bytes ----------------------------------------------------------------------------------------------

It is used to describe two key technologies of MFC: rtti (runtime type information) runtime type recognition and dynamic generation of dynamic create object.

Implementation Mechanism:

Cruntimeclass: this structure is a built-in type of MFC. Its main functions are as follows:

When defining a user type, this structure is used to record the user type name and object creation function address. All user type information in the system is saved through this structure, and a "type identification network" (actually a linked list) is formed ).

If the declare_dyncreate () and implement_dyncreate () macros are added to the. h and. cpp files of the user type, they are equivalent:

1. created a global cruntimeclass schema instance (Name: class # class name ).

2. This instance records two important information of this user type:

User Type name (m_lpszclassname)

Object creation function pointer (m_pfncreateobject)

3. use the pointer m_pbaseclass to point to the "Type Recognition object" (classbaseclass) of the base class, and use m_pnextclass to point to the next "Type Recognition object ", in this way, the user type "Type Recognition object" is added to the global "type recognition network" (linked list.

4. The first pointer to the "type recognition network" (linked list) is: cruntimeclass: pfirstruntimclass, which is a global type. The system uses this global pointer to traverse the "type recognition network" (linked list ). Rtti Type Recognition: traverse the "type recognition network" (linked list) and compare the cruntimeclass type pointer or type name lpszclassname ). for example, pobj-> iskindof (runtime_class (cmyclass); Dynamic create dynamic creation: traverse the "type recognition network" (linked list), and use the comparison type name (m_lpszclassname ), find the corresponding object creation function pointer (m_pfncreateobject), dynamically create the object, and return the "base class Pointer ". (When creating an object, you only need the information provided in the "type recognition network" and do not rely on any type information.) the preceding information may differ from the actual application details, but the general principle should be like this. 2) Message Mapping

Message loop of traditional SDK programs 
In traditional SDK programs, the message loop is very simple. In winmain, createwindow associates the created window with the window class through a parameter, in this way, all messages in the window will be sent to the window function wndproc of the window class, and then wndproc will give different actions based on different messages.

Message loop expected by MFC
In traditional SDK programs, message loops are very simple, and windows and window functions are bound together. In MFC, a problem occurs. For example, the cdocument class is not a window, so there is no window class. But I also want it to respond to messages. How can this problem be solved? The problem is not just that. Let's look at the message of MFC and we will find more problems.
MFC divides messages into three categories: 1. A standard message, such as a message starting with WM _, can be accepted by any class derived from cwnd. command message, that is, wm_command, any class derived from c1_target, and can accept the message. 3. A notification message, control notification, also appears in the form of wm_command, which is generated by the Control and notifies its parent window. In MFC, all classes that can receive messages must inherit from the csf-target class, because these classes share a common feature: Three macros, including declare_message_map, begin_message_map, and end_message_map (macro definition, it is very convenient to view in MFC, which is not listed here). These three macros organize a large message ing Network. For example:

The roles of declare_message_map, begin_message_map, and end_message_map are as follows:

"Message ing array": records messages and corresponding processing functions.

"Ing table": uses the pbasemap pointer in afx_msgmap to connect various types in the inheritance order to form a message ing Network to provide the path for message flow.

We have established a message flow network, but how does a message receive it from the message generation to the response function? In any case, it is the same for Windows systems. It uses getmessage (or other) to retrieve messages from the message queue, and then uses dispatchmessage to send messages to the window function. In "The Birth of window classes", we know that MFC registers all window processing functions as defwndproc. Does it send all the messages to defwndproc? Sorry, no, but all sent to the afxwndproc function. You may ask why, this is what I want to know. Let's look at the window creation process in the following sequence diagram:

The starting point of a message is the afxwndproc function. All messages are sent to afxwndproc, and they are routed from afxwndproc to their respective message response functions again. How does one stream? Let's see:

If the message is a standard message (wm_xxxx), it is directly sent to the target window for receiving the message in the cwnd: onwndmsg function. If it is a "notification message", go to the c0000target: on0000msg function (the getmessagemap function in it is a virtual function) and search for its own ing table, as shown in the following figure:

Figure 1 transition flow of messages ---------------- 2. Automation Object --- Component Technology Application. Automation is an advanced application based on COM technology. The essence of automation (simplest understanding): It inherits the interface of the idispatch interface. In the end, automation aims to eliminate the dependency on the type information during the compilation period (Com also has CLSID/IID/TLB/h dependency), and uses the "name" for the later stage (runtime) the technology of binding function addresses and parameter type verification. Generally, COM is used to help with the late stage through the virtual table in the memory, but it still needs to import the type information (# import) during compilation ). with the automation technology, in the script language and explain Execution Language, the automation object can be conveniently called without any type of information. Only know progid (string) is enough (progid = "component name. class Name) to create an automated object: In MFC, it provides great convenience for application automation technology and is very easy to use. 1. Select Automation 2 when creating regulardll of MFC. Create a user class that inherits from csf-target. After the interface is created, the MFC system automatically generates an interface dispinterface, whose information is saved in the odl file (similar to the IDL file of COM), and generates an implementation class for the interface, this class name has the same name as the interface (the interface and the implementation class are in a one-to-one relationship ). The association between them is estimated to be achieved through macro or MFC internal mechanism. 3. The rest is the declaration and implementation interface. In this way, an automatic object is created. Call automation objects: There are two common ways to lower the value of vc6.0: 1. Coledispatchdriver * pdriver = new (); pdriver-> createdispatch (component name. Class Name); pdirver-> invokehelper (function index, dispatch_method ,...); This call does not have a type dependency, but is bound late through an index or function name. 2. Coledispatchdriver ). in the class creation wizard window, select the 'automation 'page and click "add class... ", select the automatically packaged TLB or DLL file. After confirmation, the MFC system automatically generates a packaging class inherited from the coledispatchdriver. The class name is the interface name in TLB. MFC directly uses the function of this packaging class. Each function actually calls invokehelper and transfers it to the Automation Object. The key point is that after createdispatch is called, the packaging class saves the interface pointer of the automation object to m_lpdispatch, the member of the packaging class, and the packaging class transfers the call through the member. I personally think that the call method still has "TLB type dependency ". It is simpler to avoid the troublesome parameters of invokehelper during the call. A little wordy. Haha. For automation, the <ATL Development Guide> book is clear and easy to understand.


To be continued ......

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.