Sometimes you need to open the OLE document, Microsoft provides the source code for the DSOFramer control, but DSOFramer encounters a lot of bugs during use, so I try to borrow the document view structure to write a control of the OLE document. . 1. Start C 6.0, create an item of the MFC ActiveX ControlWizard type, here TestCtrl is used as the project name, the wizard automatically generates a CTestCtrlCtrl class. 2. Start another C 6.0, create a single document application, support OLE container and ActiveX, here SDI is used as the project name. 3. Join the mainfrm.cpp, mainfrm.h, sdiview.cpp, sdiview.h, sdidoc.cpp, sdidoc.h, cntritem.cpp, sdidoc.h, cntritem.cpp, cntritem.h, add the #include "SDI of these files in the TestCtrl project .h "removed. 4. CTestCtrlCtrl added in the control class header file CMainFrame * m_pMainFrame; add the following code CTestCtrlCtrl OnCreate class virtual function to create a main frame: RECT rect; this-> GetClientRect (& rect); m_pMainFrame = new CMainFrame; m_pMainFrame-> Create (NULL, Frame, WS_CHILD | WS_VISIBLE, RECT, (CWND *); This created framework will be included by the control. If you add a WS_OVERLAPPEDWINDOW style, you will see interesting phenomena. Add the following members in the CMAINFRAME class: ccreateContext * m_pccctext; csdidoc * m_psdidoc; csingledoctemplate * m_pnewdocTemplate;
The frame creation function is changed as follows: add a public function setTemplate void csdidoc :: setTemplate (CDOCTemplate * P) {this-> m_pdoctemplate = p; // Todo: add one-time construction code here}
int CMainFrame :: OnCreate (LPCREATESTRUCT lpCreateStruct) {m_pSDIDoc = new CSDIDoc; m_pSDIDoc-> OnNewDocument (); m_pNewDocTemplate = new CSingleDocTemplate (IDR_MENU1, RUNTIME_CLASS (CSDIDoc), RUNTIME_CLASS (CMainFrame), // main SDI frame window RUNTIME_CLASS (CSDIView)) ;
m_pCctext = new CCreateContext; m_pCctext-> m_pCurrentDoc = m_pSDIDoc; m_pCctext-> m_pCurrentFrame = this; m_pCctext-> m_pLastView = NULL; m_pCctext-> m_pNewDocTemplate = m_pNewDocTemplate; m_pCctext-> m_pNewViewClass = RUNTIME_CLASS (CSDIView); lpCreateStruct-> lpCreateParams = m_pCctext;
m_pnewdocTemplate-> addDocument (m_psdidoc); m_psdidoc-> setTemplate (m_pnewdoctemplate);
IF (CFrameWnd :: OnCreate (lpCreateStruct) == -1) // The changed lpCreatestruct is incorporated by parameters. Return -1;
Position POS = m_psdidoc-> getFirstViewPosition (); // Set the new view created to the current view so that the framework uses the getActiveView function. While (POS! = null) {cView * pView = m_psdidoc-> getNextView (POS); assert_valid (pView); this-> setActiveView (pView);} return 0; // Here, remove the previous frame code, not deleted can. }
Rewote the CSDICNTRITEM virtual function, nothing, will not add the OLE server program to our menu Void csdicntritem :: OnInsertmenus (cmenu * pmenushared, lpolemenugroupwidths lpufacths) {
}
5. Respond to the WM_SIZE message of the control, add the following code: m_pmaInframe-> setWindowPos (& CWnd :: WNDTOP, 0, 0, CX, CY, SWP_NOMOVE);
In this way, the document view structure that supports the OLE container is embedded in the control. If you add Open (LPCTSTR PATH) and Close () COM interface functions, main frameworks, and views, the PUBLIC function open (LPCTSTR PATH) and Close () controls are added: void ctestctrlctrl :: Open (lpctstr path) {//// Todo: add your dispatch handler code here m_pmainframe-> assertvalid (); if (m_pmaInframe! = Null) {m_pmainframe-> close (); m_pmaInframe-> open (path);}}
void CTestCtrlCtrl :: Close () {// TODO: Add your dispatch handler code here m_pMainFrame-> AssertValid (); if (m_pMainFrame = NULL!) m_pMainFrame-> Close ();} off control when the notification framework: void CTestCtrlCtrl :: ONDESTROY () {Colecontrol :: ONDESTROY (); m_pmaInframe-> sendMessage (wm_close);
In the main frame: void cmainframe :: Open (lpcstr path) {csdiView * pView = (csdiView *) this-> getActiveView (); if (pView! = Null) {pView-> assertvalid (); pView-> open (PATH }
// Todo: add your message handler code here}
Void CMAINFRAME :: Close () {csdiView * pView = (csdiView *) this-> getActiveView (); if (pView! = null) {pView-> assertvalid (); pView-> close ();}
// Todo: add your message handler code here}
View: void CSDIView :: Close () {COleClientItem * pActiveItem = GetDocument () -> GetInPlaceActiveItem (this); if (! PActiveItem = NULL && pActiveItem-> GetActiveView () == this) {// pActiveItem-> Deactivate ( PACTIVEITEM-> Delete (); pactiveItem-> release (); assert () -> getInplaceActiveItem (this) == null);}} void csdiView :: open (lpcstr path) {// Change The Cursor SO .
CSDICNTRITEM * PITEM = NULL; try {// Get the Document Associated with this view, and be suhe supething t // Valid. Csdidoc * pdoc = getDocument (); assert_valid (pdoc);
// Create a new item associated with this document, and be sure that // it is valid. Pitem = new csdicntritem (PDOC); assert_valid (pitem);
// Create the Excel Embedded Item. If (! Pitem-> createfromfile (path) AFXTHROWMEMORYEXCEPTION ();
// Make Sure The New CconTainer IS Valid. Assert_Valid (Pitem); this-> assertvalid (); // start the server to edit the item.
Pitem-> Doverb (oleiverb_show, this);
// as an arbitrary user interface design, this set it // selection to the last item inserted. M_pselection = pitem; // set selection to last inserted. Item pdoc-> updateAllViews (null);
This} This, with the MFC document view structure, an OLE document viewer is done. Gu Dongyan 2005. 4. 5