DRAWCLI Sample: Illustrates Integrating Active Container Support with Application-Specific Features

The DRAWCLI sample is an object-oriented drawing application with Visual Editing container support. Among the MFC Active container samples — CONTAINER, OCLIENT, and DRAWCLI — this sample provides the best illustration of integrating Active container support with application-specific features (in this case, drawing features). In addition, DRAWCLI demonstrates effective use of C++ polymorphism in the design of its "shape" and "drawing tool" classes (CDrawObj and CDrawTool).

Security noteSecurity Note:

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.

Building and Running the Sample

To build and run the DRAWCLI sample

  1. Open the solution drawcli.sln.

  2. On the Build menu, click Build.

  3. From the project's Debug directory, open and run the DRAWCLI application.

DRAWCLI's Windows Logo Features

DRAWCLI also illustrates Windows logo compliance. All MFC applications meet some of the requirements for the Windows logo: a Win32 executable, support for long file names, support for UNC path names, and use of system colors and metrics. DRAWCLI meets the remaining requirements for the Windows logo by including the following features.

  • ActiveX support. DRAWCLI is an Active container that stores its files in the compound file format, supports in-place activation, and acts as a drop target for drag-and-drop operations.

  • MAPI support. DRAWCLI provides a "Send as Mail" message on its File menu, allowing the user to send a document as a mail attachment.

  • Compliance with shell guidelines, including registration of large and small icons, use of the system registry instead of an .ini file, and having a setup and an uninstall program. For the latter, DRAWCLI includes a script compatible with InstallSHIELD, Stirling Software's toolkit for creating setup and uninstall programs.

DRAWCLI also meets the following recommendations for Windows applications.

  • Uses tabbed property pages.

  • Uses Windows common controls.

  • Displays a shortcut menu in response to a right-button mouse click.

  • Stores Summary Information with its documents.

DRAWCLI's user interface is similar to those of other object-oriented drawing programs.

Integrating Active Container Support with Application-Specific Features

The DRAWCLI sample was originally a stand-alone drawing application developed using the MFC classes. The stand-alone version of DRAWCLI was then integrated with a second skeleton version of DRAWCLI created using the application wizard's ActiveX Container feature. This process is similar to how the ActiveX Visual Editing server adds server support to SCRIBBLE.

The design of an MFC ActiveX container application should look essentially the same, regardless of whether you are adding ActiveX functionality to an existing stand-alone MFC (doc/view) application, or whether you're starting with an application wizard–generated ActiveX container application. The following is a brief description of how DRAWCLI is separated into application-specific code and ActiveX container-specific code.

  • Class CDrawObj, implemented in Drawobj.cpp, is a base class for derived "shape" classes. This base class handles hit testing of shapes, moving of shapes, and resizing of shapes. Using polymorphism, DRAWCLI can interact with objects of different classes through the interface of CDrawObj.

  • Classes CDrawRect and CDrawPoly are derived from CDrawObj. CDrawRect is used to draw rectangles, rounded rectangles, ellipses, and lines. CDrawPoly is used to draw polygons. These two classes are independent of DRAWCLI's ActiveX container functionality.

  • Class CDrawOleObj is also derived from CDrawObj, and is used to represent embedded objects. CDrawOleObj delegates any ActiveX-specific operation to a contained CDrawItem object (described below). For generic shape operations, embedded objects are treated like other shape objects in DRAWCLI because CDrawOleObj is derived from CDrawObj.

  • Class CDrawItem, derived from COleClientItem, handles all the ActiveX-specific behavior for the embedded object. The implementation of CDrawItem is similar to the implementation of the COleClientItem-derived classes in the CONTAINER and OCLIENT samples.

  • Class CDrawDoc is derived from COleDocument. The COleDocument object maintains a CObList of CDrawObj objects. CDrawDoc delegates several ActiveX container-specific menu commands, such as EditPaste, Paste Link, and Links, to the base class COleDocument.

  • Class CDrawView is derived from CScrollView. The ActiveX-specific implementation of CDrawView is similar to the implementation of the view classes in the CONTAIN and OCLIENT samples. The bulk of DRAWCLI's drawing-specific user interface is also implemented in CDrawView.


This sample demonstrates the following keywords:

