Dynamic Memory Allocation -- Linked Lists

Chapter 25 - Getting Started with OLE

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

Creating a Container Application
In Chapter 24, a simple single-document interface (SDI) application named “Graph” was developed. The container application in this chapter will be patterned closely after that example. We’ll call this application “Cnt.”
This application uses two important OLE classes, COleClientItem and COleDocument. COleDocument manages a list of COleClientItem items. COleClientItem itself manages the embedded or linked objects and the required communications.
The important thing to remember as you view the container code in the next sections is that the code is completely generated by the AppWizard. This container template code can be enhanced with your specific application features to turn it into a full-blown product. In this chapter, however, no additional features were added to the basic template.
Working with the AppWizard
The AppWizard is used here in the same way it was used in Chapter 24. You might want to review that chapter for a more detailed explanation of each step in the creation process. This section will examine the most important steps, in an abbreviated form, for building the container application, Cnt:Chapter 24. You might want to review that chapter for a more detailed explanation of each step in the creation process. This section will examine the most important steps, in an abbreviated form, for building the container application, Cnt:
  Use the Microsoft Visual C++ File menu to start a new project.
  Select the MFC AppWizard (.EXE) to start the six-step process:
  1. Create a single-document interface.
  2. Do not include database support.
  3. Select a Container as the OLE compound document. Include support for ActiveX controls.
  4. Include all of the default features for the container application.
  5. Select a MFC Standard project, source code comments, and then pick a statically linked library.
  6. Examine the list of classes to be generated, making any necessary changes. Click on the Finish button to complete the specification process.
  The AppWizard will generate a summary screen. If this information is correct, click on the OK button to generate the project’s code.
  The panel, to the left of your display, should now show the various classes and files created for the project.
Finally, build the executable file by selecting the Rebuild All option from the compiler’s Build menu. When the process is complete, the appropriate subdirectory will contain an executable file named CNT.EXE. We will test this container in another section of this chapter.
AppWizard Files
The files generated by the AppWizard produce a fully operable container application named Cnt. When the files have been generated by the AppWizard, your subdirectory will contain the following unique C++ files: CNT.CPP, MAINFRM.CPP, CNTDOC.CPP, CNTVIEW.CPP, and CNTRITEM.CPP. Also in this subdirectory will be a host of supporting header files, resource files, and so on.
The Container File: CNT.CPP
The code used in the container CNT.CPP file is almost identical to that used in the Graph example in Chapter 24. Compare the two files and notice the similarities. You might also want to return to Chapter 24 if you need more details on the message map and the classes used in this file.
The file is listed here, so the application’s code for this chapter will be complete:
// Cnt.cpp : Defines the class behaviors for the application.
//

#include “stdafx.h”
#include “Cnt.h”

#include “MainFrm.h”
#include “CntDoc.h”
#include “CntView.h”

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////
// CCntApp

BEGIN_MESSAGE_MAP(CCntApp, CWinApp)
 //{{AFX_MSG_MAP(CCntApp)
 ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
   // NOTE - the ClassWizard will add\remove mapping macros.
   //    DO NOT EDIT these blocks of generated code!
 //}}AFX_MSG_MAP
 // Standard file based document commands
 ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
 ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
 // Standard print setup command
 ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////
// CCntApp construction
CCntApp::CCntApp()
{
 // TODO: add construction code here,
 // Place all significant initialization in InitInstance
}

//////////////////////////////////////////////////////////////
// The one and only CCntApp object

CCntApp theApp;

//////////////////////////////////////////////////////////////
// CCntApp initialization

