HOWTO: Adding Splitter Bars Support to Active Document Server
ID: Q195031
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), included with:
-
Microsoft Visual C++, 32-bit Editions, versions 5.0, 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:
- Copy BINSCRB sample from Visual C++ CD-ROM.
- 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;
}
- 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:
kbDSupport
Keywords : kbole kbActiveX kbCOMt kbMFC kbVC500 kbVC600
Version : WINNT:5.0,6.0
Platform : winnt
Issue type : kbhowto
|