AfxGetApp; AfxGetMainWnd; AfxMessageBox; AfxOleInit; AfxRegisterWndClass; AfxThrowMemoryException; CArchive::Close; CArchive::IsStoring; CBitmap::CreateCompatibleBitmap; CBrush::CreateBrushIndirect; CBrush::CreateSolidBrush; CCmdTarget::BeginWaitCursor; CCmdTarget::EndWaitCursor; CCmdUI::Enable; CCmdUI::SetCheck; CCmdUI::SetRadio; CColorDialog::DoModal; CColorDialog::GetColor; CControlBar::EnableDocking; CControlBar::GetBarStyle; CControlBar::SetBarStyle; CDC::Attach; CDC::BitBlt; CDC::CreateCompatibleDC; CDC::DPtoLP; CDC::DrawFocusRect; CDC::FillRect; CDC::GetClipBox; CDC::GetDeviceCaps; CDC::HIMETRICtoDP; CDC::IntersectClipRect; CDC::IsPrinting; CDC::LPtoDP; CDC::LineTo; CDC::MoveTo; CDC::OffsetViewportOrg; CDC::OffsetWindowOrg; CDC::PatBlt; CDC::SelectObject; CDC::SetBkColor; CDC::SetBrushOrg; CDC::SetMapMode; CDC::SetViewportExt; CDC::SetViewportOrg; CDC::SetWindowExt; CDC::SetWindowOrg; CDialog::DoModal; CDocTemplate::SetContainerInfo; CDocument::GetFirstViewPosition; CDocument::GetNextView; CDocument::GetTitle; CDocument::OnNewDocument; CDocument::OnOpenDocument; CDocument::OnSaveDocument; CDocument::SetModifiedFlag; CDocument::SetTitle; CDocument::UpdateAllViews; CFrameWnd::DockControlBar; CFrameWnd::EnableDocking; CFrameWnd::LoadFrame; CFrameWnd::OnCreateClient; CGdiObject::UnrealizeObject; CMDIChildWnd::Create; CMenu::GetSubMenu; CMenu::LoadMenu; CMenu::TrackPopupMenu; CObList::AddTail; CObList::GetCount; CObList::GetHeadPosition; CObList::GetNext; CObList::IsEmpty; CObList::RemoveAll; CObList::RemoveAt; CObject::AssertValid; CObject::Dump; CObject::IsKindOf; CObject::Serialize; COleClientItem::Close; COleClientItem::CreateCloneFrom; COleClientItem::CreateFromData; COleClientItem::CreateStaticFromData; COleClientItem::Deactivate; COleClientItem::Delete; COleClientItem::DoVerb; COleClientItem::Draw; COleClientItem::GetActiveView; COleClientItem::GetClipboardData; COleClientItem::GetDocument; COleClientItem::GetExtent; COleClientItem::GetInPlaceWindow; COleClientItem::GetItemState; COleClientItem::GetType; COleClientItem::IsInPlaceActive; COleClientItem::OnChange; COleClientItem::OnChangeItemPosition; COleClientItem::OnGetItemPosition; COleClientItem::Release; COleClientItem::SetItemRects; COleClientItem::UpdateLink; COleDataObject::AttachClipboard; COleDataObject::GetFileData; COleDataObject::IsDataAvailable; COleDataSource::CacheGlobalData; COleDataSource::SetClipboard; COleInsertDialog::CreateItem; COleInsertDialog::DoModal; COleInsertDialog::GetSelectionType; CPen::CreatePen; CPen::CreatePenIndirect; CPrintDialog::CreatePrinterDC; CRect::BottomRight; CRect::Height; CRect::InflateRect; CRect::IntersectRect; CRect::IsRectEmpty; CRect::NormalizeRect; CRect::OffsetRect; CRect::SetRect; CRect::TopLeft; CRect::Width; CRectTracker::Draw; CRgn::CreateEllipticRgnIndirect; CRgn::CreatePolygonRgn; CRgn::CreateRoundRectRgn; CRgn::RectInRegion; CScrollView::GetDeviceScrollPosition; CScrollView::SetScrollSizes; CStatusBar::Create; CStatusBar::SetIndicators; CString::MakeLower; CToolBar::Create; CView::DoPreparePrinting; CView::GetDocument; CView::IsSelected; CView::OnActivateView; CView::OnBeginPrinting; CView::OnDragEnter; CView::OnDragLeave; CView::OnDragOver; CView::OnDraw; CView::OnDrop; CView::OnEndPrinting; CView::OnInitialUpdate; CView::OnPrepareDC; CView::OnPreparePrinting; CView::OnPrint; CView::OnScrollBy; CView::OnUpdate; CWinApp::AddDocTemplate; CWinApp::EnableShellOpen; CWinApp::InitInstance; CWinApp::LoadStdProfileSettings; CWinApp::RegisterShellFileTypes; CWinApp::SetRegistryKey; CWnd::DoDataExchange; CWnd::GetCapture; CWnd::GetParentFrame; CWnd::Invalidate; CWnd::InvalidateRect; CWnd::OnCreate; CWnd::OnDestroy; CWnd::OnEraseBkgnd; CWnd::OnLButtonDblClk; CWnd::OnLButtonDown; CWnd::OnLButtonUp; CWnd::OnMouseMove; CWnd::OnSetFocus; CWnd::OnSize; CWnd::PreCreateWindow; CWnd::ScreenToClient; CWnd::SetCapture; CWnd::SetFocus; CWnd::ShowWindow; CWnd::UpdateWindow; DragAcceptFiles; Ellipse; GetACP; GetKeyState; GetMapMode; GetVersion; GlobalFree; GlobalLock; GlobalUnlock; LOWORD; LineTo; LoadCursor; MAKELONG; MoveTo; MulDiv; Polygon; RGB; Rectangle; RegisterClipboardFormat; ReleaseCapture; RoundRect; SelectObject; SetCursor; free; malloc; memcpy; min; realloc; wcstombs


Some samples, such as this one, have not been modified to reflect the changes in the Visual C++ wizards, libraries, and compiler, but still demonstrate how to complete your desired task.

See Also

Other Resources

MFC Samples