Create a frame step for COM server objects with MFC

zhaozj2021-02-08  262

Create a frame step for COM server objects with MFC

Task 1: Create the first COM server task 2: Call the COM interface task with VC 3: Call the COM interface task with VB 4: Add new properties and method tasks to the interface 5: Add a new custom interface task 6: Inherit the interface class

Example programs under TECSP / DOCS / SAMPLES / COMMFCDEMO

COM server: Commfcdemocom object: Codrawobj, Codrawobjline, CodrawobjRect

Task 1: Create the first COM server operation: 1. New project COMMFCDEMO, MFC AppWizard (DLL), Regular DLL Using Shared MFC DLL, Automation. Description: The basic framework of the COM server is established, including DllcanunloadNow (), DllGetObject (), DllgetObject (), DllgetObject (), DllgetObject (), DllgetObject (), DllgetObject (), DllgetObject (), DllGinterServer ().

2. Add mfcdual.h, mfcdual.cpp file (in the TECSP / COMM directory) in the project (in the TECSP / COMM directory) COMMFCDEMO_I.H "Description: Some macro definitions used to simplify programming are defined in mfcdual.h, reducing the repetitive labor of MFC COM programming. Maintaining the COM object interface in accordance with this document will be very easy and concise. Commfcdemo_i.h is the MIDL generated from the ODL file, including COM objects, interface definitions, guid definitions, and the like.

3. Compile Option Project => Settings ... => MIDL => Project Options Join: / h Commfcdemo_i.h MIDL will compile the ODL file generation Type library CommfcDemo.tlb, header file commfcdemo_i.h, define file commfcdemo_i.c.

Task 2: Add a COM object 1. Create a new class with Class Wizard: ccodrawobj, base class is ccmdtarget, select Createable by Type ID: CommfcDemo.codrawobj. Description: To avoid manually adding interface definitions, first select the automation interface, will automatically generate ODL files and corresponding interface definitions, just do a small amount of modification. Choosing the Createable By Type ID is to create a COM object through a class factory.

2. Modify the definition file IDualDrawObj odl of 2.1 [uuid (13144AD4-ECC8-46F4-88F7-2FAC305595EA)] dispinterface IcoDrawObj change: [uuid (13144AD4-ECC8-46F4-88F7-2FAC305595EA), oleautomation, dual] interface IcoDrawObj : IDispatch interface icodrawobj: idispatch Description: It is recommended to define the default interface of the COM object into a dual interface and can be used in a variety of environments.

2.2 Delete Properties: and Methods: These two rows 2.3 define properties and methods in {}

// iCodrawobj Properties: [PropPut, Helpstring "] HRESULT X ([In] short new_x); [Propget, Helpstring] HRESULT X ([OUT, RETVAL] Short * RET_X); // iCodrawobj method: [Helpstring "] HRESULT DRAW (); Description: The above comment should be reserved to facilitate the use of the interface inheritance; Helpstring is used for annotation for the attributes and methods, should be added; read-only properties Delete the two rows defined by the PropPut. Note that the writing method of the new_x and RET_X variables, the PUT property uses the new_ prefix plus the property name, and the get attribute uses the RET_ prefix to add the property name, which is for easy use of macro definitions to generate an attribute declaration and implementation.

Modify the definition of 2.4 coclass coclass coDrawObj {[default] dispinterface IcoDrawObj;}; change: coclass coDrawObj {[default] interface IcoDrawObj;}; 2.5 compiled file selection odl the FileView, comMFCDemo.odl right-click on a file, select Compile comMFCDemo. ODL, will generate type library commfdemo.tlb, header file command commando_i.h, and definition files commfcdemo_i.c. Join CommfcDemo_i.h and CommfcDemo_i.c to the project. Choose Project => Settings ... => Commfcdemo_i.c, select C / C => category: precompiled headers => not use for precompiled headers

3. Modify the COM object header file CODRAWOBJ.H file 3.1 Add the internal member variable corresponding to the property: protected, m_ prefix plus the property name Short M_x; 3.2 Interface declaration / / ============ = // Dual interface support start / / ============== // -------------------- // icodrawobj Interface declaration start // ----------------------

