|
|
//+---------------------------------------------------------------------
//
// File: sinpl.cxx
//
// Contents: Implementation of the SrvrInPlace class
//
//------------------------------------------------------------------------
#include "headers.hxx"
#pragma hdrstop
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::SrvrInPlace, public
//
// Synopsis: Constructor for SrvrInPlace object
//
// Notes: To create a properly initialized object you must
// call the Init method immediately after construction.
//
//---------------------------------------------------------------
SrvrInPlace::SrvrInPlace(void) { DOUT(TEXT("SrvrInPlace: Constructing\r\n"));
_hwnd = NULL;
_pInPlaceSite = NULL; _frameInfo.cb = sizeof(OLEINPLACEFRAMEINFO); _pFrame = NULL; _pDoc = NULL;
_hmenu = NULL; _hOleMenu = NULL; _hmenuShared = NULL;
_fCSHelpMode = FALSE; _fChildActivating = FALSE; _fDeactivating = FALSE; _rcFrame.top = 0; _rcFrame.left = 0; _rcFrame.bottom = 0; _rcFrame.right = 0;
_fClientResize = FALSE; _fUIDown = TRUE; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::Init, public
//
// Synopsis: Fully initializes a SrvrInPlace object
//
// Arguments: [pClass] -- The initialized class descriptor for the server
// [pCtrl] -- The control subobject of the server we are a part of.
//
// Returns: NOERROR if successful
//
// Notes: The class descriptor pointer is saved in the protected _pClass
// member variable where it is accessible during the lifetime
// of the object.
//
//---------------------------------------------------------------
HRESULT SrvrInPlace::Init(LPCLASSDESCRIPTOR pClass, LPSRVRCTRL pCtrl) { _pClass = pClass; _pCtrl = pCtrl; return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::~SrvrInPlace, protected
//
// Synopsis: Destructor for the SrvrCtrl object
//
// Notes: The destructor is called as a result of the servers
// reference count going to 0. It releases all held
// resources.
//
//---------------------------------------------------------------
SrvrInPlace::~SrvrInPlace(void) { DOUT(TEXT("SrvrInPlace: Destructed\r\n")); }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::ActivateInPlace, public
//
// Synopsis: In-place activates the object
//
// Arguments: [pClientSite] -- The site on our container
//
// Returns: Success if we in-place activated properly
//
// Notes: This method implements the standard in-place activation
// protocol and creates the in-place window. It creates
// all U.I. elements using CreateUI but does not
// activate the U.I., for that is reserved for
// the ActivateUI and InstallUI methods.
//
//---------------------------------------------------------------
HRESULT SrvrInPlace::ActivateInPlace(LPOLECLIENTSITE pClientSite) { DOUT(TEXT("SrvrInPlace::ActivateInPlace\r\n"));
if (pClientSite == NULL) { DOUT(TEXT("SrvrInPlace::ActivateInPlace E_INVALIDARG\r\n")); return E_INVALIDARG; }
HWND hwndSite; RECT rect, rectVis; HRESULT hr;
//
// see if the client site supports in-place, and is willing to do so...
//
if (OK(hr = pClientSite->QueryInterface(IID_IOleInPlaceSite, (LPVOID FAR *)&_pInPlaceSite))) { if (OK(hr = _pInPlaceSite->CanInPlaceActivate())) { if (OK(hr = _pInPlaceSite->GetWindow(&hwndSite)) && OK(hr = _pInPlaceSite->GetWindowContext(&_pFrame, &_pDoc, &rect, &rectVis, &_frameInfo))) { if ((_hwnd = AttachWin(hwndSite)) == NULL) { DOUT(TEXT("SrvrInPlace::ActivateInPlace failed at AttachWin\r\n")); hr = E_UNEXPECTED; } else { if (OK(hr = _pInPlaceSite->OnInPlaceActivate())) { if(_pCtrl->IsIPBEnabled()) { _IPB.Bind(_pInPlaceSite, _hwnd, FALSE); }
// create any U.I. elements
CreateUI();
// position and show the window
SetObjectRects(&rect, &rectVis); ShowWindow(_hwnd, SW_SHOW);
return NOERROR;
//
//The rest of this code cleans up after errors...
//
} DetachWin(); } if (_pFrame != NULL) _pFrame->Release(); if (_pDoc != NULL) _pDoc->Release(); } } _pInPlaceSite->Release(); }
return hr; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::DeactivateInPlace, public
//
// Synopsis: In-place deactivates the object
//
// Returns: Success except for catastophic circumstances
//
// Notes: This method "undoes" everything done in ActivateInPlace
// including destroying U.I. elements via DestroyUI, and
// destroying the inplace active window.
//
//---------------------------------------------------------------
HRESULT SrvrInPlace::DeactivateInPlace(void) { DOUT(TEXT("SrvrInPlace::DeactivateInPlace\r\n"));
//
// The following prevents some nasty recursion cases, in which the call
// bellow to OnInPlaceDeactivate get's us back in to the same transition we
// are in now...
//
_pCtrl->SetState(OS_RUNNING); // undo everything we did in InPlaceActivate
if(_pCtrl->IsIPBEnabled()) { _IPB.Detach(); }
DestroyUI(); DetachWin();
_pInPlaceSite->OnInPlaceDeactivate();
if (_pFrame != NULL) _pFrame->Release(); if (_pDoc != NULL) _pDoc->Release();
// release the in-place site we were holding on to.
_pInPlaceSite->Release(); _pInPlaceSite = NULL;
return NOERROR; // we never fail this function
}
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::ActivateUI, public
//
// Synopsis: Notifies container of U.I. activation and installs our
// U.I. elements.
//
// Returns: Success if our container granted permission to U.I. activate.
//
// Notes: Installing our U.I. (border toolbars, floating palettes,
// adornments) is accomplished via a virtual call to InstallUI.
//
//---------------------------------------------------------------
HRESULT SrvrInPlace::ActivateUI(void) { DOUT(TEXT("SrvrInPlace::ActivateUI\r\n"));
HRESULT hr; if (OK(hr = _pInPlaceSite->OnUIActivate())) { InstallUI();
if(!GetChildActivating() && !IsDeactivating()) ReflectState(TRUE); } return hr; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::DeactivateUI, public
//
// Synopsis: Removes any U.I. we have installed and notifies our container
// that we are no longer U.I. active
//
// Returns: Success except for catastrophic circumstances
//
// Notes: This method "undoes" everything done in ActivateUI.
// U.I. elements are removed via a virtual call to RemoveUI
//
//---------------------------------------------------------------
HRESULT SrvrInPlace::DeactivateUI(void) { DOUT(TEXT("SrvrInPlace::DeactivateUI\r\n"));
//
// The following prevents some nasty recursion cases, in which the call
// bellow to OnUIDeactivate get's us back in to the same transition we
// are in now...
//
_pCtrl->SetState(OS_INPLACE); // remove any UI that is up and notify our container that we have deactivated
RemoveUI(); _pInPlaceSite->OnUIDeactivate(FALSE); ReflectState(FALSE);
//REVIEW: we should return TRUE if we add Undo capability.
return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::InstallUI, public
//
// Synopsis: Installs previously created U.I. so it is displayed to
// the user.
//
// Notes: This method will call the InstallFrameUI and InstallDocUI
// methods to install those U.I. elements, respectively.
//
//---------------------------------------------------------------
void SrvrInPlace::InstallUI(void) { DOUT(TEXT("SrvrInPlace::InstallUI\r\n")); if(!_fChildActivating && !_fDeactivating) { _pFrame->SetActiveObject((LPOLEINPLACEACTIVEOBJECT)this, _pClass->_szUserClassType[USERCLASSTYPE_SHORT]); InstallFrameUI(); InstallDocUI(); _fUIDown = FALSE; } }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::RemoveUI, public
//
// Synopsis: Removes previously installed U.I. so it is hidden from the
// the user.
//
// Notes: This method "undoes" everything done in InstallUI. It calls
// the RemoveFrameUI and RemoveDocUI methods.
//
//---------------------------------------------------------------
void SrvrInPlace::RemoveUI(void) { DOUT(TEXT("SrvrInPlace::RemoveUI\r\n"));
if(!_fUIDown) { _fUIDown = TRUE;
ClearSelection(); RemoveDocUI(); RemoveFrameUI(); _pFrame->SetActiveObject(NULL, NULL); } }
#ifdef DOCGEN // documentation for pure virtual function
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::AttachWin, public
//
// Synopsis: Attaches the child in-place window
// to the given parent.
//
// Arguments: [hwndParent] -- parent window for child
//
// Returns: HWND of attached window
//
// Notes: All servers must override this method.
//
//---------------------------------------------------------------
HWND SrvrInPlace::AttachWin(HWND hwndParent) {} #endif //DOCGEN
//+--------------------------------------------------------------
//
// Member: SrvrInPlace::DetachWin, public
//
// Synopsis: Detaches the child's in-place
// window from the current parent.
//
// Arguments: [hwndParent] -- parent window for child
//
// Notes: This destroys the _hwnd of the server.
// If the derived class does anything
// other than create a Window on AttachWin,
// it must over-ride this function.
// If the derived class destroys the window
// on detach, it must set _hwnd = NULL
//
//---------------------------------------------------------------
void SrvrInPlace::DetachWin() { DOUT(TEXT("SrvrInPlace::DetachWin\r\n"));
Assert(_hwnd != NULL && IsWindow(_hwnd)); DestroyWindow(_hwnd); _hwnd = NULL; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::CreateUI, protected
//
// Synopsis: Creates all U.I. elements
//
// Notes: This method uses information in the class descriptor
// to create a merged menu and OLE menu descriptor.
// Servers that have additional U.I. should override
// this method, but can call the base class to do the
// standard menu processing.
//
// IMPORTANT: The derived class is responsible for having
// settup the _hmenu member prior to calling
// this code.
//
//---------------------------------------------------------------
void SrvrInPlace::CreateUI(void) { DOUT(TEXT("SrvrInPlace::CreateUI\r\n"));
Assert(_hmenuShared == NULL);
_fUIDown = TRUE;
if (_hmenu != NULL) { // create an empty menu and ask application to insert its menus
if ((_hmenuShared = CreateMenu()) != NULL) { // get a copy of our menu-group widths and perform the merge
_mgw = _pClass->_mgw; if (OK(_pFrame->InsertMenus(_hmenuShared, &_mgw))) { // insert our own menus and create a descriptor for
// the whole mess
if (OK(InsertServerMenus(_hmenuShared, _hmenu, &_mgw))) _hOleMenu = OleCreateMenuDescriptor(_hmenuShared, &_mgw); } } } }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::DestroyUI, protected
//
// Synopsis: Destroys U.I. elements
//
// Notes: This method "undoes" everything that was done in
// CreateUI -- destroys the shared menu and OLE menu
// descriptor. If a server overrides CreateUI then it
// should also override this method.
//
//---------------------------------------------------------------
void SrvrInPlace::DestroyUI(void) { DOUT(TEXT("SrvrInPlace::DestroyUI\r\n"));
if (_hmenuShared != NULL) { OleDestroyMenuDescriptor(_hOleMenu); RemoveServerMenus(_hmenuShared, &_mgw); _pFrame->RemoveMenus(_hmenuShared); DestroyMenu(_hmenuShared); _hmenuShared = NULL; } }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::InstallFrameUI, protected
//
// Synopsis: Installs the U.I. elements on the frame window
//
// Notes: This method uses IOleInPlaceFrame::SetMenu to install
// the shared menu constructed in CreateUI. It also notifies
// the frame that we are the active object.
// Servers that have additional frame adornments should
// override this method.
// This method is called by the InstallUI method and
// on document window activation for when we are in a MDI
// an application.
//
//---------------------------------------------------------------
void SrvrInPlace::InstallFrameUI(void) { DOUT(TEXT("SrvrInPlace::InstallFrameUI\r\n"));
_pFrame->SetMenu(_hmenuShared, _hOleMenu, _hwnd); }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::RemoveFrameUI, protected
//
// Synopsis: Removes the U.I. elements on the frame window
//
// Notes: This method "undoes" everything that was done in
// InstallFrameUI -- it removes the shared menu from
// the frame.
// Servers that override the InstallFrameUI method will
// also want to override this method.
// This method is call by the RemoveUI method and on
// document window deactivation for MDI-application purposes.
//
//---------------------------------------------------------------
void SrvrInPlace::RemoveFrameUI(void) { DOUT(TEXT("SrvrInPlace::RemoveFrameUI\r\n"));
_pFrame->SetMenu(NULL, NULL, _hwnd); }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::InstallDocUI, protected
//
// Synopsis: Installs the U.I. elements on the document window
//
// Notes: This method notifies the document window that we are
// the active object. Otherwise, there are no standard U.I. elements
// installed on the document window.
// Servers that have document window tools should override this
// method.
//
//---------------------------------------------------------------
void SrvrInPlace::InstallDocUI(void) { DOUT(TEXT("SrvrInPlace::InstallDocUI\r\n"));
if (_pDoc != NULL) { DOUT(TEXT("SrvrInPlace::InstallDocUI (_pDoc != NULL)\r\n")); _pDoc->SetActiveObject((LPOLEINPLACEACTIVEOBJECT)this, _pClass->_szUserClassType[USERCLASSTYPE_SHORT]); } }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::RemoveDocUI, protected
//
// Synopsis: Removes the U.I. elements from the document window.
//
// Notes: This method "undoes" everything done in the InstallDocUI
// method.
// Servers that override the InstallDocUI method should
// also override this method.
//
//---------------------------------------------------------------
void SrvrInPlace::RemoveDocUI(void) { DOUT(TEXT("SrvrInPlace::RemoveDocUI\r\n"));
if (_pDoc != NULL) { _pDoc->SetActiveObject(NULL, NULL); } }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::ClearSelection
//
// Synopsis: Removes any selection because we have lost ownership of the U.I.
//
// Notes: When our container or an embedding steals the right to put
// up the U.I. then we should remove any selection to avoid
// confusing the user.
//
//---------------------------------------------------------------
void SrvrInPlace::ClearSelection(void) { DOUT(TEXT("SrvrInPlace::ClearSelection\r\n")); }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::SetFocus, public
//
// Synopsis: Overide in derived if focus-window != _hwnd
//
//---------------------------------------------------------------
void SrvrInPlace::SetFocus(HWND hwnd) { ::SetFocus(hwnd); }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::GetWindow, public
//
// Synopsis: Method of IOleWindow interface
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::GetWindow(HWND FAR* lphwnd) { if (lphwnd == NULL) { DOUT(TEXT("SrvrInPlace::GetWindow E_INVALIDARG\r\n")); return E_INVALIDARG; }
*lphwnd = _hwnd; return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::ContextSensitiveHelp, public
//
// Synopsis: Method of IOleWindow interface
//
// Notes: This method sets or clears the _fCSHelpMode
// member flag. The window procedure needs to pay
// attention to the value of this flag in implementing
// context-sensitive help.
//
// We never fail!
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::ContextSensitiveHelp(BOOL fEnterMode) { DOUT(TEXT("SrvrInPlace::ContextSensitiveHelp\r\n"));
_fCSHelpMode = fEnterMode; return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::InPlaceDeactivate, public
//
// Synopsis: Method of IOleInPlaceObject interface
//
// Notes: This method transitions the object to the loaded state
// if the object is in the InPlace or U.I. active state.
//
// We never fail!
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::InPlaceDeactivate(void) { DOUT(TEXT("SrvrInPlace::InPlaceDeactivate\r\n"));
if (_pCtrl->State() == OS_INPLACE || _pCtrl->State() == OS_UIACTIVE) { _pCtrl->TransitionTo(OS_LOADED); } return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::UIDeactivate, public
//
// Synopsis: Method of IOleInPlaceObject interface
//
// Notes: The method transitions the object to the in-place state
// if the object is in U.I. active state.
//
// We never fail!
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::UIDeactivate(void) { DOUT(TEXT("SrvrInPlace::UIDeactivate\r\n"));
if (_pCtrl->State() == OS_UIACTIVE) { _fDeactivating = TRUE; _pCtrl->TransitionTo(OS_INPLACE); _fDeactivating = FALSE; } return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::SetObjectRects, public
//
// Synopsis: Method of IOleInPlaceObject interface
//
// Notes: This method does a Move window on the child
// window to put it in its new position.
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::SetObjectRects(LPCRECT lprcPos, LPCRECT lprcVisRect) { DOUT(TEXT("SrvrInPlace::SetObjectRects\r\n"));
if (lprcPos == NULL || lprcVisRect == NULL) { DOUT(TEXT("SrvrInPlace::SetObjectRects E_INVALIDARG\r\n")); return E_INVALIDARG; }
_fClientResize = TRUE; //indicate that we are being resized by client
//
// calculate and do the new child window positioning
//
RECT rc = *lprcPos; if(_pCtrl->IsIPBEnabled()) { _IPB.SetSize(_hwnd, rc); } else { SetWindowPos( _hwnd, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER); }
//
// update our border rect (child window coordinates)
//
_rcFrame.right = rc.right - rc.left; _rcFrame.bottom = rc.bottom - rc.top;
//
// update our "native" extent
//
SIZEL sizel = { HimetricFromHPix(_rcFrame.right - _rcFrame.left), HimetricFromVPix(_rcFrame.bottom - _rcFrame.top) };
_pCtrl->SetExtent(DVASPECT_CONTENT, &sizel);
_fClientResize = FALSE; // indicate that client resize is over
return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::ReactivateAndUndo, public
//
// Synopsis: Method of IOleInPlaceObject interface
//
// Notes: This method returns E_FAIL. If the server wishes
// to support undo it should override this method.
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::ReactivateAndUndo(void) { DOUT(TEXT("SrvrInPlace::ReactivateAndUndo E_NOTIMPL\r\n")); return E_NOTIMPL; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::TranslateAccelerator, public
//
// Synopsis: Method of IOleInPlaceActiveObject interface
//
// Notes: This method translates the message according
// to the accelerator table in the class descriptor
// structure.
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::TranslateAccelerator(LPMSG lpmsg) { //
// translate the message via the SrvrInPlace accelerator table
//
if (_pClass->_haccel && ::TranslateAccelerator(_hwnd, _pClass->_haccel, lpmsg)) { return NOERROR; }
return S_FALSE; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::OnFrameWindowActivate, public
//
// Synopsis: Method of IOleInPlaceObject interface
//
// Notes: This method changes the color of our border shading
// depending on whether our frame window is activating
// or deactivating.
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::OnFrameWindowActivate(BOOL fActivate) { DOUT(TEXT("SrvrInPlace::OnFrameWindowActivate\r\n"));
if(_pCtrl->IsIPBEnabled()) _IPB.SetParentActive(fActivate);
if(fActivate && _hwnd && (_pCtrl->State() != OS_OPEN)) SetFocus(_hwnd);
return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::OnDocWindowActivate, public
//
// Synopsis: Method of IOleInPlaceObject interface
//
// Notes: This method will install or remove the frame
// U.I. elements using the InstallFrameUI or RemoveFrameUI
// methods. This is to properly handle the MDI application
// case. It also updates our shading color.
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::OnDocWindowActivate(BOOL fActivate) { DOUT(TEXT("SrvrInPlace::OnDocWindowActivate\r\n"));
if (fActivate) { InstallFrameUI(); SetFocus(_hwnd); } else if (!fActivate) RemoveFrameUI();
if(_pCtrl->IsIPBEnabled()) _IPB.SetParentActive(fActivate);
return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::ResizeBorder, public
//
// Synopsis: Method of IOleInPlaceObject interface
//
// Notes: There are no standard border adornments so we do
// nothing in this method. Servers that have additional
// U.I. elements that are installed on the frame or
// document windows should override this method.
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::ResizeBorder(LPCRECT lprc, LPOLEINPLACEUIWINDOW pUIWindow, BOOL fFrameWindow) { DOUT(TEXT("SrvrInPlace::ResizeBorder\r\n"));
// we do not install any tools on our frame or document windows.
//REVIEW: This must be implemented if we do implement a frame or document
//REVIEW: toolbar.
return NOERROR; }
//+---------------------------------------------------------------
//
// Member: SrvrInPlace::EnableModeless, public
//
// Synopsis: Method of IOleInPlaceObject interface
//
// Notes: If we are a DLL and hence don't have a separate
// message pump we can ignore this call and simply
// return NOERROR.
//
//---------------------------------------------------------------
STDMETHODIMP SrvrInPlace::EnableModeless(BOOL fEnable) { DOUT(TEXT("SrvrInPlace::EnableModeless\r\n"));
return NOERROR; }
|