MFCATL Sample: Uses ATL COM Objects in an MFC Server
Updated: March 2009
The MFCATL sample illustrates how ATL COM objects can be used in an MFC server EXE.
The server allows the creation of two objects: ObjectOne (implemented in MFC and supporting a dispinterface) and ObjectTwo (implemented in ATL and supporting a dual interface).
This sample code is provided to illustrate a concept and should not be used in applications or Web sites, as it may not illustrate the safest coding practices. Microsoft assumes no liability for incidental or consequential damages should the sample code be used for purposes other than as intended.
To get samples and instructions for installing them:
On the Visual Studio Help menu, click Samples.
For more information, see Visual Studio Samples.
The most recent version and complete list of samples is available online from the Visual Studio 2008 Samples page.
You can also locate samples on your computer's hard disk. By default, samples and a Readme file are copied into a folder under \Program Files\Visual Studio 9.0\Samples\. For Express editions of Visual Studio, all samples are located online.
To build and run the sample
Open the solution file mfcatl.sln.
From the Build menu, click Build Solution.
From the Debug menu, click Start Without Debugging. This will run the mfcatl.exe server standalone and will register it.
Open mfcatl.htm file in your Web browser and click the buttons to call into appropriate objects. You can call each object individually or both at the same time.
Originally, both MFCATL objects were implemented in MFC. Both were derived from CCmdTarget. ObjectTwo was reimplemented using ATL by following these steps:
Include the ATL header files (Atlbase.h and Atlcom.h) in Premfcat.h.
Include Atlimpl.cpp in Premfcat.cpp.
Add a CAtlModule-derived class to Prefcat.h. The derived class implements the Lock and Unlock methods to forward lock counts to MFC by calling AfxOleLockApp and AfxOleUnlockApp.
Add an object map macro pair (BEGIN_OBJECT_MAP/END_OBJECT_MAP) in Mfcatl.cpp and add a static instance of the module class called _Module.
Call _Module.Init and Term from InitInstance and ExitInstance.
Add the typelib as a resource.
Call _Module.RegisterServer(TRUE) from InitInstance to match the MFC call to COleObjectFactory::UpdateRegistryAll.
Call _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE) to match the REGCLS_MULTIPLEUSE of MFC's class factories, as implicitly done by the IMPLEMENT_OLECREATE macro.
Reimplement ObjectTwo in ATL by following these steps:
Change the ODL file from dispinterface to dual interface.
Have the ODL compilation generate a header file (Interf.h) needed by ATL.
Rewrite .h and .cpp files (the quickest way is to run the ATL wizards and copy, paste, and rename the automatically generated code in place of the original MFC code).
Add an OBJECT_ENTRY(CLSID_ObjectTwo, CObjectTwo) to the ATL object map.
Additional conversion steps (not covered here) might include:
Porting the ODL file to IDL format.
Adding support for -RegServer and -UnregServer command-line arguments.
This sample uses the following keywords:
AfxMessageBox; AfxOleInit; AfxOleLockApp; AfxOleUnlockApp; ASSERT; BEGIN_COM_MAP; CCmdTarget; CCmdTarget::OnFinalRelease; CComCoClass; CComModule; CComModule::GetLockCount; CComModule::Lock; CComModule::Unlock; CComObjectRoot; CDialog; CMenu::AppendMenu; COleObjectFactory::RegisterAll; COleObjectFactory::UpdateRegistryAll; COM_INTERFACE_ENTRY; CString::IsEmpty; CString::LoadString; CWindow::GetSystemMenu; DECLARE_DYNCREATE; DECLARE_NOT_AGGREGATABLE; DECLARE_REGISTRY; DestroyWindow; EnableAutomation; GetClientRect; GetSystemMetrics; IDispatchImpl; PostMessage; SendMessage; SetIcon; ShowWindow; SysAllocString