BOOL CCntApp::InitInstance()
{
 // Initialize OLE libraries
 if (!AfxOleInit())
 {
   AfxMessageBox(IDP_OLE_INIT_FAILED);
   return FALSE;
 }

 AfxEnableControlContainer();
 // Standard initialization
 // If not using these features you can reduce the size
 //  of the final executable; remove from the following
 //  the specific initialization routines you do not need.

#ifdef _AFXDLL
 Enable3dControls();      //Call when using MFC in shared DLL
#else
 Enable3dControlsStatic(); //Call when linking statically
#endif

 // Change the registry key under which settings are stored.
 // Modify this string to be something appropriate
 // such as the name of your company or organization.
 SetRegistryKey(_T(“Local AppWizard-Generated Applications”));

 LoadStdProfileSettings();  //Load standard options
 // Register the application’s document templates.
 //  Document templates serve as the connection between
 // documents, frame windows and views.

 CSingleDocTemplate* pDocTemplate;
 pDocTemplate = new CSingleDocTemplate(
   IDR_MAINFRAME,
   RUNTIME_CLASS(CCntDoc),
   RUNTIME_CLASS(CMainFrame),       // main SDI frame window
   RUNTIME_CLASS(CCntView));
 pDocTemplate->SetContainerInfo(IDR_CNTR_INPLACE);
 AddDocTemplate(pDocTemplate);
 // Parse command line for standard shell commands
 CCommandLineInfo cmdInfo;
 ParseCommandLine(cmdInfo);

 // Dispatch commands specified on the command line
 if (!ProcessShellCommand(cmdInfo))
   return FALSE;

 // The window has been initialized, show and update.
 m_pMainWnd->ShowWindow(SW_SHOW);
 m_pMainWnd->UpdateWindow();

 return TRUE;
}

//////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 //{{AFX_DATA(CAboutDlg)
 enum { IDD = IDD_ABOUTBOX };
 //}}AFX_DATA
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CAboutDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);
 //}}AFX_VIRTUAL

// Implementation
protected:
 //{{AFX_MSG(CAboutDlg)
   // No message handlers
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 //{{AFX_DATA_INIT(CAboutDlg)
 //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CAboutDlg)
 //}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 //{{AFX_MSG_MAP(CAboutDlg)
   // No message handlers
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CCntApp::OnAppAbout()
{
 CAboutDlg aboutDlg;
 aboutDlg.DoModal();
}


//////////////////////////////////////////////////////////////
// CCntApp commands
There is an interesting section of code in this file that deserves a mention. Under OLE, in-place editing is supported. In-place editing means that when an object is embedded in a container, such as our Cnt application, its menu replaces the container’s menu. For example, if an Excel spreadsheet object is embedded in Cnt, Cnt’s menu will change to that of Excel’s!
This menu change is handled by MFC, via OLE, almost automatically. MFC makes this possible by having three menu sources available: IDR_MAINFRAME, IDR_DOCTYPE, and IDR_CNTR_INPLACE (the name of the last IDR is specific to your application). When no object is embedded in the container application, IDR_MAINFRAME is used. When a document is opened, IDR_DOCTYPE is used. Finally, when an object has been embedded in the container, IDR_CNTR_INPLACE is used.
The Container File: MAINFRM.CPP
The code used in the container MAINFRM.CPP file is the same as that used in the Graph example in Chapter 24. Again, return to Chapter 24 if you need more details on the message map and classes used in this file.
For completeness, the file is listed here:
// MainFrm.cpp : implementation of the CMainFrame class
//

#include “stdafx.h”
#include “Cnt.h”

#include “MainFrm.h”

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
 //{{AFX_MSG_MAP(CMainFrame)
   // ClassWizard will add and remove mapping macros here.
   //    DO NOT EDIT these blocks of generated code !
 ON_WM_CREATE()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

static UINT indicators[] =
{
 ID_SEPARATOR,           // status line indicator
 ID_INDICATOR_CAPS,
 ID_INDICATOR_NUM,
 ID_INDICATOR_SCRL,
};

//////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
 // TODO: add member initialization code here
 
}

CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
   return -1;
 
 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |
   WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |
   CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
   !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
 {
   TRACE0(“Failed to create toolbar\n”);
   return -1;      // fail to create
 }
 if (!m_wndStatusBar.Create(this) ||
   !m_wndStatusBar.SetIndicators(indicators,
     sizeof(indicators)/sizeof(UINT)))
 {
   TRACE0(“Failed to create status bar\n”);
   return -1;      // fail to create
 }

 // TODO: Delete these lines to if toolbar is not to
 //  be dockable
 m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
 EnableDocking(CBRS_ALIGN_ANY);
 DockControlBar(&m_wndToolBar);

 return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 if( !CFrameWnd::PreCreateWindow(cs) )
   return FALSE;
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs

 return TRUE;
}