// This macro definition is to support interface inherit, add attributes and method #define declare_interface_part_icodrawobj / stdmethod (THIT_S) (this_ Short Far * RET_X); / stdmeth new_x); / stdmethod ( DRAW) (); /

Begin_dual_interface_part (CODRAWOBJ, ICODRAWOBJ) DECLARE_INTERFACE_PART_ICODRAWOBJ END_DUAL_INTERFACE_PART (CODRAWOBJ)

Need to modify: declare_interface_part_icodrawobj - iCodrawobj is interface name begin_dual_interface_part (Codrawobj, icodrawobj) - CODRAWOBJ is a component name, iCodrawobj is an interface name. End_dual_interface_part (CODRAWOBJ) - CODRAWOBJ is the component name, iCodrawobj is the name of the interface. // ---------------------- // iCodrawobj interface declaration end / / ------------------ ---- // Isupp Porterrorinfo Support DECLARE_DUAL_ERRORINFO () // ==========================================================================================================================================

Description: Need to note is the macro definition declare_interface_part_icodrawobj, and the end is the name of the interface. The macro is mainly used for interface inheritance, declares the properties and methods of the parent interface in the sub-interface declaration. The declarations of new properties and methods are also added in this macro definition.

3.3 Property Read and write realm description: The basic structure of the attribute read and write is very similar, to reduce the code book writing and writing errors, and use macro definitions. Require modification: Macro Definition Implement_properties_icodrawobj is for the interface inheritance, the end is the name of the interface. At present, two attribute reads and writings: normal attributes (short, float, etc.) Declare_put_property (objclass, baseclass, x) (short new_x) - Demand part: x is the attribute name, (short new_x) is the same as the declaration . Implement_put_property (Objclass, BaseClass, X) - Change part: x is the attribute name. DECLARE_GET_PROPERTY (OBJCLASS, BASECLASS, X) (short far * RET_X) - A change part: x is the property name, (short far * RET_X) is the same as the declaration. Implement_get_property (Objclass, BaseClass, X) - Change part: x is the property name.

Interface pointer properties The ADDREF method is called because the assignment of the interface pointer needs to be invoked, so this macro is given. The only difference between use is in the rear of Property to increase the _Interface suffix.

/ / ================ // Attribute read and write real presentation / / ====================================================================================================================================================================================

// --------------------------- // iCodrawobj attribute read and write real presentation // ----------- ----------------

#define IMPLEMENT_PROPERTIES_IcoDrawObj (objClass, baseClass) / DECLARE_PUT_PROPERTY (objClass, baseClass, x) (short new_x) / IMPLEMENT_PUT_PROPERTY (objClass, baseClass, x) / DECLARE_GET_PROPERTY (objClass, baseClass, x) (short FAR * ret_x) / IMPLEMENT_GET_PROPERTY (objClass, Baseclass, x) /// --------------------------- // iCodrawobj attribute read and write realization end / / ------ ---------------------

/ / ================ // Attribute read-write realization end // =================

/ / ============= // method implementation start / / ============

3.4 Method Implementation MFC Using Nested Categories Implementing Multi-Interface, the basic structure of the method is the same, so the macro definition is used to reduce code book writing and writing errors. Solution is that the method of each interface calls the same name function of the nesting parent class, so that all the implementations of the nested classes are all the same structure, and can be generated by macro definition. Each method creates a PROTECED VIRTUAL in the nested parent class to create an implementation file iCodrawobj.cpp named by an interface name, and put the implementation of the member function of the same name. This allows programmers to write only functional implementations in this file to achieve a unified control interface definition.

3.4.1 Nesting Method Implementing the macro definition of the following nested method implemented in the header file CODRAWOBJ.H back. Require modification: macro definition import_methods_icodrawobj is used for interface inheritance, and the end is the name of the interface. Stdmethodimp Objclass :: x ## Baseclass :: Draw () Final method name PTHIS-> DRAW (); final method name

/ / ============= // method implementation start / / ============

