mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1433 lines
34 KiB
1433 lines
34 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#include "stdafx.h"
|
|
|
|
#ifdef _MAC
|
|
#include <macname1.h>
|
|
#include <Processes.h>
|
|
#include <macname2.h>
|
|
#endif
|
|
|
|
#ifdef AFX_OLE2_SEG
|
|
#pragma code_seg(AFX_OLE2_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleFrameHook Construction & Destruction
|
|
|
|
COleFrameHook::COleFrameHook(CFrameWnd* pFrameWnd, COleClientItem* pItem)
|
|
{
|
|
ASSERT_VALID(pItem);
|
|
ASSERT_VALID(pFrameWnd);
|
|
|
|
m_lpActiveObject = NULL;
|
|
m_pActiveItem = pItem;
|
|
m_pFrameWnd = pFrameWnd;
|
|
m_hWnd = pFrameWnd->m_hWnd;
|
|
m_bToolBarHidden = FALSE;
|
|
m_hAccelTable = NULL;
|
|
m_bInModalState = FALSE;
|
|
m_nModelessCount = 0;
|
|
pFrameWnd->m_pNotifyHook = this; // assume start out hooked
|
|
|
|
ASSERT_VALID(this);
|
|
}
|
|
|
|
COleFrameHook::~COleFrameHook()
|
|
{
|
|
if (m_pFrameWnd != NULL)
|
|
{
|
|
ASSERT_VALID(m_pFrameWnd);
|
|
if (m_pFrameWnd->m_pNotifyHook == this)
|
|
m_pFrameWnd->m_pNotifyHook = NULL;
|
|
}
|
|
|
|
ASSERT_VALID(this);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleFrameHook overrides
|
|
|
|
void COleFrameHook::OnRecalcLayout()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_lpActiveObject == NULL)
|
|
return;
|
|
|
|
// get current border size (without current server control bars)
|
|
RECT rectBorder;
|
|
m_pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderGet, &rectBorder);
|
|
|
|
// allow server to resize/move its control bars
|
|
m_lpActiveObject->ResizeBorder(&rectBorder, &m_xOleInPlaceFrame,
|
|
m_pActiveItem->m_pInPlaceFrame == this);
|
|
}
|
|
|
|
BOOL COleFrameHook::OnDocActivate(BOOL bActive)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
#ifndef _MAC
|
|
|
|
if (m_lpActiveObject == NULL)
|
|
return TRUE;
|
|
|
|
// allow server to do document activation related actions
|
|
m_lpActiveObject->OnDocWindowActivate(bActive);
|
|
|
|
// make sure window caption gets updated later
|
|
COleFrameHook* pNotifyHook = m_pActiveItem->m_pInPlaceFrame;
|
|
pNotifyHook->m_pFrameWnd->DelayUpdateFrameTitle();
|
|
|
|
if (!bActive)
|
|
{
|
|
// clear border space
|
|
pNotifyHook->m_xOleInPlaceFrame.SetBorderSpace(NULL);
|
|
if (m_pActiveItem->m_pInPlaceDoc != NULL)
|
|
m_pActiveItem->m_pInPlaceDoc->m_xOleInPlaceFrame.SetBorderSpace(NULL);
|
|
|
|
// remove the menu hook when the doc is not active
|
|
pNotifyHook->m_xOleInPlaceFrame.SetMenu(NULL, NULL, NULL);
|
|
|
|
// unhook top-level frame if not needed
|
|
if (pNotifyHook != this)
|
|
{
|
|
// shouldn't be removing some other hook
|
|
ASSERT(pNotifyHook->m_pFrameWnd->m_pNotifyHook == pNotifyHook);
|
|
pNotifyHook->m_pFrameWnd->m_pNotifyHook = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// rehook top-level frame if necessary (no effect if top-level == doc-level)
|
|
pNotifyHook->m_pFrameWnd->m_pNotifyHook = pNotifyHook;
|
|
}
|
|
|
|
// don't do default if activating
|
|
return bActive;
|
|
|
|
#else // _MAC
|
|
|
|
if ((!bActive) && (m_pActiveItem != NULL))
|
|
{
|
|
ProcessSerialNumber psn;
|
|
|
|
m_pActiveItem->Deactivate();
|
|
|
|
psn.highLongOfPSN = 0;
|
|
psn.lowLongOfPSN = kCurrentProcess;
|
|
SetFrontProcess(&psn);
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
#endif // _MAC
|
|
}
|
|
|
|
BOOL COleFrameHook::OnContextHelp(BOOL bEnter)
|
|
{
|
|
ASSERT_VALID(this);
|
|
if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
|
|
return TRUE;
|
|
|
|
// allow all servers to enter/exit context sensitive help mode
|
|
return NotifyAllInPlace(bEnter, &COleFrameHook::DoContextSensitiveHelp);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleFrameHook callbacks for the top-level frame
|
|
|
|
BOOL COleFrameHook::OnPreTranslateMessage(MSG* pMsg)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
|
|
return FALSE;
|
|
|
|
// allow server to translate accelerators
|
|
if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
|
|
return m_lpActiveObject->TranslateAccelerator(pMsg) == S_OK;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void COleFrameHook::OnActivate(BOOL bActive)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
|
|
return;
|
|
|
|
#ifdef _MAC
|
|
if(bActive)
|
|
{
|
|
afxData.bOleIgnoreSuspend = TRUE;
|
|
}
|
|
#endif
|
|
|
|
if (m_pFrameWnd->IsWindowEnabled())
|
|
{
|
|
// allow active server to do frame level activation
|
|
m_lpActiveObject->OnFrameWindowActivate(bActive);
|
|
}
|
|
}
|
|
|
|
void COleFrameHook::OnEnableModeless(BOOL bEnable)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
|
|
return;
|
|
|
|
// allow server to disable/enable modeless dialogs
|
|
NotifyAllInPlace(bEnable, &COleFrameHook::DoEnableModeless);
|
|
}
|
|
|
|
BOOL COleFrameHook::OnUpdateFrameTitle()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT_VALID(m_pActiveItem);
|
|
|
|
if (m_lpActiveObject == NULL || m_pActiveItem->m_pInPlaceFrame != this)
|
|
return FALSE;
|
|
|
|
return m_pActiveItem->OnUpdateFrameTitle();
|
|
}
|
|
|
|
void COleFrameHook::OnPaletteChanged(CWnd* pFocusWnd)
|
|
{
|
|
CWnd* pWnd = m_pActiveItem->GetInPlaceWindow();
|
|
if (pWnd != NULL)
|
|
pWnd->SendMessage(WM_PALETTECHANGED, (WPARAM)pFocusWnd->GetSafeHwnd());
|
|
}
|
|
|
|
BOOL COleFrameHook::OnQueryNewPalette()
|
|
{
|
|
CWnd* pWnd = m_pActiveItem->GetInPlaceWindow();
|
|
if (pWnd != NULL)
|
|
return pWnd->SendMessage(WM_QUERYNEWPALETTE);
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Helpers for notifications that have to affect all in-place windows
|
|
|
|
BOOL COleFrameHook::NotifyAllInPlace(
|
|
BOOL bParam, BOOL (COleFrameHook::*pNotifyFunc)(BOOL bParam))
|
|
{
|
|
ASSERT_VALID(this);
|
|
HWND hWndFrame = m_hWnd;
|
|
CWinApp* pApp = AfxGetApp();
|
|
|
|
// no doc manager - no templates
|
|
if (pApp->m_pDocManager == NULL)
|
|
return TRUE;
|
|
|
|
// walk all templates in the application
|
|
CDocTemplate* pTemplate;
|
|
POSITION pos = pApp->m_pDocManager->GetFirstDocTemplatePosition();
|
|
while (pos != NULL)
|
|
{
|
|
pTemplate = pApp->m_pDocManager->GetNextDocTemplate(pos);
|
|
ASSERT_VALID(pTemplate);
|
|
ASSERT_KINDOF(CDocTemplate, pTemplate);
|
|
|
|
// walk all documents in the template
|
|
POSITION pos2 = pTemplate->GetFirstDocPosition();
|
|
while (pos2)
|
|
{
|
|
COleDocument* pDoc = (COleDocument*)pTemplate->GetNextDoc(pos2);
|
|
ASSERT_VALID(pDoc);
|
|
if (pDoc->IsKindOf(RUNTIME_CLASS(COleDocument)))
|
|
{
|
|
// walk all COleClientItem objects in the document
|
|
COleClientItem* pItem;
|
|
POSITION pos3 = pDoc->GetStartPosition();
|
|
while ((pItem = pDoc->GetNextClientItem(pos3)) != NULL)
|
|
{
|
|
if (pItem->m_pInPlaceFrame != NULL &&
|
|
pItem->m_pInPlaceFrame->m_lpActiveObject != NULL &&
|
|
pItem->m_pView != NULL &&
|
|
AfxIsDescendant(hWndFrame, pItem->m_pView->m_hWnd))
|
|
{
|
|
// Whew! Found an in-place active item that is
|
|
// part of this frame window hierarchy.
|
|
COleFrameHook* pNotifyHook = pItem->m_pInPlaceFrame;
|
|
if (!(pNotifyHook->*pNotifyFunc)(bParam))
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL COleFrameHook::DoContextSensitiveHelp(BOOL bEnter)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_lpActiveObject != NULL);
|
|
|
|
return !FAILED(m_lpActiveObject->ContextSensitiveHelp(bEnter));
|
|
}
|
|
|
|
BOOL COleFrameHook::DoEnableModeless(BOOL bEnable)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_lpActiveObject != NULL);
|
|
|
|
// allow server to enable/disable any modeless windows
|
|
if (!bEnable)
|
|
{
|
|
if (m_nModelessCount++ == 0)
|
|
m_lpActiveObject->EnableModeless(FALSE);
|
|
}
|
|
else
|
|
{
|
|
if (m_nModelessCount != 0 && --m_nModelessCount == 0)
|
|
m_lpActiveObject->EnableModeless(TRUE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleClientItem - default in-place activation implementation
|
|
|
|
BOOL COleClientItem::CanActivate()
|
|
{
|
|
// don't allow in-place activations with iconic aspect items
|
|
if (m_nDrawAspect == DVASPECT_ICON)
|
|
return FALSE;
|
|
|
|
// if no view has been set, attempt to find suitable one.
|
|
// (necessary to get links to embeddings to work correctly)
|
|
if (m_pView == NULL)
|
|
{
|
|
// only use pActivateView if this item is in same document
|
|
_AFX_OLE_STATE* pOleState = _afxOleState;
|
|
if (pOleState->m_pActivateView != NULL &&
|
|
pOleState->m_pActivateView->GetDocument() != GetDocument())
|
|
{
|
|
pOleState->m_pActivateView = NULL; // not in same document
|
|
}
|
|
|
|
CView* pView = pOleState->m_pActivateView;
|
|
if (pView == NULL)
|
|
{
|
|
// no routing view available - just use first one
|
|
COleDocument* pDoc = GetDocument();
|
|
POSITION pos = pDoc->GetFirstViewPosition();
|
|
pView = pDoc->GetNextView(pos);
|
|
}
|
|
m_pView = pView;
|
|
}
|
|
|
|
return m_pView->GetSafeHwnd() != NULL;
|
|
}
|
|
|
|
void COleClientItem::OnActivate()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// it is necessary to lock the object when it is in-place
|
|
// (without this, a link to an embedding may disconnect unexpectedly)
|
|
if (!m_bLocked)
|
|
{
|
|
OleLockRunning(m_lpObject, TRUE, FALSE);
|
|
m_bLocked = TRUE;
|
|
}
|
|
|
|
// notify the item of the state change
|
|
if (m_nItemState != activeState)
|
|
{
|
|
OnChange(OLE_CHANGED_STATE, (DWORD)activeState);
|
|
m_nItemState = activeState;
|
|
}
|
|
}
|
|
|
|
void COleClientItem::OnActivateUI()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// notify the item of the state change
|
|
if (m_nItemState != activeUIState)
|
|
{
|
|
OnChange(OLE_CHANGED_STATE, (DWORD)activeUIState);
|
|
m_nItemState = activeUIState;
|
|
}
|
|
|
|
// the container window must have WS_CLIPCHILDREN set
|
|
ASSERT_VALID(m_pView);
|
|
m_dwContainerStyle = m_pView->GetStyle();
|
|
m_pView->ModifyStyle(0, WS_CLIPCHILDREN);
|
|
|
|
// cache the server's HWND for later
|
|
LPOLEINPLACEOBJECT lpInPlaceObject =
|
|
QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
|
|
ASSERT(lpInPlaceObject != NULL);
|
|
|
|
// get the HWND for the in-place active object
|
|
HWND hWnd;
|
|
if (lpInPlaceObject->GetWindow(&hWnd) != S_OK)
|
|
hWnd = NULL;
|
|
lpInPlaceObject->Release();
|
|
m_hWndServer = hWnd;
|
|
|
|
// make sure top-level frame is hooked
|
|
if (m_pInPlaceFrame != NULL)
|
|
{
|
|
ASSERT_VALID(m_pInPlaceFrame->m_pFrameWnd);
|
|
m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook = m_pInPlaceFrame;
|
|
}
|
|
// make sure doc-level frame is hooked
|
|
if (m_pInPlaceDoc != NULL)
|
|
{
|
|
ASSERT_VALID(m_pInPlaceDoc->m_pFrameWnd);
|
|
m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook = m_pInPlaceDoc;
|
|
}
|
|
}
|
|
|
|
BOOL COleClientItem::OnShowControlBars(CFrameWnd* pFrameWnd, BOOL bShow)
|
|
{
|
|
ASSERT_VALID(pFrameWnd);
|
|
ASSERT_VALID(this);
|
|
|
|
// show/hide all bars marked with CBRS_HIDE_INPLACE style
|
|
BOOL bResult = FALSE;
|
|
if (bShow)
|
|
{
|
|
POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CControlBar* pBar =
|
|
(CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
|
|
ASSERT_VALID(pBar);
|
|
if ((pBar->GetBarStyle() & CBRS_HIDE_INPLACE) &&
|
|
(pBar->m_nStateFlags & CControlBar::tempHide))
|
|
{
|
|
pBar->m_nStateFlags &= ~CControlBar::tempHide;
|
|
pFrameWnd->ShowControlBar(pBar, TRUE, TRUE);
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CControlBar* pBar =
|
|
(CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
|
|
ASSERT_VALID(pBar);
|
|
if (pBar->IsVisible() && (pBar->GetBarStyle() & CBRS_HIDE_INPLACE))
|
|
{
|
|
pBar->m_nStateFlags |= CControlBar::tempHide;
|
|
pFrameWnd->ShowControlBar(pBar, FALSE, TRUE);
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
BOOL COleClientItem::OnGetWindowContext(
|
|
CFrameWnd** ppMainFrame, CFrameWnd** ppDocFrame,
|
|
LPOLEINPLACEFRAMEINFO pFrameInfo)
|
|
{
|
|
ASSERT(AfxIsValidAddress(ppMainFrame, sizeof(CFrameWnd*)));
|
|
ASSERT(AfxIsValidAddress(ppDocFrame, sizeof(CFrameWnd*)));
|
|
ASSERT(pFrameInfo == NULL ||
|
|
AfxIsValidAddress(pFrameInfo, sizeof(OLEINPLACEFRAMEINFO)));
|
|
ASSERT_VALID(this);
|
|
ASSERT_VALID(m_pView);
|
|
|
|
// get main window of application
|
|
*ppMainFrame = m_pView->GetTopLevelFrame();
|
|
ASSERT_VALID(*ppMainFrame);
|
|
ASSERT_KINDOF(CFrameWnd, *ppMainFrame);
|
|
|
|
// get document window (if there is one)
|
|
CFrameWnd* pDocFrame = m_pView->GetParentFrame();
|
|
if (pDocFrame != *ppMainFrame)
|
|
{
|
|
*ppDocFrame = pDocFrame;
|
|
ASSERT_VALID(*ppDocFrame);
|
|
ASSERT_KINDOF(CFrameWnd, *ppDocFrame);
|
|
}
|
|
|
|
if (pFrameInfo != NULL)
|
|
{
|
|
// get accelerator table
|
|
CDocTemplate* pTemplate = GetDocument()->GetDocTemplate();
|
|
HACCEL hAccel = pTemplate != NULL ? pTemplate->m_hAccelInPlace : NULL;
|
|
pFrameInfo->cAccelEntries =
|
|
hAccel != NULL ? CopyAcceleratorTable(hAccel, NULL, 0) : 0;
|
|
pFrameInfo->haccel = pFrameInfo->cAccelEntries != 0 ? hAccel : NULL;
|
|
pFrameInfo->hwndFrame = (*ppMainFrame)->m_hWnd;
|
|
pFrameInfo->fMDIApp = *ppDocFrame != NULL;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL COleClientItem::OnScrollBy(CSize sizeExtent)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT_VALID(m_pView);
|
|
|
|
// scroll through splitter or view
|
|
CSplitterWnd* pSplitter = CView::GetParentSplitter(m_pView, FALSE);
|
|
BOOL bResult;
|
|
if (pSplitter != NULL)
|
|
bResult = pSplitter->DoScrollBy(m_pView, sizeExtent);
|
|
else
|
|
bResult = m_pView->OnScrollBy(sizeExtent);
|
|
|
|
return bResult;
|
|
}
|
|
|
|
void COleClientItem::OnDeactivateUI(BOOL /*bUndoable*/)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// notify the item of the state change
|
|
if (m_nItemState != activeState)
|
|
{
|
|
OnChange(OLE_CHANGED_STATE, (DWORD)activeState);
|
|
m_nItemState = activeState;
|
|
}
|
|
|
|
if (m_pView != NULL && m_pDocument->GetFirstViewPosition())
|
|
{
|
|
// restore container window's WS_CLIPCHILDREN bit...
|
|
ASSERT_VALID(m_pView);
|
|
m_pView->ModifyStyle(WS_CLIPCHILDREN, m_dwContainerStyle & WS_CLIPCHILDREN);
|
|
}
|
|
|
|
// restore original user interface on the frame window
|
|
CFrameWnd* pMainFrame;
|
|
CFrameWnd* pDocFrame = NULL;
|
|
if (OnGetWindowContext(&pMainFrame, &pDocFrame, NULL))
|
|
{
|
|
ASSERT_VALID(pMainFrame);
|
|
pMainFrame->DelayUpdateFrameTitle();
|
|
if (pMainFrame->NegotiateBorderSpace(CFrameWnd::borderSet, NULL))
|
|
pMainFrame->DelayRecalcLayout();
|
|
|
|
// restore original user interface on the document window
|
|
if (pDocFrame != NULL)
|
|
{
|
|
pDocFrame->DelayUpdateFrameTitle();
|
|
if (pDocFrame->NegotiateBorderSpace(CFrameWnd::borderSet, NULL))
|
|
pDocFrame->DelayRecalcLayout();
|
|
}
|
|
}
|
|
|
|
// cleanup frame interfaces allocated in GetWindowContext
|
|
if (m_pInPlaceFrame != NULL)
|
|
{
|
|
OnShowControlBars(m_pInPlaceFrame->m_pFrameWnd, TRUE);
|
|
|
|
#ifndef _MAC
|
|
// release OLE frame window hooks and allow menu update
|
|
::OleSetMenuDescriptor(NULL, m_pInPlaceFrame->m_pFrameWnd->m_hWnd,
|
|
NULL, NULL, NULL);
|
|
if (m_pInPlaceDoc != NULL)
|
|
{
|
|
::OleSetMenuDescriptor(NULL, m_pInPlaceDoc->m_pFrameWnd->m_hWnd,
|
|
NULL, NULL, NULL);
|
|
}
|
|
#endif
|
|
m_pInPlaceFrame->m_pFrameWnd->DelayUpdateFrameMenu(NULL);
|
|
|
|
// unhook from frame window
|
|
if (m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook == m_pInPlaceFrame)
|
|
m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook = NULL;
|
|
|
|
// cleanup document interfaces allocated in GetWindowContext
|
|
if (m_pInPlaceDoc != NULL)
|
|
{
|
|
OnShowControlBars(m_pInPlaceDoc->m_pFrameWnd, TRUE);
|
|
|
|
// unhook from frame window
|
|
if (m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook == m_pInPlaceDoc)
|
|
m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook = NULL;
|
|
}
|
|
}
|
|
|
|
// reset server HWND -- no longer necessary
|
|
m_hWndServer = NULL;
|
|
|
|
CWnd* pWnd = AfxGetMainWnd();
|
|
if (pWnd != NULL)
|
|
{
|
|
// set focus back to the container
|
|
pWnd = pWnd->GetTopLevelParent();
|
|
ASSERT_VALID(pWnd);
|
|
if (::GetActiveWindow() == pWnd->m_hWnd)
|
|
pWnd->SetFocus();
|
|
}
|
|
}
|
|
|
|
void COleClientItem::OnDeactivate()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// notify the item of the state change
|
|
if (m_nItemState != loadedState)
|
|
{
|
|
OnChange(OLE_CHANGED_STATE, (DWORD)loadedState);
|
|
m_nItemState = loadedState;
|
|
}
|
|
|
|
// cleanup frame interfaces allocated in GetWindowContext
|
|
if (m_pInPlaceFrame != NULL)
|
|
{
|
|
// release in place frame
|
|
if (m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook == m_pInPlaceFrame)
|
|
m_pInPlaceFrame->m_pFrameWnd->m_pNotifyHook = NULL;
|
|
m_pInPlaceFrame->InternalRelease();
|
|
m_pInPlaceFrame = NULL;
|
|
|
|
// cleanup document interfaces allocated in GetWindowContext
|
|
if (m_pInPlaceDoc != NULL)
|
|
{
|
|
// release in place document
|
|
if (m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook == m_pInPlaceDoc)
|
|
m_pInPlaceDoc->m_pFrameWnd->m_pNotifyHook = NULL;
|
|
m_pInPlaceDoc->InternalRelease();
|
|
m_pInPlaceDoc = NULL;
|
|
}
|
|
}
|
|
|
|
// both frame-level and doc-level interfaces should be cleaned up
|
|
ASSERT(m_pInPlaceFrame == NULL);
|
|
ASSERT(m_pInPlaceDoc == NULL);
|
|
|
|
// no longer need the container window
|
|
m_pView = NULL;
|
|
}
|
|
|
|
void COleClientItem::OnDiscardUndoState()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// default does nothing
|
|
}
|
|
|
|
void COleClientItem::OnDeactivateAndUndo()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DeactivateUI(); // default is to UI deactivate
|
|
}
|
|
|
|
BOOL COleClientItem::OnChangeItemPosition(const CRect& rectPos)
|
|
{
|
|
if (!IsInPlaceActive())
|
|
return FALSE;
|
|
|
|
ASSERT_VALID(this);
|
|
ASSERT(AfxIsValidAddress(&rectPos, sizeof(CRect), FALSE));
|
|
ASSERT_VALID(m_pView);
|
|
|
|
// determine the visible rect based on intersection between client rect
|
|
CRect clipRect;
|
|
OnGetClipRect(clipRect);
|
|
CRect visRect;
|
|
visRect.IntersectRect(clipRect, rectPos);
|
|
|
|
// advise the server of the new visible rectangle
|
|
if (!visRect.IsRectEmpty())
|
|
return SetItemRects(&rectPos, &clipRect);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IOleInPlaceFrame notifications (default implementation)
|
|
|
|
void COleClientItem::OnInsertMenus(CMenu* pMenuShared,
|
|
LPOLEMENUGROUPWIDTHS lpMenuWidths)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT_VALID(pMenuShared);
|
|
ASSERT(AfxIsValidAddress(lpMenuWidths, sizeof(OLEMENUGROUPWIDTHS)));
|
|
|
|
// initialize the group widths array
|
|
lpMenuWidths->width[0] = 0;
|
|
lpMenuWidths->width[2] = 0;
|
|
lpMenuWidths->width[4] = 0;
|
|
|
|
// get menu from document template
|
|
CDocTemplate* pTemplate = GetDocument()->GetDocTemplate();
|
|
HMENU hMenuOLE = pTemplate->m_hMenuInPlace;
|
|
|
|
// only copy the popups if there is a menu loaded
|
|
if (hMenuOLE == NULL)
|
|
return;
|
|
|
|
// insert our menu items and adjust group widths array
|
|
AfxMergeMenus(pMenuShared, CMenu::FromHandle(hMenuOLE),
|
|
&lpMenuWidths->width[0], 0);
|
|
}
|
|
|
|
void COleClientItem::OnSetMenu(CMenu* pMenuShared, HOLEMENU holemenu,
|
|
HWND hwndActiveObject)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pInPlaceFrame != NULL);
|
|
ASSERT(m_pInPlaceFrame->m_pFrameWnd != NULL);
|
|
|
|
// don't set the doc is active
|
|
CFrameWnd* pFrameWnd = m_pInPlaceFrame->m_pFrameWnd;
|
|
ASSERT_VALID(pFrameWnd);
|
|
if (m_pInPlaceDoc != NULL &&
|
|
m_pInPlaceDoc->m_pFrameWnd != pFrameWnd->GetActiveFrame())
|
|
{
|
|
return;
|
|
}
|
|
|
|
// update the menu
|
|
pFrameWnd->DelayUpdateFrameMenu(pMenuShared->GetSafeHmenu());
|
|
|
|
#ifndef _MAC
|
|
// enable/disable the OLE command routing hook
|
|
::OleSetMenuDescriptor(holemenu, pFrameWnd->m_hWnd,
|
|
hwndActiveObject, NULL, NULL);
|
|
if (m_pInPlaceDoc != NULL)
|
|
{
|
|
pFrameWnd = m_pInPlaceDoc->m_pFrameWnd;
|
|
ASSERT_VALID(pFrameWnd);
|
|
::OleSetMenuDescriptor(holemenu, pFrameWnd->m_hWnd,
|
|
hwndActiveObject, NULL, NULL);
|
|
}
|
|
#else
|
|
holemenu;
|
|
hwndActiveObject;
|
|
#endif
|
|
}
|
|
|
|
void COleClientItem::OnRemoveMenus(CMenu* pMenuShared)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT_VALID(pMenuShared);
|
|
|
|
// get menu from document template
|
|
CDocTemplate* pTemplate = GetDocument()->GetDocTemplate();
|
|
HMENU hMenuOLE = pTemplate->m_hMenuInPlace;
|
|
if (hMenuOLE == NULL)
|
|
return;
|
|
|
|
// remove any menu popups originally added in OnInsertMenus
|
|
AfxUnmergeMenus(pMenuShared, CMenu::FromHandle(hMenuOLE));
|
|
}
|
|
|
|
BOOL COleClientItem::OnUpdateFrameTitle()
|
|
{
|
|
ASSERT_VALID(this);
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// In-place Activation operations
|
|
|
|
void COleClientItem::Deactivate()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_lpObject != NULL);
|
|
ASSERT(IsInPlaceActive());
|
|
|
|
// get IOleInPlaceObject interface
|
|
LPOLEINPLACEOBJECT lpInPlaceObject =
|
|
QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
|
|
if (lpInPlaceObject == NULL)
|
|
{
|
|
Close(); // handle rare failure cases by calling Close
|
|
return;
|
|
}
|
|
|
|
// call IOleInPlaceObject::InPlaceDeactivate
|
|
m_scLast = lpInPlaceObject->InPlaceDeactivate();
|
|
lpInPlaceObject->Release();
|
|
if (FAILED(m_scLast))
|
|
{
|
|
Close(); // handle rare failure cases by calling Close
|
|
return;
|
|
}
|
|
m_nItemState = loadedState; // just in case server has crashed
|
|
}
|
|
|
|
void COleClientItem::DeactivateUI()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_lpObject != NULL);
|
|
ASSERT(GetItemState() == activeUIState);
|
|
|
|
// get IOleInPlaceObject interface
|
|
LPOLEINPLACEOBJECT lpInPlaceObject =
|
|
QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
|
|
if (lpInPlaceObject == NULL)
|
|
{
|
|
Close(); // handle rare failure cases by calling Close
|
|
return;
|
|
}
|
|
|
|
// call IOleInPlaceObject::UIDeactivate
|
|
m_scLast = lpInPlaceObject->UIDeactivate();
|
|
lpInPlaceObject->Release();
|
|
if (FAILED(m_scLast))
|
|
{
|
|
Close(); // handle rare failure cases by calling Close
|
|
return;
|
|
}
|
|
m_nItemState = activeState; // just in case server has crashed
|
|
}
|
|
|
|
BOOL COleClientItem::SetItemRects(LPCRECT lpPosRect, LPCRECT lpClipRect)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_lpObject != NULL);
|
|
ASSERT(IsInPlaceActive());
|
|
ASSERT(lpPosRect == NULL ||
|
|
AfxIsValidAddress(lpPosRect, sizeof(RECT), FALSE));
|
|
ASSERT(lpClipRect == NULL ||
|
|
AfxIsValidAddress(lpClipRect, sizeof(RECT), FALSE));
|
|
|
|
// get IOleInPlaceObject interface
|
|
LPOLEINPLACEOBJECT lpInPlaceObject =
|
|
QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
|
|
if (lpInPlaceObject == NULL)
|
|
return FALSE; // perhaps server crashed?
|
|
|
|
// use OnGetPosRect if rectangle not specified
|
|
CRect rectPos;
|
|
if (lpPosRect == NULL)
|
|
{
|
|
ASSERT(lpClipRect == NULL);
|
|
OnGetItemPosition(rectPos);
|
|
lpPosRect = &rectPos;
|
|
}
|
|
|
|
// use OnGetClipRect if clipping rectangle not specified
|
|
CRect rectClip;
|
|
if (lpClipRect == NULL)
|
|
{
|
|
OnGetClipRect(rectClip);
|
|
lpClipRect = &rectClip;
|
|
}
|
|
ASSERT(lpPosRect != NULL);
|
|
ASSERT(lpClipRect != NULL);
|
|
|
|
// notify the server of the new item rectangles
|
|
m_scLast = lpInPlaceObject->SetObjectRects(lpPosRect, lpClipRect);
|
|
lpInPlaceObject->Release();
|
|
|
|
// remember position rectangle as cached position
|
|
return !FAILED(m_scLast);
|
|
}
|
|
|
|
BOOL COleClientItem::ReactivateAndUndo()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_lpObject != NULL);
|
|
ASSERT(IsInPlaceActive());
|
|
|
|
// get IOleInPlaceObject interface
|
|
LPOLEINPLACEOBJECT lpInPlaceObject =
|
|
QUERYINTERFACE(m_lpObject, IOleInPlaceObject);
|
|
if (lpInPlaceObject == NULL)
|
|
{
|
|
Close(); // handle rare failure cases by calling Close
|
|
return FALSE;
|
|
}
|
|
|
|
// call IOleInPlaceObject::ReactivateAndUndo
|
|
m_scLast = lpInPlaceObject->ReactivateAndUndo();
|
|
lpInPlaceObject->Release();
|
|
if (FAILED(m_scLast))
|
|
{
|
|
Close(); // handle rare failure cases by calling Close
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
CWnd* COleClientItem::GetInPlaceWindow()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_lpObject != NULL);
|
|
|
|
// only inplace active items should be asking for the window handle
|
|
if (GetItemState() != activeUIState)
|
|
return NULL;
|
|
|
|
// handle case of server that just disappears
|
|
if (m_hWndServer != NULL && !::IsWindow(m_hWndServer))
|
|
{
|
|
Close();
|
|
return NULL;
|
|
}
|
|
|
|
ASSERT(m_hWndServer == NULL || ::IsWindow(m_hWndServer));
|
|
return CWnd::FromHandle(m_hWndServer);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleFrameHook OLE interface implementation
|
|
|
|
BEGIN_INTERFACE_MAP(COleFrameHook, CCmdTarget)
|
|
INTERFACE_PART(COleFrameHook, IID_IOleWindow, OleInPlaceFrame)
|
|
INTERFACE_PART(COleFrameHook, IID_IOleInPlaceUIWindow, OleInPlaceFrame)
|
|
INTERFACE_PART(COleFrameHook, IID_IOleInPlaceFrame, OleInPlaceFrame)
|
|
END_INTERFACE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleFrameHook::XOleInPlaceFrame implementation
|
|
|
|
STDMETHODIMP_(ULONG) COleFrameHook::XOleInPlaceFrame::AddRef()
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
|
|
return pThis->ExternalAddRef();
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) COleFrameHook::XOleInPlaceFrame::Release()
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
|
|
return pThis->ExternalRelease();
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::QueryInterface(
|
|
REFIID iid, LPVOID* ppvObj)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
|
|
return pThis->ExternalQueryInterface(&iid, ppvObj);
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::GetWindow(
|
|
HWND* lphwnd)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
|
|
|
|
*lphwnd = pThis->m_hWnd;
|
|
return *lphwnd != NULL ? S_OK : E_FAIL;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::ContextSensitiveHelp(
|
|
BOOL fEnterMode)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
// document frame windows should not be put in help mode, so we get the
|
|
// top-level frame window and check it first
|
|
CFrameWnd* pFrameWnd = pThis->m_pFrameWnd->GetTopLevelFrame();
|
|
ASSERT_VALID(pFrameWnd);
|
|
|
|
if (fEnterMode)
|
|
{
|
|
if (!pFrameWnd->m_bHelpMode)
|
|
{
|
|
// check if help mode probable
|
|
if (!pFrameWnd->CanEnterHelpMode())
|
|
return E_UNEXPECTED;
|
|
|
|
// attempt to enter context help
|
|
if (!pThis->OnContextHelp(TRUE) ||
|
|
!pFrameWnd->PostMessage(WM_COMMAND, ID_CONTEXT_HELP))
|
|
{
|
|
return E_UNEXPECTED;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// just exit help mode
|
|
pFrameWnd->ExitHelpMode();
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::GetBorder(LPRECT lpRectBorder)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
COleClientItem* pItem = pThis->m_pActiveItem;
|
|
ASSERT_VALID(pItem);
|
|
CFrameWnd* pFrameWnd = pThis->m_pFrameWnd;
|
|
ASSERT_VALID(pFrameWnd);
|
|
|
|
// hide the control bars temporarily
|
|
BOOL bHidden = pItem->OnShowControlBars(pFrameWnd, FALSE);
|
|
|
|
// determine border space assuming that we'll remove our control bars
|
|
CRect rectSave = pFrameWnd->m_rectBorder;
|
|
#ifndef _MAC
|
|
pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderSet, NULL);
|
|
#else
|
|
if (pFrameWnd->GetActiveView()->GetParentFrame() != pFrameWnd)
|
|
{
|
|
// MDI only
|
|
pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderSet, NULL);
|
|
}
|
|
#endif
|
|
pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderGet, lpRectBorder);
|
|
pFrameWnd->NegotiateBorderSpace(CFrameWnd::borderSet, &rectSave);
|
|
|
|
// restore control bars
|
|
if (bHidden)
|
|
pItem->OnShowControlBars(pFrameWnd, TRUE);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::RequestBorderSpace(
|
|
LPCRECT lpRectWidths)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
CFrameWnd* pFrameWnd = pThis->m_pFrameWnd;
|
|
ASSERT_VALID(pFrameWnd);
|
|
|
|
if (!pFrameWnd->NegotiateBorderSpace(
|
|
CFrameWnd::borderRequest, (LPRECT)lpRectWidths))
|
|
{
|
|
return INPLACE_E_NOTOOLSPACE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::SetBorderSpace(
|
|
LPCRECT lpRectWidths)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
CFrameWnd* pFrameWnd = pThis->m_pFrameWnd;
|
|
|
|
if (pFrameWnd->NegotiateBorderSpace(
|
|
CFrameWnd::borderSet, (LPRECT)lpRectWidths))
|
|
{
|
|
pFrameWnd->DelayRecalcLayout(FALSE);
|
|
}
|
|
pThis->m_pActiveItem->OnShowControlBars(pFrameWnd, lpRectWidths == NULL);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::SetActiveObject(
|
|
LPOLEINPLACEACTIVEOBJECT lpActiveObject, LPCOLESTR lpszObjName)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
// release the old active object
|
|
RELEASE(pThis->m_lpActiveObject);
|
|
|
|
// set the new active object
|
|
pThis->m_lpActiveObject = lpActiveObject;
|
|
if (lpActiveObject != NULL)
|
|
lpActiveObject->AddRef();
|
|
|
|
// update caption if necessary
|
|
pThis->m_strObjName.Empty();
|
|
if (lpszObjName != NULL && lpActiveObject != NULL)
|
|
{
|
|
pThis->m_strObjName = lpszObjName;
|
|
pThis->m_pActiveItem->OnUpdateFrameTitle();
|
|
}
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::InsertMenus(
|
|
HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
// get the associated COleClientItem object
|
|
COleClientItem* pItem = pThis->m_pActiveItem;
|
|
ASSERT_VALID(pItem);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pItem->OnInsertMenus(CMenu::FromHandle(hmenuShared), lpMenuWidths);
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::SetMenu(
|
|
HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
// get the associated COleClientItem object
|
|
COleClientItem* pItem = pThis->m_pActiveItem;
|
|
ASSERT_VALID(pItem);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pItem->OnSetMenu(CMenu::FromHandle(hmenuShared), holemenu,
|
|
hwndActiveObject);
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::RemoveMenus(
|
|
HMENU hmenuShared)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
// get the associated COleClientItem object
|
|
COleClientItem* pItem = pThis->m_pActiveItem;
|
|
ASSERT_VALID(pItem);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pItem->OnRemoveMenus(CMenu::FromHandle(hmenuShared));
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::SetStatusText(
|
|
LPCOLESTR lpszStatusText)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleFrameHook, OleInPlaceFrame)
|
|
USES_CONVERSION;
|
|
|
|
pThis->m_pFrameWnd->SendMessage(WM_SETMESSAGESTRING, 0,
|
|
(LPARAM)OLE2CT(lpszStatusText));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::EnableModeless(BOOL fEnable)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
ASSERT_VALID(pThis->m_pFrameWnd);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
if (!fEnable)
|
|
pThis->m_pFrameWnd->BeginModalState();
|
|
else
|
|
pThis->m_pFrameWnd->EndModalState();
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleFrameHook::XOleInPlaceFrame::TranslateAccelerator(
|
|
LPMSG lpmsg, WORD /*wID*/)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleFrameHook, OleInPlaceFrame)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
// swap accel tables and call PreTranslateMessage
|
|
CFrameWnd* pFrameWnd = pThis->m_pFrameWnd;
|
|
HACCEL hAccelSave = pFrameWnd->m_hAccelTable;
|
|
pFrameWnd->m_hAccelTable = pThis->m_hAccelTable;
|
|
ASSERT(lpmsg != NULL);
|
|
MSG msg = *lpmsg;
|
|
sc = pFrameWnd->PreTranslateMessage(&msg) ? S_OK : S_FALSE;
|
|
*lpmsg = msg;
|
|
pFrameWnd->m_hAccelTable = hAccelSave;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COleClientItem::XOleIPSite implementation
|
|
|
|
STDMETHODIMP_(ULONG) COleClientItem::XOleIPSite::AddRef()
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
|
|
return pThis->ExternalAddRef();
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) COleClientItem::XOleIPSite::Release()
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
|
|
return pThis->ExternalRelease();
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::QueryInterface(
|
|
REFIID iid, LPVOID* ppvObj)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
|
|
return pThis->ExternalQueryInterface(&iid, ppvObj);
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::GetWindow(HWND* lphwnd)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
|
|
|
|
*lphwnd = pThis->m_pView->GetSafeHwnd();
|
|
return *lphwnd != NULL ? S_OK : E_FAIL;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::ContextSensitiveHelp(
|
|
BOOL fEnterMode)
|
|
{
|
|
METHOD_PROLOGUE_EX_(COleClientItem, OleIPSite)
|
|
|
|
if (pThis->m_pInPlaceFrame == NULL)
|
|
return E_UNEXPECTED;
|
|
|
|
// simply delegate to frame window implementation
|
|
return pThis->m_pInPlaceFrame->
|
|
m_xOleInPlaceFrame.ContextSensitiveHelp(fEnterMode);
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::CanInPlaceActivate()
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
|
|
return pThis->CanActivate() ? S_OK : S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::OnInPlaceActivate()
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pThis->OnActivate();
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::OnUIActivate()
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pThis->OnActivateUI();
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::GetWindowContext(
|
|
LPOLEINPLACEFRAME* lplpFrame,
|
|
LPOLEINPLACEUIWINDOW* lplpDoc,
|
|
LPRECT lpPosRect, LPRECT lpClipRect,
|
|
LPOLEINPLACEFRAMEINFO lpFrameInfo)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
*lplpFrame = NULL; // init these in-case of mem-alloc failure
|
|
*lplpDoc = NULL;
|
|
|
|
CFrameWnd* pMainFrame = NULL;
|
|
CFrameWnd* pDocFrame = NULL;
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
// get position of the item relative to activation view
|
|
CRect rect;
|
|
pThis->OnGetItemPosition(rect);
|
|
::CopyRect(lpPosRect, &rect);
|
|
pThis->OnGetClipRect(rect);
|
|
::CopyRect(lpClipRect, &rect);
|
|
|
|
// get the window context information
|
|
if (pThis->OnGetWindowContext(&pMainFrame, &pDocFrame, lpFrameInfo))
|
|
{
|
|
// hook IOleInPlaceFrame interface to pMainFrame
|
|
if (pThis->m_pInPlaceFrame == NULL)
|
|
pThis->m_pInPlaceFrame = new COleFrameHook(pMainFrame, pThis);
|
|
pThis->m_pInPlaceFrame->InternalAddRef();
|
|
*lplpFrame = (LPOLEINPLACEFRAME)pThis->m_pInPlaceFrame->
|
|
GetInterface(&IID_IOleInPlaceFrame);
|
|
|
|
// save accel table for IOleInPlaceFrame::TranslateAccelerators
|
|
pThis->m_pInPlaceFrame->m_hAccelTable = lpFrameInfo->haccel;
|
|
|
|
// hook IOleInPlaceUIWindow to pDocFrame
|
|
if (pDocFrame != NULL)
|
|
{
|
|
if (pThis->m_pInPlaceDoc == NULL)
|
|
pThis->m_pInPlaceDoc = new COleFrameHook(pDocFrame, pThis);
|
|
pThis->m_pInPlaceDoc->InternalAddRef();
|
|
*lplpDoc = (LPOLEINPLACEUIWINDOW)pThis->m_pInPlaceDoc->
|
|
GetInterface(&IID_IOleInPlaceUIWindow);
|
|
}
|
|
sc = S_OK;
|
|
}
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// cleanup memory that may be partially allocated
|
|
delete *lplpFrame;
|
|
ASSERT(*lplpDoc == NULL);
|
|
DELETE_EXCEPTION(e);
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::Scroll(SIZE scrollExtent)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
if (!pThis->OnScrollBy(CSize(scrollExtent)))
|
|
sc = S_FALSE;
|
|
else
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::OnUIDeactivate(BOOL fUndoable)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pThis->OnDeactivateUI(fUndoable);
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::OnInPlaceDeactivate()
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pThis->OnDeactivate();
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::DiscardUndoState()
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pThis->OnDiscardUndoState();
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::DeactivateAndUndo()
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
pThis->OnDeactivateAndUndo();
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
STDMETHODIMP COleClientItem::XOleIPSite::OnPosRectChange(
|
|
LPCRECT lpPosRect)
|
|
{
|
|
METHOD_PROLOGUE_EX(COleClientItem, OleIPSite)
|
|
ASSERT_VALID(pThis);
|
|
|
|
SCODE sc = E_UNEXPECTED;
|
|
TRY
|
|
{
|
|
CRect rect;
|
|
rect.CopyRect(lpPosRect);
|
|
pThis->OnChangeItemPosition(rect);
|
|
sc = S_OK;
|
|
}
|
|
END_TRY
|
|
|
|
return sc;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|