//////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
 CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
 CFrameWnd::Dump(dc);
}

#endif //_DEBUG

//////////////////////////////////////////////////////////////
// CMainFrame message handlers
The Container File: CNTDOC.CPP
The code used in the container CNTDOC.CPP file, shown here, contains some additional code that does not appear in the Graph application in Chapter 24. Compare the two files and notice the differences.Chapter 24. Compare the two files and notice the differences.
// CntDoc.cpp : implementation of the CCntDoc class
//

#include “stdafx.h”
#include “Cnt.h”

#include “CntDoc.h”
#include “CntrItem.h”
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//////////////////////////////////////////////////////////////
// CCntDoc
IMPLEMENT_DYNCREATE(CCntDoc, COleDocument)

BEGIN_MESSAGE_MAP(CCntDoc, COleDocument)
 //{{AFX_MSG_MAP(CCntDoc)
   // NOTE - the ClassWizard will add and remove macros here.
   //    DO NOT EDIT these blocks of generated code!
 //}}AFX_MSG_MAP
 // Enable default OLE container implementation
 ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE,
                    COleDocument::OnUpdatePasteMenu)
 ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_LINK,
                                           COleDocument::OnUpdatePasteLinkMenu)
 ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT,
                                             COleDocument::OnUpdateObjectVerbMenu)
 ON_COMMAND(ID_OLE_EDIT_CONVERT,
                       COleDocument::OnEditConvert)
 ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS,
                                           COleDocument::OnUpdateEditLinksMenu)
 ON_COMMAND(ID_OLE_EDIT_LINKS,
                       COleDocument::OnEditLinks)
 ON_UPDATE_COMMAND_UI_RANGE(ID_OLE_VERB_FIRST,
                                               ID_OLE_VERB_LAST,
                                               COleDocument::OnUpdateObjectVerbMenu)
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////
// CCntDoc construction/destruction

CCntDoc::CCntDoc()
{
 // Use OLE compound files
 EnableCompoundFile();

 // TODO: add one-time construction code here

}
CCntDoc::~CCntDoc()
{
}

BOOL CCntDoc::OnNewDocument()
{
 if (!COleDocument::OnNewDocument())
   return FALSE;

 // TODO: add reinitialization code here
 // (SDI documents will reuse this document)

 return TRUE;
}


//////////////////////////////////////////////////////////////
// CCntDoc serialization

void CCntDoc::Serialize(CArchive& ar)
{
 if (ar.IsStoring())
 {
   // TODO: add storing code here
 }
 else
 {
   // TODO: add loading code here
 }

 // Calling the base class COleDocument enables serialization
 //  of the container document’s COleClientItem objects.
 COleDocument::Serialize(ar);
}
//////////////////////////////////////////////////////////////
// CCntDoc diagnostics

#ifdef _DEBUG
void CCntDoc::AssertValid() const
{
 COleDocument::AssertValid();
}

void CCntDoc::Dump(CDumpContext& dc) const
{
 COleDocument::Dump(dc);
}
#endif //_DEBUG

//////////////////////////////////////////////////////////////
// CCntDoc commands
The most significant change in this file comes with the expansion of the message map, as shown in bold type.
The message map will now allow the implementation of the default OLE container. You can also see that the constructor calls the EnableCompoundFile( ) function. This is required for a container application.
The Container File: CNTVIEW.CPP
The container CNTVIEW.CPP file also has some major changes in comparison to the Graph application in Chapter 24. Examine the following file and note the additions to the message map.
// CntView.cpp : implementation of the CCntView class
//

#include “stdafx.h”
#include “Cnt.h”
#include “CntDoc.h”
#include “CntrItem.h”
#include “CntView.h”

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//////////////////////////////////////////////////////////////
// CCntView