// ----------------------- // iCodrawobj method start // ----------------- --------

#define IMPLEMENT_METHODS_IcoDrawObj (objClass, baseClass) / STDMETHODIMP objClass :: X ## baseClass :: Draw () / {/ BEGIN_NEST_INTERFACE_FRAME (objClass, baseClass) / pThis-> Draw (); / END_NEST_INTERFACE_FRAME /} /

// ----------------------- // iCodrawobj method end / / ----------------- --------

/ / ============ / / method end / / ================= Nested parent class method implementation icodrawobj.cpp file sample (interface definition After completing, the programmer only needs to write function implementations in this file):

// icodrawobj.cpp

#include "stdafx.h" #include "CODRAWOBJ.H"

Void ccodrawobj :: Draw () {AFXMessageBox ("this is codeobj.");}

4. Modify CODRAWOBJ.CPP file 4.1 Constructor ColdRawobj () // Automation Support EnableAutomation (); // Aggregation Support EnableAggGREGATION (); 4.2 Deleting IID Definition Delete Similar to the following line, because the previous has been added to MIDL automatic generation We can manage all GUID definitions in a file. Static const Iid_icodrawobj = {0x13144AD4, 0xECC8, 0X46F4, {0x88, 0x10, 0x2f, 0xAc, 0x30, 0x55, 0x95, 0xEa}};

4.3 Multiple Interface Support Definition

will

Begin_Interface_map (ccodrawobj, ccmdtarget) Interface_part (ccodrawobj, iid_icodrawobj, dispatch) end_interface_map ()

Change to:

// Multi-interface support Define Begin_Interface_map (ccodrawobj, ccmdtarget) Interface_part (ccodrawobj, IID_ICODRAWOBJ, CODRAWOBJ) DUAL_ERRORINFO_PART (CCODRAWOBJ) End_Interface_map ()

Require modification: ccodrawobj is COM object class, IID_ICODRAWOBJ is the interface GUID, CODRAWOBJ deletes the i prefix for the interface name.

4.4 Class Factory Realization System has been automatically added, similar below: // {09671A2C-04FA-495E-A40C-410073A3A36E} Implement_olecreate (ccodrawobj, "CommfcDemo.codrawobj", 0x9671a2c, 0x4fa, 0x495e, 0xA4, 0xc, 0x41, 0x0 , 0x73, 0xA3, 0xA3, 0x6e)

4.5 Implementing the standard base interface method Add the following code:

/ / Realize standard IDispatch method DELEGATE_DUAL_INTERFACE (ccodrawobj, Codrawobj) // Realize standard IUNKNOWN Method // Delegate_iunknown_Interface (ccodrawobj, Codrawobj)

Require modification: ccodrawobj is COM object class, CODRAWOBJ deletes the i prefix for the interface name.

Use the first macro definition for the automation interface to use the second macro definition for the custom interface. Each interface requires a row of macro definitions, and the modification part is deleted from the I prefix for the last CODRAWOBJ.

4.6 ISUPPORTERRORINFO Support

Add the following line:

// Isupp PorterrorInfo supports implementation import_dual_errorinfo (ccodrawobj, IID_ICODRAWOBJ) Require modification section: ccodrawobj is COM object class, IID_ICODRAWOBJ is the default interface GUID. Description: Currently only one interface (please use the default interface), then add multiple interface support.

4.7 Interface Attribute Realizing Each interface adds to the following line:

// Interface Properties Implement Implement_Properties_icodrawobj (CCODRAWOBJ, CODRAWOBJ)

You need to modify part: iCodrawobj is the interface name, ccodrawobj is COM object class, CODRAWOBJ deletes the i prefix for the interface name.

4.8 Interface Method Realization Each interface is added:

// Interface method Implement Implement_Methods_icodrawobj (ccodrawobj, Codrawobj)

You need to modify part: iCodrawobj is the interface name, ccodrawobj is COM object class, CODRAWOBJ deletes the i prefix for the interface name.

