DOCUMENT:Q195031 17-JUL-2001 [visualc] TITLE :HOWTO: Adding Splitter Bars Support to Active Document Server PRODUCT :Microsoft C Compiler PROD/VER:winnt:5.0,6.0 OPER/SYS: KEYWORDS:kbole kbActiveDocs kbActiveX kbCOMt kbLocalSvr kbMFC kbVC500 kbVC600 kbDSupport kbGrpDS ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - The Microsoft Foundation Classes (MFC), used with: - Microsoft Visual C++, 32-bit Enterprise Edition, version 5.0 - Microsoft Visual C++, 32-bit Professional Edition, version 5.0 - Microsoft Visual C++, 32-bit Enterprise Edition, version 6.0 - Microsoft Visual C++, 32-bit Professional Edition, version 6.0 - Microsoft Visual C++, 32-bit Learning Edition, version 6.0 ------------------------------------------------------------------------------- SUMMARY ======= An Active Document Server (or DocObject Server) that has a splitter window (CSplitterWnd class) as its view will have splitter bars show up fine when it is running as a stand alone application. However, the splitter bars won't show up when it is embedded in an Active Document Container such as Internet Explorer or Microsoft Binder. This article presents a way to show the splitter bars in those containers. MORE INFORMATION ================ The BINDSCRB sample illustrates an example of building an Active Document Server. The code below is added to BINDSCRB for the splitter bars support. Steps to be taken: ------------------ 1. Copy BINSCRB sample from Visual C++ CD-ROM. 2. Override CreateInPlaceFrame() in CScribDoc class (a COleServerDoc- derived class). This function is called to create a frame window for in- place editing. The function is modified so it uses a splitter window (CSplitterWnd class) as the view of the in-place frame window (a COleDocIPFrameWnd-derived class). COleIPFrameWnd* CScribDoc::CreateInPlaceFrame(CWnd* pParentWnd) { ASSERT_VALID(this); ASSERT_VALID(pParentWnd); // Get run-time class from the doc template. CDocTemplate* pTemplate = GetDocTemplate(); ASSERT_VALID(pTemplate); // Use existing view if possible. CView* pView = NULL; CFrameWnd* pFrame = GetFirstFrame(); if (pFrame != NULL) { pView = (CView*)pFrame->GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE); if (pView != NULL) { ASSERT_KINDOF(CView, pView); m_dwOrigStyle = pView->GetStyle(); m_dwOrigStyleEx = pView->GetExStyle(); } } // Create the frame from the template, ALWAYS use the CView of the // CSplitterWnd. COleIPFrameWnd* pFrameWnd = (COleIPFrameWnd*) pTemplate->CreateOleFrame(pParentWnd, this, FALSE); if (pFrameWnd == NULL) return NULL; // Connect the splitter window (CSplitterWnd class) to the // COleDocIPFrameWnd. CWnd* split = pFrame->GetWindow(GW_CHILD); VERIFY(pFrame == split->SetParent(pFrameWnd)); // Remember the original parent window for deactivate--uses the // CFrameWnd-derived class (that is, CMDIChildWnd for MDI). m_pOrigParent = pFrame; // Set the active view of COleDocIPFrameWnd. pFrameWnd->SetActiveView(pView, FALSE); pFrameWnd->RecalcLayout(); pView->ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_DRAWFRAME); // Verify the type. ASSERT_VALID(pFrameWnd); ASSERT_KINDOF(COleIPFrameWnd, pFrameWnd); return pFrameWnd; } 3. Override DestroyInPlaceFrame() in CScribDoc class (a COleServerDoc- derived class) to destroy the in-place frame window and return the server application's document window to its state before in-place activation. void CScribDoc::DestroyInPlaceFrame(COleIPFrameWnd* pFrameWnd) { ASSERT_VALID(this); ASSERT_VALID(pFrameWnd); // connect view to original, if existing view was used if (m_pOrigParent != NULL) { CView* pView = (CView*)pFrameWnd->GetDescendantWindow( AFX_IDW_PANE_FIRST, TRUE); ASSERT_VALID(pView); // Leaving the focus on an MDI child or one of its child // windows causes Windows to get confused when the child window // is destroyed, not to mention the fact that the focus will be // out of sync with activation. if (::GetFocus() == pView->m_hWnd) { // Move focus to somewhere safe. HWND hWnd = ::GetParent(pFrameWnd->m_hWnd); if (hWnd != NULL) ::SetFocus(hWnd); // Check again. if (::GetFocus() == pView->m_hWnd) SetFocus(NULL); // last ditch effort } // Set parent of the splitter window (CSplitterWnd class) to be // the CFrameWnd-derived class (that is, CMDIChildWnd for MDI // application). ASSERT_KINDOF(CFrameWnd, m_pOrigParent); CFrameWnd* frame = (CFrameWnd*) m_pOrigParent; CWnd* split = pFrameWnd->GetWindow(GW_CHILD); VERIFY(pFrameWnd == split->SetParent(frame)); // Set the active view of CFrameWnd-derived class (that is, // CMDIChildWnd for MDI application). frame->SetActiveView(pView, FALSE); frame->RecalcLayout(); m_pOrigParent = NULL; // Remove any scrollbars added because of in-place activation. if ((m_dwOrigStyle & (WS_HSCROLL|WS_VSCROLL)) == 0 && (pView->GetStyle() & (WS_HSCROLL|WS_VSCROLL)) != 0) { ::SetScrollRange(pView->m_hWnd, SB_HORZ, 0, 0, TRUE); ::SetScrollRange(pView->m_hWnd, SB_VERT, 0, 0, TRUE); } // Restore old 3D style. pView->ModifyStyleEx(0, m_dwOrigStyleEx & WS_EX_CLIENTEDGE, SWP_DRAWFRAME); // Force recalc layout on splitter window. CSplitterWnd* pSplitter = CView::GetParentSplitter(pView, TRUE); if (pSplitter != NULL) pSplitter->RecalcLayout(); } // No active view or document during destroy. pFrameWnd->SetActiveView(NULL); // Destroy in-place frame window. pFrameWnd->DestroyWindow(); } REFERENCES ========== References from Visual C++ online documentation: TN029: Splitter Windows BINDSCRB: Illustrates an MFC Binder-Compatible Server (c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Yeong- Kah Tam, Microsoft Corporation. Additional query words: ====================================================================== Keywords : kbole kbActiveDocs kbActiveX kbCOMt kbLocalSvr kbMFC kbVC500 kbVC600 kbDSupport kbGrpDSMFCATL Technology : kbAudDeveloper kbMFC Version : winnt:5.0,6.0 Issue type : kbhowto ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 2001.