IMPLEMENT_DYNCREATE(CCntView, CView)

BEGIN_MESSAGE_MAP(CCntView, CView)
 //{{AFX_MSG_MAP(CCntView)
   // NOTE - the ClassWizard will add and remove macros.
   //    DO NOT EDIT these blocks of generated code!
 ON_WM_DESTROY()
 ON_WM_SETFOCUS()
 ON_WM_SIZE()
 ON_COMMAND(ID_OLE_INSERT_NEW, OnInsertObject)
 ON_COMMAND(ID_CANCEL_EDIT_CNTR, OnCancelEditCntr)
 //}}AFX_MSG_MAP
 // Standard printing commands
 ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////
// CCntView construction/destruction

CCntView::CCntView()
{
 m_pSelection = NULL;
 // TODO: add construction code here

}
CCntView::~CCntView()
{
}

BOOL CCntView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs

 return CView::PreCreateWindow(cs);
}

//////////////////////////////////////////////////////////////
// CCntView drawing

void CCntView::OnDraw(CDC* pDC)
{
   CCntDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here
   // TODO: also draw all OLE items in the document

 // Draw the selection at an arbitrary position.

   //  This code should be removed once your real drawing
   //  code is implemented.  This position corresponds exactly
   //  to the rectangle returned by CCntCntrItem,
   //  to give the effect of in-place editing.

 // TODO: remove this code when final draw code is complete.


 if (m_pSelection == NULL)

 {
       POSITION pos = pDoc->GetStartPosition();
       m_pSelection = (CCntCntrItem*)pDoc->GetNextClientItem(pos);
 }
 if (m_pSelection != NULL)
     m_pSelection->Draw(pDC, CRect(10, 10, 210, 210));
}

void CCntView::OnInitialUpdate()
{
 CView::OnInitialUpdate();


 // TODO: remove this code when final code is written
 m_pSelection = NULL;    // initialize selection

}
//////////////////////////////////////////////////////////////
// CCntView printing

BOOL CCntView::OnPreparePrinting(CPrintInfo* pInfo)
{
 // default preparation
 return DoPreparePrinting(pInfo);
}

void CCntView::OnBeginPrinting(CDC* /*pDC*/,
                              CPrintInfo* /*pInfo*/)
{
 // TODO: add extra initialization before printing
}

void CCntView::OnEndPrinting(CDC* /*pDC*/,
                            CPrintInfo* /*pInfo*/)
{
 // TODO: add cleanup after printing
}
void CCntView::OnDestroy()
{
 // Deactivate the item on destruction; this is important
 // when a splitter view is being used.
  CView::OnDestroy();
  COleClientItem* pActiveItem = GetDocument()->
                                GetInPlaceActiveItem(this);
  if (pActiveItem != NULL && pActiveItem->
                             GetActiveView() == this)
  {
     pActiveItem->Deactivate();
     ASSERT(GetDocument()->
            GetInPlaceActiveItem(this) == NULL);
  }
}


//////////////////////////////////////////////////////////////
// OLE Client support and commands

BOOL CCntView::IsSelected(const CObject* pDocItem) const
{
 // The implementation below is adequate if your selection
 //  consists of only CCntCntrItem objects.  To handle
 //  different selection mechanisms, the implementation
 //  here should be replaced.
 // TODO: implement this function that tests for a selected
 // OLE client item

 return pDocItem == m_pSelection;
}

