Article ID: 195031
Article Last Modified on 11/21/2006
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;
}
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();
}
TN029: Splitter Windows BINDSCRB: Illustrates an MFC Binder-Compatible Server(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Yeong- Kah Tam, Microsoft Corporation.
Keywords: kbactivedocs kbhowto kblocalsvr KB195031