|
|
/*************************************************************************
** ** OLE 2 Server Sample Code ** ** svrinpl.c ** ** This file contains all interfaces, methods and related support ** functions for an In-Place Object (Server) application (aka. Visual ** Editing). The in-place Object application includes the following ** implementation objects: ** ** ServerDoc Object ** exposed interfaces: ** IOleInPlaceObject ** IOleInPlaceActiveObject ** ** ServerApp Object ** exposed interfaces: ** IUnknown ** ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved ** *************************************************************************/
#include "outline.h"
OLEDBGDATA
extern LPOUTLINEAPP g_lpApp;
/* OLE2NOTE: the object should compose a string that is used by
** in-place containers to be used for the window titles. this string ** is passed to the container application via ** IOleInPlaceUIWindow::SetActiveObject. the string should have the ** following form: ** <application name> - <object short type name> ** SDI containers can use the string directly to display in the ** frame window title. the container would concatenate the string ** " in <container doc name>". ** an MDI container with the MDI child window maximized can do the ** same as the SDI container. an MDI container with the MDI child ** windows NOT maximized can look for the " - " in the string from ** the object. the first part of the string (app name) would be put ** as the frame window title; the second part would be composed with ** " in <container doc name>" and used as the MDI child window ** title. */
// REVIEW: should use string resource for messages
char g_szIPObjectTitle[] = APPNAME " - " SHORTUSERTYPENAME;
extern RECT g_rectNull;
/*************************************************************************
** ServerDoc::IOleInPlaceObject interface implementation *************************************************************************/
// IOleInPlaceObject::QueryInterface method
STDMETHODIMP SvrDoc_IPObj_QueryInterface( LPOLEINPLACEOBJECT lpThis, REFIID riid, LPVOID FAR * lplpvObj ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
return OleDoc_QueryInterface((LPOLEDOC)lpServerDoc, riid, lplpvObj); }
// IOleInPlaceObject::AddRef method
STDMETHODIMP_(ULONG) SvrDoc_IPObj_AddRef(LPOLEINPLACEOBJECT lpThis) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
OleDbgAddRefMethod(lpThis, "IOleInPlaceObject");
return OleDoc_AddRef((LPOLEDOC)lpServerDoc); }
// IOleInPlaceObject::Release method
STDMETHODIMP_(ULONG) SvrDoc_IPObj_Release(LPOLEINPLACEOBJECT lpThis) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
OleDbgReleaseMethod(lpThis, "IOleInPlaceObject");
return OleDoc_Release((LPOLEDOC)lpServerDoc); }
// IOleInPlaceObject::GetWindow method
STDMETHODIMP SvrDoc_IPObj_GetWindow( LPOLEINPLACEOBJECT lpThis, HWND FAR* lphwnd ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
OLEDBG_BEGIN2("SvrDoc_IPObj_GetWindow\r\n")
*lphwnd = ((LPOUTLINEDOC)lpServerDoc)->m_hWndDoc;
OLEDBG_END2 return S_OK; }
// IOleInPlaceObject::ContextSensitiveHelp method
STDMETHODIMP SvrDoc_IPObj_ContextSensitiveHelp( LPOLEINPLACEOBJECT lpThis, BOOL fEnable ) { LPOLEDOC lpOleDoc = (LPOLEDOC)((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; OleDbgOut2("SvrDoc_IPObj_ContextSensitiveHelp\r\n");
/* OLE2NOTE: see context sensitive help technote (CSHELP.DOC).
** This method is called when SHIFT-F1 context sensitive help is ** entered. the cursor should then change to a question mark ** cursor and the app should enter a modal state where the next ** mouse click does not perform its normal action but rather ** gives help corresponding to the location clicked. if the app ** does not implement a help system, it should at least eat the ** click and do nothing. */ lpOleDoc->m_fCSHelpMode = fEnable;
return S_OK; }
// IOleInPlaceObject::InPlaceDeactivate method
STDMETHODIMP SvrDoc_IPObj_InPlaceDeactivate(LPOLEINPLACEOBJECT lpThis) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; HRESULT hrErr;
OLEDBG_BEGIN2("SvrDoc_IPObj_InPlaceDeactivate\r\n")
hrErr = ServerDoc_DoInPlaceDeactivate(lpServerDoc);
OLEDBG_END2 return hrErr; }
// IOleInPlaceObject::UIDeactivate method
STDMETHODIMP SvrDoc_IPObj_UIDeactivate(LPOLEINPLACEOBJECT lpThis) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; LPLINELIST lpLL = (LPLINELIST)&((LPOUTLINEDOC)lpServerDoc)->m_LineList; HWND hWndApp = OutlineApp_GetWindow(g_lpApp);
OLEDBG_BEGIN2("SvrDoc_IPObj_UIDeactivate\r\n");
if (!lpServerDoc->m_fUIActive) { OLEDBG_END2 return NOERROR; }
lpServerDoc->m_fUIActive = FALSE;
// Clip the hatch window to the size of pos rect so, that the object
// adornments and hatch border will not be visible.
ServerDoc_ResizeInPlaceWindow(lpServerDoc, (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect), (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect) );
if (lpIPData->lpDoc) lpIPData->lpDoc->lpVtbl->SetActiveObject(lpIPData->lpDoc, NULL, NULL);
if (lpIPData->lpFrame) { lpIPData->lpFrame->lpVtbl->SetActiveObject( lpIPData->lpFrame, NULL, NULL ); }
#if defined( USE_FRAMETOOLS )
/* OLE2NOTE: we must hide our frame tools here but NOT call
** IOleInPlaceFrame::SetBorderSpace(NULL) or SetMenu(NULL). ** we must hide our tools BEFORE calling ** IOleInPlaceSite::OnUIDeactivate. the container will put ** his menus and tools back when OnUIDeactivate is called. */ ServerDoc_RemoveFrameLevelTools(lpServerDoc); #endif
OLEDBG_BEGIN2("IOleInPlaceSite::OnUIDeactivate called\r\n"); lpIPData->lpSite->lpVtbl->OnUIDeactivate(lpIPData->lpSite, FALSE); OLEDBG_END2
/* Reset to use our normal app's accelerator table */ g_lpApp->m_hAccelApp = lpServerApp->m_hAccelBaseApp; g_lpApp->m_hAccel = lpServerApp->m_hAccelBaseApp; g_lpApp->m_hWndAccelTarget = hWndApp;
OLEDBG_END2
#if !defined( SVR_INSIDEOUT )
/* OLE2NOTE: an "outside-in" style in-place server would hide its
** window here. an "inside-out" style server leaves its window ** visible when it is UIDeactivated. it would only hide its ** window when InPlaceDeactivated. this app is an "inside-out" ** style server. it is recommended for most server to support ** inside-out behavior if possible. */ ServerDoc_DoInPlaceHide(lpServerDoc); #endif // INSIEDOUT
return NOERROR; }
// IOleInPlaceObject::SetObjectRects method
STDMETHODIMP SvrDoc_IPObj_SetObjectRects( LPOLEINPLACEOBJECT lpThis, LPCRECT lprcPosRect, LPCRECT lprcClipRect ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; LPLINELIST lpLL = OutlineDoc_GetLineList((LPOUTLINEDOC)lpServerDoc); OLEDBG_BEGIN2("SvrDoc_IPObj_SetObjectRects\r\n")
#if defined( _DEBUG )
OleDbgOutRect3("SvrDoc_IPObj_SetObjectRects (PosRect)", (LPRECT)lprcPosRect); OleDbgOutRect3("SvrDoc_IPObj_SetObjectRects (ClipRect)", (LPRECT)lprcClipRect); #endif
// save the current PosRect and ClipRect
lpIPData->rcPosRect = *lprcPosRect; lpIPData->rcClipRect = *lprcClipRect;
if (! lpServerDoc->m_fUIActive) // hatch and adornaments must not be drawn
lprcClipRect = lprcPosRect;
ServerDoc_ResizeInPlaceWindow( lpServerDoc, (LPRECT)lprcPosRect, (LPRECT)lprcClipRect);
OLEDBG_END2 return NOERROR; }
// IOleInPlaceObject::ReactivateAndUndo method
STDMETHODIMP SvrDoc_IPObj_ReactivateAndUndo(LPOLEINPLACEOBJECT lpThis) { OLEDBG_BEGIN2("SvrDoc_IPObj_ReactivateAndUndo\r\n")
// We do not support support UNDO.
/* REVIEW: for debugging purposes it would be useful to give a
** message box indicating that this method has been called. */
OLEDBG_END2 return NOERROR; }
/*************************************************************************
** ServerDoc::IOleInPlaceActiveObject interface implementation *************************************************************************/
// IOleInPlaceActiveObject::QueryInterface method
STDMETHODIMP SvrDoc_IPActiveObj_QueryInterface( LPOLEINPLACEACTIVEOBJECT lpThis, REFIID riid, LPVOID FAR * lplpvObj ) { SCODE sc = E_NOINTERFACE; LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
/* The container should not be able to access the other interfaces
** of our object by doing QI on this interface. */
*lplpvObj = NULL; if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleWindow) || IsEqualIID(riid, &IID_IOleInPlaceActiveObject)) { OleDbgOut4("OleDoc_QueryInterface: IOleInPlaceActiveObject* RETURNED\r\n");
*lplpvObj = lpThis; OleDoc_AddRef((LPOLEDOC)lpServerDoc); sc = NOERROR; }
OleDbgQueryInterfaceMethod(*lplpvObj);
return ResultFromScode(sc); }
// IOleInPlaceActiveObject::AddRef method
STDMETHODIMP_(ULONG) SvrDoc_IPActiveObj_AddRef( LPOLEINPLACEACTIVEOBJECT lpThis ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
OleDbgAddRefMethod(lpThis, "IOleInPlaceActiveObject");
return OleDoc_AddRef((LPOLEDOC)lpServerDoc); }
// IOleInPlaceActiveObject::Release method
STDMETHODIMP_(ULONG) SvrDoc_IPActiveObj_Release( LPOLEINPLACEACTIVEOBJECT lpThis ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
OleDbgReleaseMethod(lpThis, "IOleInPlaceActiveObject");
return OleDoc_Release((LPOLEDOC)lpServerDoc); }
// IOleInPlaceActiveObject::GetWindow method
STDMETHODIMP SvrDoc_IPActiveObj_GetWindow( LPOLEINPLACEACTIVEOBJECT lpThis, HWND FAR* lphwnd ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc;
OLEDBG_BEGIN2("SvrDoc_IPActiveObj_GetWindow\r\n")
*lphwnd = ((LPOUTLINEDOC)lpServerDoc)->m_hWndDoc;
OLEDBG_END2 return NOERROR; }
// IOleInPlaceActiveObject::ContextSensitiveHelp method
STDMETHODIMP SvrDoc_IPActiveObj_ContextSensitiveHelp( LPOLEINPLACEACTIVEOBJECT lpThis, BOOL fEnterMode ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; OleDbgOut2("SvrDoc_IPActiveObj_ContextSensitiveHelp\r\n");
/* OLE2NOTE: see context sensitive help technote (CSHELP.DOC)
** This method is called when F1 is pressed when a menu item is ** selected. this tells the in-place server application to give ** help rather than execute the next menu command. at a minimum, ** even if the in-place server application does not implement a ** help system, it should NOT execute the next command when ** fEnable==TRUE. We set the active object's m_fMenuMode flag here. ** later, in WM_COMMAND processing in the DocWndProc, if this ** flag is set then the command is NOT executed (and help could ** be given if we had a help system....but we don't.) */ lpServerDoc->m_fMenuHelpMode = fEnterMode;
#if !defined( HACK )
((LPOLEDOC)lpServerDoc)->m_fCSHelpMode = fEnterMode; #endif
return NOERROR; }
// IOleInPlaceActiveObject::TranslateAccelerator method
STDMETHODIMP SvrDoc_IPActiveObj_TranslateAccelerator( LPOLEINPLACEACTIVEOBJECT lpThis, LPMSG lpmsg ) { // This will never be called because this server is implemented as an EXE
return NOERROR; }
// IOleInPlaceActiveObject::OnFrameWindowActivate method
STDMETHODIMP SvrDoc_IPActiveObj_OnFrameWindowActivate( LPOLEINPLACEACTIVEOBJECT lpThis, BOOL fActivate ) { LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC) ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; HWND hWndDoc = OutlineDoc_GetWindow(lpOutlineDoc); #if defined( _DEBUG )
if (fActivate) OleDbgOut2("SvrDoc_IPActiveObj_OnFrameWindowActivate(TRUE)\r\n"); else OleDbgOut2("SvrDoc_IPActiveObj_OnFrameWindowActivate(FALSE)\r\n"); #endif // _DEBUG
/* OLE2NOTE: this is a notification of the container application's
** WM_ACTIVATEAPP status. some applications may find this ** important. we need to update the enable/disable status of our ** tool bar buttons. */
// OLE2NOTE: We can't call OutlineDoc_UpdateFrameToolButtons
// right away which
// would generate some OLE calls and eventually
// WM_ACTIVATEAPP and a loop was formed. Therefore, we
// should delay the frame tool initialization until
// WM_ACTIVATEAPP is finished by posting a message
// to ourselves.
/* Update enable/disable state of buttons in toolbar */ if (fActivate) PostMessage(hWndDoc, WM_U_INITFRAMETOOLS, 0, 0L);
return NOERROR; }
// IOleInPlaceActiveObject::OnDocWindowActivate method
STDMETHODIMP SvrDoc_IPActiveObj_OnDocWindowActivate( LPOLEINPLACEACTIVEOBJECT lpThis, BOOL fActivate ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; #if defined( _DEBUG )
if (fActivate) OleDbgOut2("SvrDoc_IPActiveObj_OnDocWindowActivate(TRUE)\r\n"); else OleDbgOut2("SvrDoc_IPActiveObj_OnDocWindowActivate(FALSE)\r\n"); #endif
if (fActivate) { ServerDoc_AddFrameLevelUI(lpServerDoc); } else { #if defined( USE_FRAMETOOLS )
/* OLE2NOTE: we must NOT call IOleInPlaceFrame::SetBorderSpace(NULL)
** or SetMenu(NULL) here. we should simply hide our tools. */ ServerDoc_RemoveFrameLevelTools(lpServerDoc); #endif
}
OLEDBG_END2 return NOERROR; }
// IOleInPlaceActiveObject::ResizeBorder method
STDMETHODIMP SvrDoc_IPActiveObj_ResizeBorder( LPOLEINPLACEACTIVEOBJECT lpThis, LPCRECT lprectBorder, LPOLEINPLACEUIWINDOW lpIPUiWnd, BOOL fFrameWindow ) { LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
OLEDBG_BEGIN2("SvrDoc_IPActiveObj_ResizeBorder\r\n")
#if defined( USE_FRAMETOOLS )
if (fFrameWindow) { FrameTools_NegotiateForSpaceAndShow( lpOutlineDoc->m_lpFrameTools, (LPRECT)lprectBorder, (LPOLEINPLACEFRAME)lpIPUiWnd ); }
#endif
OLEDBG_END2 return NOERROR; }
// IOleInPlaceActiveObject::EnableModeless method
STDMETHODIMP SvrDoc_IPActiveObj_EnableModeless( LPOLEINPLACEACTIVEOBJECT lpThis, BOOL fEnable ) { #if defined( USE_FRAMETOOLS )
LPSERVERDOC lpServerDoc = ((struct CDocOleObjectImpl FAR*)lpThis)->lpServerDoc; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; LPFRAMETOOLS lptb;
/* OLE2NOTE: we must enable/disable mouse and keyboard input to our
** floating tool palette */ if (lpOutlineDoc) { lptb = lpOutlineDoc->m_lpFrameTools; if (lptb) FrameTools_EnableWindow(lptb, fEnable); } #endif // USE_FRAMETOOLS
#if defined( _DEBUG )
if (fEnable) OleDbgOut2("SvrDoc_IPActiveObj_EnableModeless(TRUE)\r\n"); else OleDbgOut2("SvrDoc_IPActiveObj_EnableModeless(FALSE)\r\n"); #endif // _DEBUG
/* OLE2NOTE: this method is called when the top-level, in-place
** container puts up a modal dialog. it tells the UIActive ** object to disable it modeless dialogs for the duration that ** the container is displaying a modal dialog. ** ** ISVROTL does not use any modeless dialogs, thus we can ** ignore this method. */ return NOERROR; }
/*************************************************************************
** Support Functions *************************************************************************/
HRESULT ServerDoc_DoInPlaceActivate( LPSERVERDOC lpServerDoc, LONG lVerb, LPMSG lpmsg, LPOLECLIENTSITE lpActiveSite ) { LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp; LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp; SCODE sc = E_FAIL; RECT rcPos; RECT rcClip; LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; LPOUTLINEDOC lpOutlineDoc=(LPOUTLINEDOC)lpServerDoc; HWND hWndDoc = lpOutlineDoc->m_hWndDoc; HWND hWndHatch = lpServerDoc->m_hWndHatch; HRESULT hrErr; LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList; LPOLEINPLACESITE lpIPSite = NULL;
/* OLE2NOTE: lpActiveSite should be used only for InPlace PLAYing.
** This app does not do inplace PLAYing, so it never uses ** lpActiveSite. */
/* InPlace activation can only be done if the ClientSite is non-NULL. */ if (! lpServerDoc->m_lpOleClientSite) return NOERROR;
if (! lpServerDoc->m_fInPlaceActive) {
// if the object is in open mode then we do not want to do inplace
// activation.
if (IsWindowVisible(lpOutlineDoc->m_hWndDoc)) return NOERROR;
lpIPSite = (LPOLEINPLACESITE)OleStdQueryInterface( (LPUNKNOWN)lpServerDoc->m_lpOleClientSite, &IID_IOleInPlaceSite );
if (! lpIPSite) goto errActivate;
OLEDBG_BEGIN2("IOleInPlaceSite::CanInPlaceActivate called\r\n"); hrErr = lpIPSite->lpVtbl->CanInPlaceActivate(lpIPSite); OLEDBG_END2 if (hrErr != NOERROR) goto errActivate;
lpServerDoc->m_fInPlaceActive = TRUE; OLEDBG_BEGIN2("IOleInPlaceSite::OnInPlaceActivate called\r\n"); hrErr = lpIPSite->lpVtbl->OnInPlaceActivate(lpIPSite); OLEDBG_END2 if (hrErr != NOERROR) goto errActivate;
if (! ServerDoc_AllocInPlaceData(lpServerDoc)) { sc = E_OUTOFMEMORY; OLEDBG_BEGIN2("IOleInPlaceSite::OnInPlaceDeactivate called\r\n"); lpIPSite->lpVtbl->OnInPlaceDeactivate(lpIPSite); OLEDBG_END2 goto errActivate; }
(lpIPData = lpServerDoc->m_lpIPData)->lpSite = lpIPSite; goto InPlaceActive;
errActivate: lpServerDoc->m_fInPlaceActive = FALSE; if (lpIPSite) OleStdRelease((LPUNKNOWN)lpIPSite); return ResultFromScode(sc); }
InPlaceActive:
if (! lpServerDoc->m_fInPlaceVisible) { lpServerDoc->m_fInPlaceVisible = TRUE;
OLEDBG_BEGIN2("IOleInPlaceSite::GetWindow called\r\n"); hrErr = lpIPData->lpSite->lpVtbl->GetWindow( lpIPData->lpSite, &lpServerDoc->m_hWndParent); OLEDBG_END2 if (hrErr != NOERROR) { sc = GetScode(hrErr); goto errRtn; }
if (! lpServerDoc->m_hWndParent) goto errRtn;
/* OLE2NOTE: The server should fill in the "cb" field so that the
** container can tell what size structure the server is ** expecting. this enables this structure to be easily extended ** in future releases of OLE. the container should check this ** field so that it doesn't try to use fields that do not exist ** since the server may be using an old structure definition. */ _fmemset( (LPOLEINPLACEFRAMEINFO)&lpIPData->frameInfo, 0, sizeof(OLEINPLACEFRAMEINFO) ); lpIPData->frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
OLEDBG_BEGIN2("IOleInPlaceSite::GetWindowContext called\r\n"); hrErr = lpIPData->lpSite->lpVtbl->GetWindowContext(lpIPData->lpSite, (LPOLEINPLACEFRAME FAR*) &lpIPData->lpFrame, (LPOLEINPLACEUIWINDOW FAR*)&lpIPData->lpDoc, (LPRECT)&rcPos, (LPRECT)&rcClip, (LPOLEINPLACEFRAMEINFO)&lpIPData->frameInfo); OLEDBG_END2
if (hrErr != NOERROR) { sc = GetScode(hrErr); goto errRtn; }
lpServerApp->m_lpIPData = lpIPData; ShowWindow(hWndDoc, SW_HIDE); // make sure we are hidden
/* OLE2NOTE: reparent in-place server document's window to the
** special in-place hatch border window. set the in-place site's ** window as the parent of the hatch window. position the ** in-place and hatch border windows using the PosRect and ** ClipRect. ** it is important to properly parent and position the in-place ** server window BEFORE calling IOleInPlaceFrame::SetMenu and ** SetBorderSpace. */ ShowWindow(lpServerDoc->m_hWndHatch, SW_SHOW); // make sure App busy/blocked dialogs are parented to our
// new hWndFrame
OleStdMsgFilter_SetParentWindow( lpOleApp->m_lpMsgFilter,lpIPData->frameInfo.hwndFrame); SetParent(lpServerDoc->m_hWndHatch, lpServerDoc->m_hWndParent); SetParent(hWndDoc, lpServerDoc->m_hWndHatch);
#if defined( _DEBUG )
OleDbgOutRect3("IOleInPlaceSite::GetWindowContext (PosRect)", (LPRECT)&rcPos); OleDbgOutRect3("IOleInPlaceSite::GetWindowContext (ClipRect)", (LPRECT)&rcClip); #endif
// save the current PosRect and ClipRect
lpIPData->rcPosRect = rcPos; lpIPData->rcClipRect = rcClip;
/* OLE2NOTE: build the shared menu for the in-place container and
** the server. */ if (ServerDoc_AssembleMenus (lpServerDoc) != NOERROR) goto errRtn;
#if defined( SVR_INSIDEOUT )
if (lVerb == OLEIVERB_INPLACEACTIVATE) { // Clip the hatch window to the size of pos rect so, that
// hatch and object adornments will not be visible.
ServerDoc_ResizeInPlaceWindow(lpServerDoc, (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect), (LPRECT)&(lpServerDoc->m_lpIPData->rcPosRect) ); } #endif // SVR_INSIDEOUT
}
#if defined( SVR_INSIDEOUT )
// OLE2NOTE: if verb is OLEIVERB_INPLACEACTIVATE we do NOT want to
// show our UI
if (lVerb == OLEIVERB_INPLACEACTIVATE) { return NOERROR; } #endif // SVR_INSIDEOUT
if (! lpServerDoc->m_fUIActive) { lpServerDoc->m_fUIActive = TRUE; OLEDBG_BEGIN2("IOleInPlaceSite::OnUIActivate called\r\n"); hrErr = lpIPData->lpSite->lpVtbl->OnUIActivate(lpIPData->lpSite); OLEDBG_END2 if (hrErr != NOERROR) { lpServerDoc->m_fUIActive = FALSE; goto errRtn; }
SetFocus(hWndDoc);
// Show the object adornments and hacth border around them.
ServerDoc_ResizeInPlaceWindow(lpServerDoc, (LPRECT)&lpIPData->rcPosRect, (LPRECT)&lpIPData->rcClipRect );
/* OLE2NOTE: IOleInPlaceFrame::SetActiveObject must be called BEFORE
** IOleInPlaceFrame::SetMenu. */ OLEDBG_BEGIN2("IOleInPlaceSite::SetActiveObject called\r\n"); CallIOleInPlaceUIWindowSetActiveObjectA( (struct IOleInPlaceUIWindow *) lpIPData->lpFrame, (LPOLEINPLACEACTIVEOBJECT) &lpServerDoc->m_OleInPlaceActiveObject, (LPSTR)g_szIPObjectTitle ); OLEDBG_END2
/* OLE2NOTE: If the container wants to give ownership of the
** palette then he would sendmessage WM_QUEYNEWPALETTE to ** the object window proc, before returning from ** IOleInPlaceFrame::SetActiveObject. Those objects which ** want to be edited inplace only if they have the ownership of ** the palette, can check at this point in the code whether ** they got WM_QUERYNEWPALETTE or not. If they didn't get ** the message, then they can inplace deactivate and do open ** editing instead. */
if (lpIPData->lpDoc) { CallIOleInPlaceUIWindowSetActiveObjectA( lpIPData->lpDoc, (LPOLEINPLACEACTIVEOBJECT)&lpServerDoc->m_OleInPlaceActiveObject, (LPSTR)g_szIPObjectTitle ); }
/* OLE2NOTE: install the menu and frame-level tools on the in-place
** frame. */ ServerDoc_AddFrameLevelUI(lpServerDoc); }
return NOERROR;
errRtn: ServerDoc_DoInPlaceDeactivate(lpServerDoc); return ResultFromScode(sc); }
HRESULT ServerDoc_DoInPlaceDeactivate(LPSERVERDOC lpServerDoc) { LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc;
if (!lpServerDoc->m_fInPlaceActive) return S_OK;
lpServerDoc->m_fInPlaceActive = FALSE;
SvrDoc_IPObj_UIDeactivate( (LPOLEINPLACEOBJECT)&lpServerDoc->m_OleInPlaceObject);
/* OLE2NOTE: an inside-out style in-place server will
** NOT hide its window in UIDeactive (an outside-in ** style object will hide its window in UIDeactivate). ** thus, an inside-out server must explicitly hide ** its window in InPlaceDeactivate. it is ALSO important for an ** outside-in style object to call ServerDoc_DoInPlaceHide here ** BEFORE freeing the InPlaceData structure. it will be common ** for in-place containers to call IOleInPlaceObject:: ** InPlaceDeactivate in their IOleInPlaceSite::OnUIDeactiate ** implementation. */ ServerDoc_DoInPlaceHide(lpServerDoc);
OLEDBG_BEGIN2("IOleInPlaceSite::OnInPlaceDeactivate called\r\n"); lpIPData->lpSite->lpVtbl->OnInPlaceDeactivate(lpIPData->lpSite); OLEDBG_END2
OleStdRelease((LPUNKNOWN)lpIPData->lpSite); lpIPData->lpSite = NULL;
ServerDoc_FreeInPlaceData(lpServerDoc);
return NOERROR; }
HRESULT ServerDoc_DoInPlaceHide(LPSERVERDOC lpServerDoc) { LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; LPOLEAPP lpOleApp = (LPOLEAPP)g_lpApp; HWND hWndApp = OutlineApp_GetWindow(g_lpApp);
if (! lpServerDoc->m_fInPlaceVisible) return NOERROR;
// Set the parent back to server app's window
OleDoc_HideWindow((LPOLEDOC)lpServerDoc, FALSE /* fShutdown */);
/* we need to enusure that our window is set to normal 100% zoom.
** if the window is next shown in open mode it should start out ** at normal zoom factor. our window may have been set to a ** different zoom factor while it was in-place active. */ OutlineDoc_SetCurrentZoomCommand(lpOutlineDoc,IDM_V_ZOOM_100);
lpServerDoc->m_fInPlaceVisible = FALSE;
lpServerDoc->m_hWndParent = hWndApp; SetParent( lpOutlineDoc->m_hWndDoc, lpServerDoc->m_hWndParent );
// make sure App busy/blocked dialogs are parented to our own hWndApp
OleStdMsgFilter_SetParentWindow(lpOleApp->m_lpMsgFilter, hWndApp);
// Hide the in-place hatch border window.
ShowWindow(lpServerDoc->m_hWndHatch, SW_HIDE);
ServerDoc_DisassembleMenus(lpServerDoc);
/* we no longer need the IOleInPlaceFrame* or the doc's
** IOleInPlaceWindow* interface pointers. */ if (lpIPData->lpDoc) { OleStdRelease((LPUNKNOWN)lpIPData->lpDoc); lpIPData->lpDoc = NULL; }
if (lpIPData->lpFrame) { OleStdRelease((LPUNKNOWN)lpIPData->lpFrame); lpIPData->lpFrame = NULL; }
((LPSERVERAPP)g_lpApp)->m_lpIPData = NULL;
return NOERROR; }
BOOL ServerDoc_AllocInPlaceData(LPSERVERDOC lpServerDoc) { LPINPLACEDATA lpIPData;
if (!(lpIPData = (LPINPLACEDATA) New(sizeof(INPLACEDATA)))) return FALSE;
lpIPData->lpFrame = NULL; lpIPData->lpDoc = NULL; lpIPData->lpSite = NULL; lpIPData->hOlemenu = NULL; lpIPData->hMenuShared = NULL;
lpServerDoc->m_lpIPData = lpIPData; return TRUE; }
void ServerDoc_FreeInPlaceData(LPSERVERDOC lpServerDoc) { Delete(lpServerDoc->m_lpIPData); lpServerDoc->m_lpIPData = NULL; }
HRESULT ServerDoc_AssembleMenus(LPSERVERDOC lpServerDoc) { HMENU hMenuShared; LONG FAR* lpWidths; UINT uPosition; UINT uPositionStart; LPSERVERAPP lpServerApp = (LPSERVERAPP) g_lpApp; LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; HRESULT hresult; BOOL fNoError = TRUE;
lpWidths = lpIPData->menuGroupWidths.width; hMenuShared = CreateMenu();
if (hMenuShared && (hresult = lpIPData->lpFrame->lpVtbl->InsertMenus( lpIPData->lpFrame, hMenuShared, &lpIPData->menuGroupWidths)) == NOERROR) {
/* Insert EDIT group menus */
uPosition = (UINT)lpWidths[0]; /* # of menus in the FILE group */ uPositionStart = uPosition;
fNoError &= InsertMenu( hMenuShared, (UINT)uPosition, (UINT)(MF_BYPOSITION | MF_POPUP), (UINT)lpServerApp->m_hMenuEdit, (LPCSTR)"&Edit" ); uPosition++;
lpWidths[1] = uPosition - uPositionStart;
/* Insert OBJECT group menus */
uPosition += (UINT)lpWidths[2]; uPositionStart = uPosition;
fNoError &= InsertMenu( hMenuShared, (UINT)uPosition, (UINT)(MF_BYPOSITION | MF_POPUP), (UINT)lpServerApp->m_hMenuLine, (LPCSTR)"&Line" ); uPosition++;
fNoError &= InsertMenu( hMenuShared, (UINT)uPosition, (UINT)(MF_BYPOSITION | MF_POPUP), (UINT)lpServerApp->m_hMenuName, (LPCSTR)"&Name" ); uPosition++;
fNoError &= InsertMenu( hMenuShared, (UINT)uPosition, (UINT)(MF_BYPOSITION | MF_POPUP), (UINT)lpServerApp->m_hMenuOptions, (LPCSTR)"&Options" ); uPosition++;
fNoError &= InsertMenu( hMenuShared, (UINT)uPosition, (UINT)(MF_BYPOSITION | MF_POPUP), (UINT)lpServerApp->m_hMenuDebug, (LPCSTR)"DbgI&Svr" ); uPosition++;
lpWidths[3] = uPosition - uPositionStart;
/* Insert HELP group menus */
uPosition += (UINT) lpWidths[4]; /* # of menus in WINDOW group */ uPositionStart = uPosition;
fNoError &= InsertMenu( hMenuShared, (UINT)uPosition, (UINT)(MF_BYPOSITION | MF_POPUP), (UINT)lpServerApp->m_hMenuHelp, (LPCSTR)"&Help" ); uPosition++;
lpWidths[5] = uPosition - uPositionStart;
OleDbgAssert(fNoError == TRUE);
} else { /* In-place container does not allow us to add menus to the
** frame. ** OLE2NOTE: even when the in-place container does NOT allow ** the building of a merged menu bar, it is CRITICAL that ** the in-place server still call OleCreateMenuDescriptor ** passing NULL for hMenuShared. */ if (hMenuShared) { DestroyMenu(hMenuShared); hMenuShared = NULL; } }
lpIPData->hMenuShared = hMenuShared;
if (!(lpIPData->hOlemenu = OleCreateMenuDescriptor(hMenuShared, &lpIPData->menuGroupWidths))) return ResultFromScode(E_OUTOFMEMORY);
return NOERROR; }
void ServerDoc_DisassembleMenus(LPSERVERDOC lpServerDoc) { UINT uCount; UINT uGroup; UINT uDeleteAt; LPINPLACEDATA lpIPData = lpServerDoc->m_lpIPData; LONG FAR* lpWidths = lpIPData->menuGroupWidths.width; BOOL fNoError = TRUE;
/* OLE2NOTE: even when hMenuShared is NULL (ie. the server has no
** Menu), there is still an hOleMenu created that must be destroyed. */ if (lpIPData->hOlemenu) { OleDestroyMenuDescriptor (lpIPData->hOlemenu); lpIPData->hOlemenu = NULL; }
if (! lpIPData->hMenuShared) return; // no menus to be destroyed
/* Remove server group menus. */ uDeleteAt = 0; for (uGroup = 0; uGroup < 6; uGroup++) { uDeleteAt += (UINT)lpWidths[uGroup++]; for (uCount = 0; uCount < (UINT)lpWidths[uGroup]; uCount++) fNoError &= RemoveMenu(lpIPData->hMenuShared, uDeleteAt, MF_BYPOSITION); }
/* Remove container group menus */ fNoError &= (lpIPData->lpFrame->lpVtbl->RemoveMenus( lpIPData->lpFrame, lpIPData->hMenuShared) == NOERROR);
OleDbgAssert(fNoError == TRUE);
DestroyMenu(lpIPData->hMenuShared); lpIPData->hMenuShared = NULL; }
/* ServerDoc_UpdateInPlaceWindowOnExtentChange
** ------------------------------------------- ** The size of the in-place window needs to be changed. ** calculate the size required in Client coordinates (taking into ** account the current scale factor imposed by the in-place ** container) and ask our in-place container to allow us to resize. ** our container must call us back via ** IOleInPlaceObject::SetObjectRects for the actual sizing to take ** place. ** ** OLE2NOTE: the rectangle that we ask for from our in-place ** container is always the rectangle required for the object display ** itself (in our case the size of the LineList contents). it does ** NOT include the space we require for object frame adornments. */ void ServerDoc_UpdateInPlaceWindowOnExtentChange(LPSERVERDOC lpServerDoc) { SIZEL sizelHim; SIZEL sizelPix; RECT rcPosRect; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; LPLINELIST lpLL=(LPLINELIST)&lpOutlineDoc->m_LineList; HWND hWndLL = lpLL->m_hWndListBox; LPSCALEFACTOR lpscale = (LPSCALEFACTOR)&lpOutlineDoc->m_scale;
if (!lpServerDoc->m_fInPlaceActive) return;
OleDoc_GetExtent((LPOLEDOC)lpServerDoc, (LPSIZEL)&sizelHim);
// apply current scale factor
sizelHim.cx = sizelHim.cx * lpscale->dwSxN / lpscale->dwSxD; sizelHim.cy = sizelHim.cy * lpscale->dwSxN / lpscale->dwSxD; XformSizeInHimetricToPixels(NULL, (LPSIZEL)&sizelHim, (LPSIZEL)&sizelPix);
GetWindowRect(hWndLL, (LPRECT)&rcPosRect); ScreenToClient(lpServerDoc->m_hWndParent, (POINT FAR *)&rcPosRect);
rcPosRect.right = rcPosRect.left + (int) sizelPix.cx; rcPosRect.bottom = rcPosRect.top + (int) sizelPix.cy; OleDbgOutRect3("ServerDoc_UpdateInPlaceWindowOnExtentChange: (PosRect)", (LPRECT)&rcPosRect);
OLEDBG_BEGIN2("IOleInPlaceSite::OnPosRectChange called\r\n"); lpServerDoc->m_lpIPData->lpSite->lpVtbl->OnPosRectChange( lpServerDoc->m_lpIPData->lpSite, (LPRECT) &rcPosRect ); OLEDBG_END2 }
/* ServerDoc_CalcInPlaceWindowPos
* ------------------------------ * * Move (and re-scale) the ServerDoc to the specified rectangle. * * Parameters: * lprcListBox - rect in client coordinate in which the listbox will fit * lprcDoc - corresponding size of the Doc in client coordinate * */ void ServerDoc_CalcInPlaceWindowPos( LPSERVERDOC lpServerDoc, LPRECT lprcListBox, LPRECT lprcDoc, LPSCALEFACTOR lpscale ) { SIZEL sizelHim; SIZEL sizelPix; LPLINELIST lpLL; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; LPHEADING lphead;
if (!lpServerDoc || !lprcListBox || !lprcDoc) return;
lphead = (LPHEADING)&lpOutlineDoc->m_heading;
lpLL = OutlineDoc_GetLineList(lpOutlineDoc); OleDoc_GetExtent((LPOLEDOC)lpServerDoc, (LPSIZEL)&sizelHim); XformSizeInHimetricToPixels(NULL, &sizelHim, &sizelPix);
if (sizelHim.cx == 0 || sizelPix.cx == 0) { lpscale->dwSxN = 1; lpscale->dwSxD = 1; } else { lpscale->dwSxN = lprcListBox->right - lprcListBox->left; lpscale->dwSxD = sizelPix.cx; }
if (sizelHim.cy == 0 || sizelPix.cy == 0) { lpscale->dwSyN = 1; lpscale->dwSyD = 1; } else { lpscale->dwSyN = lprcListBox->bottom - lprcListBox->top; lpscale->dwSyD = sizelPix.cy; }
lprcDoc->left = lprcListBox->left - Heading_RH_GetWidth(lphead,lpscale); lprcDoc->right = lprcListBox->right; lprcDoc->top = lprcListBox->top - Heading_CH_GetHeight(lphead,lpscale); lprcDoc->bottom = lprcListBox->bottom; }
/* ServerDoc_ResizeInPlaceWindow
** ----------------------------- ** Actually resize the in-place ServerDoc windows according to the ** PosRect and ClipRect allowed by our in-place container. ** ** OLE2NOTE: the PosRect rectangle that our in-place container tells ** us is always the rectangle required for the object display ** itself (in our case the size of the LineList contents). it does ** NOT include the space we require for object frame adornments. */ void ServerDoc_ResizeInPlaceWindow( LPSERVERDOC lpServerDoc, LPCRECT lprcPosRect, LPCRECT lprcClipRect ) { LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; LPLINELIST lpLL = (LPLINELIST)&lpOutlineDoc->m_LineList; SCALEFACTOR scale; RECT rcDoc; POINT ptOffset;
/* OLE2NOTE: calculate the space needed for our object frame
** adornments. our in-place container tells us the size that our ** object should take in window client coordinates ** (lprcPosRect). the rectangle cooresponds to the size that our ** LineList ListBox should be. our Doc window must the correct ** amount larger to accomodate our row/column headings. ** then move all windows into position. */ ServerDoc_CalcInPlaceWindowPos( lpServerDoc, (LPRECT)lprcPosRect, (LPRECT)&rcDoc, (LPSCALEFACTOR)&scale );
/* OLE2NOTE: we need to honor the lprcClipRect specified by our
** in-place container. we must NOT draw outside of the ClipRect. ** in order to achieve this, we will size the hatch window to be ** exactly the size that should be visible (rcVisRect). the ** rcVisRect is defined as the intersection of the full size of ** the in-place server window and the lprcClipRect. ** the ClipRect could infact clip the HatchRect on the ** right/bottom and/or on the top/left. if it is clipped on the ** right/bottom then it is sufficient to simply resize the hatch ** window. but if the HatchRect is clipped on the top/left then ** we must "move" the ServerDoc window (child of HatchWindow) by ** the delta that was clipped. the window origin of the ** ServerDoc window will then have negative coordinates relative ** to its parent HatchWindow. */ SetHatchWindowSize( lpServerDoc->m_hWndHatch, (LPRECT)&rcDoc, (LPRECT)lprcClipRect, (LPPOINT)&ptOffset );
// shift Doc window to account for hatch frame being drawn
OffsetRect((LPRECT)&rcDoc, ptOffset.x, ptOffset.y);
// move/size/set scale factor of ServerDoc window.
OutlineDoc_SetScaleFactor( lpOutlineDoc, (LPSCALEFACTOR)&scale, (LPRECT)&rcDoc);
/* reset the horizontal extent of the listbox. this makes
** the listbox realize that a scroll bar is not needed. */ SendMessage( lpLL->m_hWndListBox, LB_SETHORIZONTALEXTENT, (int) 0, 0L ); SendMessage( lpLL->m_hWndListBox, LB_SETHORIZONTALEXTENT, (int) (lprcPosRect->right - lprcPosRect->left), 0L ); }
/* ServerDoc_SetStatusText
** Tell the active in-place frame to display a status message. */ void ServerDoc_SetStatusText(LPSERVERDOC lpServerDoc, LPSTR lpszMessage) { if (lpServerDoc && lpServerDoc->m_fUIActive && lpServerDoc->m_lpIPData != NULL) {
OLEDBG_BEGIN2("IOleInPlaceFrame::SetStatusText called\r\n") CallIOleInPlaceFrameSetStatusTextA (lpServerDoc->m_lpIPData->lpFrame, lpszMessage); OLEDBG_END2 } }
/* ServerDoc_GetTopInPlaceFrame
** ---------------------------- ** returns NON-AddRef'ed pointer to Top In-Place Frame interface */ LPOLEINPLACEFRAME ServerDoc_GetTopInPlaceFrame(LPSERVERDOC lpServerDoc) { if (lpServerDoc->m_lpIPData) return lpServerDoc->m_lpIPData->lpFrame; else return NULL; }
void ServerDoc_GetSharedMenuHandles( LPSERVERDOC lpServerDoc, HMENU FAR* lphSharedMenu, HOLEMENU FAR* lphOleMenu ) { if (lpServerDoc->m_lpIPData) { *lphSharedMenu = lpServerDoc->m_lpIPData->hMenuShared; *lphOleMenu = lpServerDoc->m_lpIPData->hOlemenu; } else { *lphSharedMenu = NULL; *lphOleMenu = NULL; } }
void ServerDoc_AddFrameLevelUI(LPSERVERDOC lpServerDoc) { LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc); HMENU hSharedMenu; // combined obj/cntr menu
HOLEMENU hOleMenu; // returned by OleCreateMenuDesc.
ServerDoc_GetSharedMenuHandles( lpServerDoc, &hSharedMenu, &hOleMenu );
lpTopIPFrame->lpVtbl->SetMenu( lpTopIPFrame, hSharedMenu, hOleMenu, lpOutlineDoc->m_hWndDoc );
// save normal accelerator table
lpServerApp->m_hAccelBaseApp = lpOutlineApp->m_hAccelApp;
// install accelerator table for UIActive server (w/ active editor cmds)
lpOutlineApp->m_hAccel = lpServerApp->m_hAccelIPSvr; lpOutlineApp->m_hAccelApp = lpServerApp->m_hAccelIPSvr; lpOutlineApp->m_hWndAccelTarget = lpOutlineDoc->m_hWndDoc;
#if defined( USE_FRAMETOOLS )
ServerDoc_AddFrameLevelTools(lpServerDoc);
// update toolbar button enable states
OutlineDoc_UpdateFrameToolButtons(lpOutlineDoc); #endif
}
void ServerDoc_AddFrameLevelTools(LPSERVERDOC lpServerDoc) { LPOUTLINEAPP lpOutlineApp = (LPOUTLINEAPP)g_lpApp; LPSERVERAPP lpServerApp = (LPSERVERAPP)g_lpApp; LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; LPOLEINPLACEFRAME lpTopIPFrame=ServerDoc_GetTopInPlaceFrame(lpServerDoc);
#if defined( USE_FRAMETOOLS )
HWND hWndFrame;
FrameTools_Enable(lpOutlineDoc->m_lpFrameTools, TRUE);
// if not in-place UI active, add our tools to our own frame.
if (! lpServerDoc->m_fUIActive) { OutlineDoc_AddFrameLevelTools(lpOutlineDoc); return; }
if ((hWndFrame = OutlineApp_GetFrameWindow(lpOutlineApp)) == NULL) { /* we could NOT get a valid frame window, so POP our tools up. */
/* OLE2NOTE: since we are poping up our tools, we MUST inform
** the top in-place frame window that we need NO tool space ** BUT that it should NOT put its own tools up. if we were ** to pass NULL instead of (0,0,0,0), then the container ** would have the option to leave its own tools up. */ lpTopIPFrame->lpVtbl->SetBorderSpace( lpTopIPFrame, (LPCBORDERWIDTHS)&g_rectNull ); FrameTools_PopupTools(lpOutlineDoc->m_lpFrameTools); } else {
/* OLE2NOTE: we need to negotiate for space and attach our frame
** level tools to the top-level in-place container's frame window. */ FrameTools_AttachToFrame(lpOutlineDoc->m_lpFrameTools, hWndFrame);
FrameTools_NegotiateForSpaceAndShow( lpOutlineDoc->m_lpFrameTools, NULL, lpTopIPFrame ); }
#else // ! USE_FRAMETOOLS
/* OLE2NOTE: if you do NOT use frame tools, you MUST inform the top
** in-place frame window so that it can put back its own tools. */ lpTopIPFrame->lpVtbl->SetBorderSpace(lpIPData->lpFrame, NULL); #endif // ! USE_FRAMETOOLS
}
#if defined( USE_FRAMETOOLS )
void ServerDoc_RemoveFrameLevelTools(LPSERVERDOC lpServerDoc) { LPOUTLINEDOC lpOutlineDoc = (LPOUTLINEDOC)lpServerDoc; OleDbgAssert(lpOutlineDoc->m_lpFrameTools != NULL);
// Reparent our tools back to one of our own windows
FrameTools_AttachToFrame(lpOutlineDoc->m_lpFrameTools,g_lpApp->m_hWndApp);
FrameTools_Enable(lpOutlineDoc->m_lpFrameTools, FALSE); } #endif // USE_FRAMETOOLS
void ServerDoc_UIActivate (LPSERVERDOC lpServerDoc) { if (lpServerDoc->m_fInPlaceActive && !lpServerDoc->m_fUIActive) { ServerDoc_DoInPlaceActivate(lpServerDoc, OLEIVERB_UIACTIVATE, NULL /*lpmsg*/, lpServerDoc->m_lpOleClientSite ); OutlineDoc_ShowWindow((LPOUTLINEDOC)lpServerDoc); } }
|