5. Register your COM server, now this support for the double-interface COM server has been completed, please register. Tools => Register Control COM Server: Commfcdemo Automation Object: CODRAWOBJ Supports Dual Interface ICODRAWOBJ, attribute X, Method DRAW

Task 2: Call COM interface with VC

1. Add new items in the project: vcdemo, choose Dialog Base to join ../commfcdemo_i.h and ../commfcdemo_i.h and ../commfcdemo_i.c file Select Project => Settings ... => Commfcdemo_i.c, on the right panel Select C / C => category: precompiled headers => NOT USING Precompiled Headers

2. Add a COM library in the initInstance function in the app file: if (! Afxoleinit ()) Return False; 3. Add a button in the dialog box to define it. Click Message 4. In vcdemodlg.cpp

#include "../commfcdemo_i.h"

ICodrawobj * Picodrawobj = NULL;

BOOL CVcDemoDlg :: OnInitDialog () {... HRESULT hr; hr = CoCreateInstance (CLSID_coDrawObj, NULL, CLSCTX_INPROC_SERVER, IID_IcoDrawObj, reinterpret_cast (& pIcoDrawObj)); if (FAILED (hr)) return FALSE;

...}

Bool cvcdemodlg :: destroyWindow () {ix (picodrawobj) {picodrawobj-> release (); picodrawobj = null;} returno cdialog :: destroyWindow ();}

Void cvcdemodlg :: onbutton1 () {i (picodrawobj) {Picodrawobj-> Draw ();}}

5. Ok, now you can compile, see what you have after the click button? Task 3: Call the COM interface with VB

We create automated objects can be used in VB. 1. Create VB Applications 2. Join the COM object Reference Project => References ... => Browse .. => .tlb

3. Create a button to generate it Click Event Private Sub Command1_Click () Dim Codrawobj As New Codrawobj Codrawobj.drawend Sub

4. Ok, you can run, click the button.

Task 4: Add new properties and methods to interfaces

1. Modify the ODL file interface icodrawobj: idispatch {// iCodrawobj Properties: [PropPut, Helpstring "] HRESULT X ([In] short new_x); [Propget, Helpstring (" horizontal)] HRESULT X ( [OUT, RETVAL] Short * RET_X); >> [PropPut, Helpstring "] >> HRESULT Y ([In] Short new_y); >> [Propget, Helpstring (" Welcome ")] >> HRESULT Y ([OUT, RETVAL] Short * RET_Y); // iCodrawobj method: [Helpstring ("Draw Graphic"] HRESULT DRAW (); >> [Helpstring ("About")] >> HRESULT ABOUTME ();} Compile ODL file

2. In the COM object header file CODRAWOBJ.H, the internal member variable short m_y should be added;

3. Modify the interface in COM object header file CODRAWOBJ.H Declaration #define declare_interface_part_icodrawobj / stdmethod (THIS_SORT FAR * RET_X); / STDMETHOD (this_ Short new_x); /> stdmethod (get_y) (this_ Short far * RET_Y); /> stdmethod (this_ short new_y); / stdmethod (DRAW) (); /> stdmethod (about) (); /

4. Modify the properties achieved reader #define IMPLEMENT_PROPERTIES_IcoDrawObj (objClass, baseClass) / DECLARE_PUT_PROPERTY (objClass, baseClass, x) (short new_x) / IMPLEMENT_PUT_PROPERTY (objClass, baseClass, x) / DECLARE_GET_PROPERTY (objClass header file in the COM object in coDrawObj.h , baseClass, x) (short FAR * ret_x) / IMPLEMENT_GET_PROPERTY (objClass, baseClass, x) / >> DECLARE_PUT_PROPERTY (objClass, baseClass, y) (short new_y) / >> IMPLEMENT_PUT_PROPERTY (objClass, baseClass, y) / >> DECLARE_GET_PROPERTY (Objclass, BaseClass, Y) /> Implement_get_property (Objclass, Baseclass, Y) / 4. Modify the interface method in COM object header file CODRAWOBJ.H

#define IMPLEMENT_METHODS_IcoDrawObj (objClass, baseClass) / STDMETHODIMP objClass :: X ## baseClass :: Draw () / {/ BEGIN_NEST_INTERFACE_FRAME (objClass, baseClass) / pThis-> Draw (); / END_NEST_INTERFACE_FRAME /} / >> STDMETHODIMP objClass :: X # #BaseClass :: Aboutme () / >> {/ >> begin_nest_interface_frame (objclass, baseclass) / >> pthis-> Aboutme (); / >> End_nest_interface_frame / >>} /

5. Creating a Protected Virtual Member Functions of Coated Vcodrawobj from CCODRAWOBJ moves the function to iCodrawobj.cpp and handed over to the programmer. Void ccodrawobj :: Aboutme () {AFXMESSAGEBOX ("this is Codrawobj Aboutme ().");}

6. Compile, register. You can now add Picodrawobj-> Aboutme () in VcDemo; test it.

Task 5: Add a new custom interface The default automation interface provides support for other development platform programmers, and there is a need for some internal work within the COM object to be implemented with a custom interface.

1. Modify the ODL file to add a new interface (interface uuid is generated with guidgen) [UUID (8C1A8020-627B-4C37-AE70-51F9AD56FFBD), Object, Helpstring ("Co-calculation method of CODRAWOBJ)] Interface iCalc: iunknown {[Helpstring ("Calculate")] HRESULT CALC ();

Add a new interface to CoClass Codrawobj {[default] interface icodrawobj; >> interface ics; ------------------ // iCalc interface statement start // -------------------- # define DECLARE_INTERFACE_PART_ICALC / STDMETHOD (CALC) (); /

Begin_Interface_part (CALC, ICALC) DECLARE_INTERFACE_PART_ICALC END_INTERFACE_PART (CALC)

// ---------------------- // iCalc interface declaration end / / ------------------ ----

Need to modify: declare_interface_part_ICALC - ICALC is interface name begin_interface_part (CODRAWOBJ, ICALC) - CALC is the interface name to delete the I prefix, ICALC is the interface name. End_interface_part (CALC) - CALC is an interface name to delete the i prefix, iCalc is an interface name.

2.2 Interface method implementation // --------------------- // iCalc method start // ------------- ------------

#define IMPLEMENT_METHODS_ICalc (objClass, baseClass) / STDMETHODIMP objClass :: X ## baseClass :: Calc () / {/ BEGIN_NEST_INTERFACE_FRAME (objClass, baseClass) / pThis-> Calc (); / END_NEST_INTERFACE_FRAME /} /

// ----------------------- // iCalc method end / / ----------------- ------ Need to modify part: import_methods_ICALC Last for Interface Name Stdmethodimp Objclass :: x ## Baseclass :: Calc () Last for Interface Method PTHIS-> CALC (); Last is the interface method name

2.3 Creating a CCODRAWOBJ PROTECTED VIRTUAL Member Function Calc Moves the function to iCalc.cpp and handed over to the programmer. Void ccodrawobj :: Calc () {AFXMessageBox ("this is coderawobj Calc ().");

3. Modify the COM object implementation file coDrawObj.cpp added support multiple interfaces // define BEGIN_INTERFACE_MAP (CcoDrawObj, CCmdTarget) INTERFACE_PART (CcoDrawObj, IID_IcoDrawObj, coDrawObj) >> INTERFACE_PART (CcoDrawObj, IID_ICalc, Calc) DUAL_ERRORINFO_PART (CcoDrawObj) END_INTERFACE_MAP () needs to be modified : IID_ICALC - Interface GUID CCODRAWOBJ - COM object class CALC - interface name is deleted I prefix

/ / Realize ICAlc's standard iUnknown method DELEGATE_IUNKNOWN_INTERFACE (ccodrawobj, CALC) Require modification: ccodrawobj - COM object class CALC - interface name delete i prefix

Implement_methods_ICALC (CCODRAWOBJ, CALC) Requires Modification: ICALC - Interface Name CCODRAWOBJ - COM Object Class CALC - Interface Name Delete I Prefix

4. Compile operation

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

New Post(0)