ATLTangram: Demonstrates Managing Large Projects That Use ATL, MFC, and COM

Click to open or copy the ATLTangram project files.

ATLTangram is a port of the Tangram example found in the last chapter of Dale Rogerson's Inside Com (http://mspress.microsoft.com). Many thanks to Dale for doing all the hard work and allowing us to use the code in an ATL sample. This sample will help you convert a legacy COM application to one that uses ATL for its infrastructure.

ATLTangram is a large project consisting of the ATLTangram workspace, which is the master controller for seven subprojects: MFCTangram, ATLModel, ATLGdiWorld, ATLGLWorld, ATLModelps, ATLModelExe, and ATLTangramCanvas. The sample demonstrates several features of the Visual C++ Integrated Development Environment (IDE) and several concepts of COM. The sample also demonstrates using MFC as the client of ATL COM servers.

Managing a Large Project

All of the project settings are already established for the sample. Follow these steps to examine the project interdependencies.

  1. From the Project menu, click Project Settings.

  2. Click the Custom Build tab to examine the rules used for idl files and for various projects

  3. Click the C/C++ tab, and in the Category drop-down, select Preprocessor. Examine the Additional Include Directories edit box.

  4. Click the Post-Build Step tab to examine the post-build commands to copy files to the ATLModelps directory. The sample requires several files after the MIDL compiler runs in the ATLModel project.

  5. From the Project menu, click Project Dependencies and examine the dependent project names.

The ATLModel and ATLModelExe projects demonstrate how to set up a COM server so you can build it as either an in-proc server or a local server using the same set of files and two project files. Using two project files allows dependencies to exist on both the DLL and the EXE.

COM/ATL Features

This sample is a COM system that consists of several COM servers and an MFC application that uses the servers. The sample exhibits the intermodule communication via the connection point mechanism and demonstrates local and in-proc servers.

Other Demonstrated Features

The sample uses the following ATL classes:

CComObjectRootEx, CComCoClass, CComControl, IDispatchImpl, IProvideClassInfo2Impl, IPersistStreamInitImpl, IPersistStorageImpl, IPersistPropertyBagImpl, IPerPropertyBrowsingImpl, IQuickActivateImpl, IObjectSafetyImpl, IOleControlImpl, IOleObjectImpl, IOleInPlaceActiveObjectImpl, IViewObjectExImpl, IOleInPlaceObjectWindowlessImpl, IDataObjectImpl, ISupportErrorInfo, ISpecifyPropertyPagesImpl, IConnectionPointContainerImpl, IPropertyNotifySinkCP, CDialogImpl

The sample uses the following MFC classes:

CFrameWnd, CTypedPtrList<>, CDialog, CWinApp, and additional supporting classes.

This sample uses the following keywords:

_ASSERTE; AddRef; AddUpdateRect; Advise; assert; ASSERT; ATLTRACE; auxSolidSphere; BEGIN_COM_MAP; BEGIN_CONNECTION_POINT_MAP; BEGIN_MESSAGE_MAP; BEGIN_OBJECT_MAP; BitBlt; CATEGORYINFO ; CComCoClass; CComModule::GetClassObject; CComModule::GetLockCount; CComModule::Init; CComModule::RegisterServer; CComModule::Term; CComModule::UnregisterServer; CComObjectRootEx; CExeModule::Init; CExeModule::RegisterClassObjects; CExeModule::RegisterServer; CExeModule::RevokeClassObjects; CExeModule::UnregisterServer; CExeModule::UpdateRegistryFromResource; CFrameWnd::AssertValid; CFrameWnd::Dump; CFrameWnd::PreCreateWindow; ChoosePixelFormat; CModelList; CoCreateInstance; CoInitializeEx; COM_INTERFACE_ENTRY; COM_INTERFACE_ENTRY_AGGREGATE; COM_INTERFACE_ENTRY_IMPL; CONNECTION_POINT_ENTRY; CopyRect; CoTaskMemFree; CProxyIATLTangramModelEvent; CreateCompatibleDC; CreatePalette; CWnd::CreateEx; DECLARE_GET_CONTROLLING_UNKNOWN; DECLARE_MESSAGE_MAP; DECLARE_ONLY_AGGREGATABLE; DECLARE_REGISTRY_RESOURCEID; DeleteObject; DescribePixelFormat; DisableThreadLibraryCalls; DispatchMessage; DoButtonDown; DoModal; END_COM_MAP; END_CONNECTION_POINT_MAP; END_MESSAGE_MAP; END_OBJECT_MAP; EqualRect; ErrorMessage; GdiFlush; GetBoundingRect; GetClientRect; GetCommandLine; GetControllingUnknown; GetDC; GetMessage; GetModuleFileName; GetObject; GetPalette; GetPaletteEntries; GetPixelFormat; GetRotation; GetVertices; glBegin; glClearColor; GLdouble CoCreateInstance; glEnable; glEnd; glFlush; glGetIntegerv; glInitNames; glLightfv; glLightModelfv; glLoadIdentity; glMatrixMode; glNormal3d; glPolygonMode; glPopMatrix; glPopName; glPushMatrix; glPushName; GLRender; glRenderMode; GLResize; glRotated; glSelectBuffer; GLSetup; glTranslated; glTranslatef; gluPerspective; gluPickMatrix; gluUnProject; glVertex2d; glVertex3d; glViewport; HPALETTE; ICatInformation::EnumClassesOfCategories; ICatRegister::QueryInterface; ICatRegister::RegisterCategories; ICatRegister::RegisterClassImplCategories; ICatRegister::UnRegisterCategories; ICatRegister::UnRegisterClassImplCategories; IConnectionPointContainer::FindConnectionPoint; IConnectionPointContainer::Release; IConnectionPointContainerImpl; InitInstance; InvalidateRect; IsCurrent; IsValidAddress; IUnknown::Release; LoadIcon; LoadStandardCursor; LocalFree; MakeCurrent; OBJECT_ENTRY; ON_COMMAND; ON_WM_DESTROY ; OnCancel; OnDestroy; OnInitDialog; OnOK; OnQueryNewPalette; OutputDebugString; OutputGlError; Polygon; PreCreateWindow; PtInRegion; QueryInterface; RealizePalette; Release; ReleaseConnectionPoint; ReleaseDC; Rotate; SelectObject; SelectPalette; SetPixelFormat; SetRectEmpty; specifyMaterial; StringFromCLSID; SubkeyExists; va_end; wcscpy; wglCreateContext; wglGetCurrentContext; wglMakeCurrent

Building the Sample

The project has established all the interdependencies in the IDE. These interdependencies work with the default directory structure for the sample and are path-relative.

The MFCTangram project drives all of the other projects. By building this project, you will build all of the necessary, interdependent projects:

  1. In ClassView, right-click MFCTangram classes. Click Set as Active Project.

  2. On the menu bar, click Build. Click Build MFCTangram.exe. Building MFCTangram will build all of the necessary projects that MFCTangram is dependent upon.

The dependency hierarchy looks roughly like this:

MFCTangram
   ATLGLWorld
      ATLGdiWorld
         ATLTangramCanvas
            ATLModel
   ATLModelExe
      ATLModel
   ATLModelps
      ATLModel