📄 olecli2.cpp
字号:
}
}
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);
// 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);
}
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->GetSafeHmenu(), 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());
// 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);
}
}
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->GetSafeHmenu(), 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;
}
if (m_nItemState == activeUIState)
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)
#ifndef _AFXDLL
INTERFACE_PART(COleFrameHook, IID_IOleCommandTarget, OleCommandTarget)
#endif
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COleFrameHook::XOleCommandTarget implementation
#ifdef _AFXDLL
LPUNKNOWN COleFrameHook::GetInterfaceHook(const void* pIID)
{
ASSERT(m_pModuleState != NULL);
if (m_pModuleState->m_dwVersion >= 0x423 &&
*(IID*)pIID == IID_IOleCommandTarget)
{
return &m_xOleCommandTarget;
}
return NULL;
}
#endif
STDMETHODIMP_(ULONG) COleFrameHook::XOleCommandTarget::AddRef()
{
METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
return pThis->ExternalAddRef();
}
STDMETHODIMP_(ULONG) COleFrameHook::XOleCommandTarget::Release()
{
METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
return pThis->ExternalRelease();
}
STDMETHODIMP COleFrameHook::XOleCommandTarget::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
return pThis->ExternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP COleFrameHook::XOleCommandTarget::Exec(
const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
{
HRESULT hResult = OLECMDERR_E_UNKNOWNGROUP;
METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
COleDocObjectItem* pActiveDocObjectItem =
DYNAMIC_DOWNCAST(COleDocObjectItem, pThis->m_pActiveItem);
if (pActiveDocObjectItem != NULL)
{
hResult = _AfxExecOleCommandHelper(pActiveDocObjectItem,
pguidCmdGroup, nCmdID, nCmdExecOpt, pvarargIn, pvarargOut);
}
return hResult;
}
STDMETHODIMP COleFrameHook::XOleCommandTarget::QueryStatus(
const GUID* pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[],
OLECMDTEXT* pcmdtext)
{
HRESULT hResult = OLECMDERR_E_UNKNOWNGROUP;
METHOD_PROLOGUE_EX_(COleFrameHook, OleCommandTarget)
COleDocObjectItem* pActiveDocObjectItem =
DYNAMIC_DOWNCAST(COleDocObjectItem, pThis->m_pActiveItem);
if (pActiveDocObjectItem != NULL)
{
hResult = _AfxQueryStatusOleCommandHelper(pActiveDocObjectItem,
pguidCmdGroup, cCmds, rgCmds, pcmdtext);
}
return hResult;
}
/////////////////////////////////////////////////////////////////////////////
// COleFrameHook::XOleInPlaceFrame implementation
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -