COM programming with MFC in VC ++ 6.0

zhaozj2021-02-08  459

COM programming with MFC in VC 6.0

2000-03-21 · Yang Ning · vchelp

First, it should be clear that the MFC is to implement the COM interface through the nested category rather than multiple inheritance, and the interface and implementation of the interface are associated with the nested classes that implement the interface; the MFC is provided with a simple macro to achieve nested Class definition. Second, the MFC implements an IUNKNOWN interface through the ccmdtarget class. This article first describes the steps and core code for creating a COM server. Then explain the customer critical code. This COM server implements a TimeLogServer component, which is only the same, this component is only An interface ITIMELOG, through ITIMELOG's method OutputLog can output log text to log files. Create a MFC DLL project, choose support Automation (Of course this program is not necessarily an automation server, this is here to do a few necessary Output functions such as DllgetClassObject, DllRegisterServer, etc., otherwise write) the first COM server. Declaration Components and interfaces 1. Write a guids.h, declare the components and interfaces in Guids.h Guid // Declaration Components Guid {a433E701 -E45E-11D3-97B5-52544CBA7F28}

// define_guid (CLSID_TIMELOGSERVER,

// 0xA433E701, 0XA45E, 0X11D3, 0x97, 0xB5, 0x52, 0x54, 0x4c, 0xBa, 0x7f, 0x28);

Static const Iid CLSID_TIMELOGSERVER =

{0xA433E701, 0xE45E, 0x11D3, {0x97, 0xB5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28}};

// Declaration interface guid {a433e702-E45E-11D3-97B5-52544CBA7F28}

// define_guid (IID_ITIMELOG,

// 0xA433E702, 0xA433E702, 0xE45E, 0X11D3, 0x97, 0xB5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28);

Static const same IID_ITIMELOG =

{0xA433E702, 0xE45E, 0x11D3, {0x97, 0xB5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28}};

2. Write a ITIMELOGSERVER.H, declared components and interfaces in ITIMELOGSERVER.H files //itimelogserver.h

#include "guids.h"

// Interface ITIMELOG declaration

Declare_Interface_ (ITIMELOG, IUNKNOWN)

{

STDMETHOD (OUTPUTLOG) PURE;

}

Description: 1. Macro Define_GUID associates the PROGID of the components and interfaces. You can use the Guidgen.exe tool. 2. Macro Declare_interface_ declared the interface; the first parameter is the interface name, the second parameter is the interface Base class. Declaring no base class interface with declare_interface macro. 3. Macro stdmethod declares how the method in the interface. The return value of this method is HRESULT.PURE is interpreted as "= 0", that is, this method is a pure virtual function. The return value of the method is not HRESULT, with macro STDMETHOD_ (return type, function name) pure; two. Declarative component class CTIMELOGSERVER and the nested class of the interface add new class CTimelogServer, the base class is selected as ccmdtarget Modify its header file TimelogServer1.h, plus #include "itimelogserver.h"; simultaneously add // declared the nested class of the ITIMELOG interface in the class declaration

Begin_Interface_part (TimeLog, ITIMELOG) // Automatically declares the three methods of the iUnknown interface stdmethod (outputlog) (BSTR * VARLOGTEXT);

END_INTERFACE_PART (TIMELO)

// Declaration Interface Map

Declare_interface_map ()

// Disclaimer

Declare_olecreate (CTimelogServer)

III. Implementation of class and interface mapping in CTimelogServer implementation files: // Implementation

Implement_olecreate (CTimelogServer, "TimelogServer",

0xA433E701, 0XE45E, 0x11D3, 0x97, 0xB5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28);

// Mapping the interface to the corresponding nested class

Begin_Interface_map (ctimelogserver, ccmdtarget)

Interface_part (CTimelogServer, IID_ITIMELOG, TIMELOG)

END_INTERFACE_MAP ()

Four. Counting the overall object count in the constructor and destructive function

CTimelogServer :: ctimelogserver ()

{

:: AfxoLockApp ();

}

CTimelogServer :: ~ ctimelogserver ()

{

:: AfxoleunlockApp ();

} V. IUNKNOWN interface / / for nested classes to implement iUnknown interface

STDMETHODIMP_ (ULONG)

CTimelogServer :: Xtimelog :: AddRef ()

{

Method_Prologue (CTimelogServer, Timelog)

Return PTHIS-> EXTERNALADDREF ();

}

STDMETHODIMP_ (ULONG)

CTimelogServer :: Xtimelog :: release ()

{

Method_Prologue (CTimelogServer, Timelog)

Return PTHIS-> EXTERNALRELEASE ();

}

StdMethodimp

CTimelogServer :: Xtimelog :: queryinterface (refiid riid, void ** ppvobj)

{

Method_Prologue (CTimelogServer, Timelog)

Return PTHIS-> ExternalQueryInterface (& RiID, PPVObj);

Note: Although the CCMDTARGET class has implemented an IUNKNOWN interface, it is also necessary to map the nested class's iUnknown to the iUnknown interface supported by the ccmdTarget. The two parameters of the Method_ProLogueh macro are the class and implementation of the interface. Nested classes. Six. Method for implementing the ITIMELOG interface Outputlog Note The function of this component is to enter the log file. 1. Add a file pointer to the component class: // attributes

PUBLIC:

protected:

FILE * M_LOGFILE;

2. Initializing and exiting first in the constructor of CTimelogServer: CTimelogServer :: CTimelogServer ()

{

:: AfxoLockApp ();

CTIME TIMESTAMP = CTime :: getcurrenttime ();

CSTRING FILENAME;

Filename.Format (_T ("% s.log"), timestamp.format ("% y% m% D"));

m_logfile = fopen (filename, _t ("a"));

IF (m_logfile) {

FPRINTF (M_Logfile, _T ("# # # # # # # # # # # / n"));

FPRINTF (M_Logfile, _T ("Start:% S"), (LPCTSTR) TimeStamp.Format ("% y year% M month% D days% H:% M% s"));

FPRINTF (m_logfile, _t ("/ n"));

}

}

/ / Then close the file in the destructor

CTimelogServer :: ~ ctimelogserver ()

{

:: AfxoleunlockApp ();

IF (m_logfile)

{

CTIME TIMESTAMP = CTime :: getcurrenttime ();

FPRINTF (m_logfile, _t ("/ n"));

FPRINTF (M_Logfile, _T ("end:% s"), (lpctstr) timestamp.format ("% y year% M month% D day% h:% m% s"));

FPRINTF (m_logfile, _t ("/ n"));

FPRINTF (M_Logfile, _T ("# # # # # # # # # # # / n"));

Fclose (m_logfile);

}

} 3. Implement interface ITIMELOG method // implement interface ITIMELOG method

StdMethodimp

CtimelogServer :: Xtimelog :: OutputLog (BSTR * VARLOGTEXT)

{

Method_Prologue (CTimelogServer, Timelog)

IF (PTHIS-> M_LOGFILE)

{

CTIME TIMESTAMP = CTime :: getcurrenttime ();

CString nowTime = timestamp.format ("% y year% M month% D day% h:% m:% s");

CString logtext (lpcwstr) * varLogtext);

FPrintf (pTHIS-> M_LogFile, "/ N% S / N% S / N%", NOWTIME, LOGTEXT

Return noerror;

}

Else

{

AfxMessageBox ("No log file!");

Return S_FALSE;

}

} Seven. Improve component server in the implementation file of the application object CTIMELOGSERVERAPP, process instance () and exitInstance () Bool CTimelogSerVerapp :: initInstance ()

{

:: AfxoLockApp ();

// Register All Ole Server (Factories) As Running. This Enables the

// Ole Libraries to create Objects from Other Applications.

ColeObjectFactory :: registerall ();

Return True;

}

Int ctimelogserVerapp :: exitInstance ()

{

// Todo: Add Your Specialized Code Here and / or Call The Base Class

:: AfxoleunlockApp ();

Return CWINAPP :: EXITINSTANCE ();

} The key steps for the client program for the second section of the customer using the COM component server are: initialize the COM library, create component objects, and get the iUnknown interface pointer, query the interface and use, release the component. #Include "itimelogserver.h"

// Initialize the COM library, instantiate the components

HRESULT HRESULT;

IUNKNOWN * PIUNKNOWN;

HRESULT = :: Coinitialize (NULL);

Failed (HRESULT))

{

:: AfxMessageBox ("You can't initialize the COM library!");

Return False;

}

// Create a component instance

Piunknown = null;

HRESULT = :: COCREATEINSTANCE (CLSID_TIMELOGSERVER, NULL,

CLSCTX_INPROC_SERVER, IID_IUNKNOWN, (VOID **) & PIUNKNOWN;

Failed (HRESULT))

{

Piunknown = null;

:: AfxMessageBox ("You can't create Timelog Objects!");

Return False;

}

/ / Query the interface and use

IF (PiunkNown! = NULL)

{

ITIMELOG * PITIMELOG;

HRESULT = Piunknown-> queryinterface (iid_itimelog, (void **) & pitimelog);

Failed (HRESULT))

{

:: AfxMessageBox ("You cannot get interface itimelog!");

Piunknown-> Release ();

Return;

}

BSTR BSTRLOGTEXT;

Bstrlogtext = m_logtext.allocsystring ();

CString text ((lpcwstr) BSTRLogText);

:: AfxMessageBox (Text);

IF (Failed (PitiMelog-> Outputlog (& Bstrlogtext))))

{

:: AfxMessageBox ("Log Output Error!");

PitiMelog-> Release ();

Return;

}

PitiMelog-> Release ();

:: AfxMessageBox ("Log already writes!");

}

// Release component

Piunknown-> Release ();

Piunknown = null; :: couninitialize ();

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

New Post(0)