void CCntView::OnInsertObject()
{
 // Invoke standard Insert Object dialog box for information
 //  for new CCntCntrItem object.
 COleInsertDialog dlg;
 if (dlg.DoModal(COleInsertDialog::DocObjectsOnly) != IDOK)
   return;

 BeginWaitCursor();

 CCntCntrItem* pItem = NULL;
 TRY
 {
   // Create new item connected to this document.
   CCntDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   pItem = new CCntCntrItem(pDoc);
   ASSERT_VALID(pItem);
   // Initialize the item from the dialog data.
   if (!dlg.CreateItem(pItem))
     AfxThrowMemoryException();  // any exception will do
   ASSERT_VALID(pItem);

   // If item created from class list, not from file, launch
   //  the server to edit the item.
   if (dlg.GetSelectionType() ==
           COleInsertDialog::createNewItem)
     pItem->DoVerb(OLEIVERB_SHOW, this);

   ASSERT_VALID(pItem);

   // As an arbitrary interface, this sets the selection
   //  to the last item inserted.

   // TODO: reimplement selection as for your application
   m_pSelection = pItem;   // set to last inserted item
   pDoc->UpdateAllViews(NULL);
 }
 CATCH(CException, e)
 {
   if (pItem != NULL)
   {
     ASSERT_VALID(pItem);
     pItem->Delete();
   }
   AfxMessageBox(IDP_FAILED_TO_CREATE);
 }
 END_CATCH

 EndWaitCursor();
}

// The following command handler provides standard keyboard
//  user interface to cancel an in-place editing session.
//  The container (not the server) causes the deactivation.
void CCntView::OnCancelEditCntr()
{
 // Close any in-place active item on this view.
 COleClientItem* pActiveItem = GetDocument()->
                               GetInPlaceActiveItem(this);
 if (pActiveItem != NULL)
 {
   pActiveItem->Close();
 }
 ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
// Special handling of OnSetFocus and OnSize is required for
//  a container when an object is being edited in-place.
void CCntView::OnSetFocus(CWnd* pOldWnd)
{
 COleClientItem* pActiveItem = GetDocument()->
                               GetInPlaceActiveItem(this);
 if (pActiveItem != NULL &&
   pActiveItem->GetItemState() ==
                COleClientItem::activeUIState)
 {
   // need to set focus to this item if in the same view
   CWnd* pWnd = pActiveItem->GetInPlaceWindow();
   if (pWnd != NULL)
   {
     pWnd->SetFocus();   // don’t call the base class
     return;
   }
 }

 CView::OnSetFocus(pOldWnd);
}
void CCntView::OnSize(UINT nType, int cx, int cy)
{
 CView::OnSize(nType, cx, cy);
 COleClientItem* pActiveItem = GetDocument()->
                               GetInPlaceActiveItem(this);
 if (pActiveItem != NULL)
   pActiveItem->SetItemRects();
}
//////////////////////////////////////////////////////////////
// CCntView diagnostics

#ifdef _DEBUG
void CCntView::AssertValid() const
{
 CView::AssertValid();
}

void CCntView::Dump(CDumpContext& dc) const
{
 CView::Dump(dc);
}
CCntDoc* CCntView::GetDocument() // non-debug version
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCntDoc)));
 return (CCntDoc*)m_pDocument;
}
#endif //_DEBUG

//////////////////////////////////////////////////////////////
// CCntView message handlers
So that it can handle drawing (i.e., inserted objects) for CCntView container, the OnDraw( ) member function has to be altered by the AppWizard. This portion of code was shown in bold type in the file. Here is just a small portion of that code:
if (m_pSelection != NULL)
   m_pSelection->Draw(pDC, CRect(10, 10, 210, 210));
}
This code, by default, places the object at a prearranged location designated by CRect( ) at 10,10 and 210,210. These values can be changed manually or automatically.
Other additions include OnInitialUpdate( ), IsSelected( ), OnInsertObject( ), OnCancelEdit( ), OnSetFocus( ), and OnSize( ). These signal when an OLE object is selected or otherwise being manipulated. OnInsertObject( ) runs COleInsertDialog. Any additional code for these functions must be supplied by you, the programmer.
The Container File: CNTRITEM.CPP
The container CNTVIEW.CPP file also has some major changes in comparison to the Graph application in Chapter 24. Examine the following file and note the additions to the message map.
// CntrItem.cpp : implementation of the CCntCntrItem class
//

#include “stdafx.h”
#include “Cnt.h”

#include “CntDoc.h”
#include “CntView.h”
#include “CntrItem.h”

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////
// CCntCntrItem implementation

IMPLEMENT_SERIAL(CCntCntrItem, COleClientItem, 0)

CCntCntrItem::CCntCntrItem(CCntDoc* pContainer)
 : COleClientItem(pContainer)
{
 // TODO: add one-time construction code here
 
}
CCntCntrItem::~CCntCntrItem()
{
 // TODO: add cleanup code here
 
}

void CCntCntrItem::OnChange(OLE_NOTIFICATION nCode,
                           DWORD dwParam)
{
 ASSERT_VALID(this);
 COleClientItem::OnChange(nCode, dwParam);

 // When an item is being edited (in-place or fully open)
 //  it sends OnChange notifications for changes in the state
 //  of the item or visual appearance of its content.

 // TODO: invalidate the item by calling UpdateAllViews
 //  (with hints appropriate to your application)

 GetDocument()->UpdateAllViews(NULL);
   // for now just update ALL views/no hints
}

BOOL CCntCntrItem::OnChangeItemPosition(const CRect& rectPos)
{
 ASSERT_VALID(this);
 // In-place activation CCntCntrItem::OnChangeItemPosition
 //  is called to change the position of the in-place
 //  window. This is a result of the data in the server
 //  document changing when the extent has changed or as a
 //  result of in-place resizing.
 //
 // The default is to call the base class, which will call
 //  COleClientItem::SetItemRects to move the item
 //  to the new position.

 if (!COleClientItem::OnChangeItemPosition(rectPos))
   return FALSE;

 // TODO: update any cache of the item’s rectangle/extent

 return TRUE;
}
void CCntCntrItem::OnGetItemPosition(CRect& rPosition)
{
   ASSERT_VALID(this);

 // In-place activation, CCntCntrItem::OnGetItemPosition

   //  will determine the location of this item.  The default
  //  implementation simply returns a hard-coded
  //  rectangle. This rectangle would reflect the current

   //  position of the item relative to the view used
   // for activation.
   // Obtain the view by calling CCntCntrItem::GetActiveView.

 // TODO: return correct rectangle (in pixels) in rPosition


 rPosition.SetRect(10, 10, 210, 210);

}
void CCntCntrItem::OnActivate()
{
   // Allow only one inplace activate item per frame
   CCntView* pView = GetActiveView();
   ASSERT_VALID(pView);
   COleClientItem* pItem = GetDocument()->
                           GetInPlaceActiveItem(pView);
   if (pItem != NULL && pItem != this)
       pItem->Close();
   
   COleClientItem::OnActivate();
}

void CCntCntrItem::OnDeactivateUI(BOOL bUndoable)
{
 COleClientItem::OnDeactivateUI(bUndoable);
   // Hide the object if it is not an outside-in object
   DWORD dwMisc = 0;
   m_lpObject->GetMiscStatus(GetDrawAspect(), &dwMisc);
   if (dwMisc & OLEMISC_INSIDEOUT)
       DoVerb(OLEIVERB_HIDE, NULL);
}

void CCntCntrItem::Serialize(CArchive& ar)
{
 ASSERT_VALID(this);

 // Call base class to read in COleClientItem data.
 // This sets up the m_pDocument pointer returned from
 //  CCntCntrItem::GetDocument, it is a good idea to call
 //  the base class Serialize first.
 COleClientItem::Serialize(ar);
 // now store/retrieve data specific to CCntCntrItem
 if (ar.IsStoring())
 {
   // TODO: add storing code here
 }
 else
 {
   // TODO: add loading code here
 }
}

//////////////////////////////////////////////////////////////
// CCntCntrItem diagnostics

#ifdef _DEBUG
void CCntCntrItem::AssertValid() const
{
 COleClientItem::AssertValid();
}
void CCntCntrItem::Dump(CDumpContext& dc) const
{
 COleClientItem::Dump(dc);
}
#endif

//////////////////////////////////////////////////////////////
The main purpose of this file is to help monitor the position and size of the item in the drawing. Examine the portion of code set in bold type. Have you seen these coordinates before?
In the next section, you’ll see how to use the container application to accept an object from a server.

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net