//=--------------------------------------------------------------------------= // ControlEmbedding.Cpp //=--------------------------------------------------------------------------= // Copyright 1995 Microsoft Corporation. All Rights Reserved. // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. //=--------------------------------------------------------------------------= // // implementation of the interfaces required for inplace activation for // COleControl // #include "pch.h" #include "CtrlObj.H" #include "CtlHelp.H" #include "StdEnum.H" // for ASSERT and FAIL // SZTHISFILE //=--------------------------------------------------------------------------= // all controls support the following in-place verbs at an absolute minimum. // #define CINPLACEVERBS 4 const VERBINFO rgInPlaceVerbs [] = { { OLEIVERB_SHOW, 0, 0, 0}, { OLEIVERB_HIDE, 0, 0, 0}, { OLEIVERB_INPLACEACTIVATE, 0, 0, 0}, { OLEIVERB_PRIMARY, 0, 0, 0} }; // NOTE: Resource ID for Properties string must be 1000 // const VERBINFO ovProperties = { CTLIVERB_PROPERTIES, 1000, 0, OLEVERBATTRIB_ONCONTAINERMENU }; const VERBINFO ovUIActivate = { OLEIVERB_UIACTIVATE, 0, 0, 0}; //=--------------------------------------------------------------------------= // COleControl::GetControlInfo (IOleControl) //=--------------------------------------------------------------------------= // returns some information on a control, such as an accelerator table, and // flags. really used for keyboard handling and mnemonics // // Parameters: // CONTROLINFO * - [in] where to put said information // // Output: // HRESULT - S_OK // // Notes: // STDMETHODIMP COleControl::GetControlInfo ( CONTROLINFO *pControlInfo ) { CHECK_POINTER(pControlInfo); // certain hosts have a bug in which it doesn't initialize the cb in the // CONTROLINFO structure, so we can only assert on that here. // ASSERT(pControlInfo->cb == sizeof(CONTROLINFO), "Host doesn't initialize CONTROLINFO structure"); // NOTE: control writers should override this routine if they want to // return accelerator information in their control. // pControlInfo->hAccel = NULL; pControlInfo->cAccel = NULL; pControlInfo->dwFlags = 0; //joejo - Vegas #VBE9106 uninitialized dwFlags return S_OK; } //=--------------------------------------------------------------------------= // COleControl::OnMnemonic [IOleControl] //=--------------------------------------------------------------------------= // the container has decided to pass on a key that the end-user has pressed to // us. default implementation will be to just activate the control. people // looking for more functionality should override this method. // // Parameters: // LPMSG - [in] message for this mnemonic // // Output: // HRESULT - S_OK, E_POINTER // // Notes: // STDMETHODIMP COleControl::OnMnemonic ( LPMSG pMsg ) { // OVERRIDE: default implementation is to just activate our control. // user can override if they want more interesting behaviour. // return InPlaceActivate(OLEIVERB_UIACTIVATE); } //=--------------------------------------------------------------------------= // COleControl:OnAmbientPropertyChange [IOleControl] //=--------------------------------------------------------------------------= // a container calls this whenever it changes an ambient property. // // Parameters: // DISPID - [in] dispid of the property that changed. // // Output: // HRESULT - S_OK // // Notes: // STDMETHODIMP COleControl::OnAmbientPropertyChange ( DISPID dispid ) { // if we're being told about a change in mode [design/run] then // remember that so our stashing of mode will update itself // correctly // if (dispid == DISPID_AMBIENT_USERMODE || dispid == DISPID_UNKNOWN) m_fModeFlagValid = FALSE; if (dispid == DISPID_AMBIENT_LOCALEID || dispid == DISPID_UNKNOWN) { ENTERCRITICALSECTION1(&g_CriticalSection); // Should be a crit sect around this. g_fHaveLocale = FALSE; // Cause the lcid to be re-browsed when its needed LEAVECRITICALSECTION1(&g_CriticalSection); } // just pass this on to the derived control and see if they want // to do anything with it. // AmbientPropertyChanged(dispid); return S_OK; } //=--------------------------------------------------------------------------= // COleControL::FreezeEvents [IOleControl] //=--------------------------------------------------------------------------= // allows a container to freeze all of a controls events. when events are // frozen, a control will not fire any of them. // // Parameters: // BOOL - [in] TRUE means FREEZE, FALSE means THAW // // Output: // HRESULT - S_OK // // Notes: // - we maintain an internal count of freezes versus thaws. // STDMETHODIMP COleControl::FreezeEvents ( BOOL fFreeze ) { // OVERRIDE: by default, we don't care. user can override if they want to. // return S_OK; } //=--------------------------------------------------------------------------= // COleControl::SetClientSite [IOleObject] //=--------------------------------------------------------------------------= // informs the embedded object [control] of it's client site [display // location] within it's container // // Parameters: // IOleClientSite * - [in] pointer to client site. // // Output: // HRESULT - S_OK, E_UNEXPECTED // // Notes: // STDMETHODIMP COleControl::SetClientSite ( IOleClientSite *pClientSite ) { // make sure we free up all site pointers we're holding on to! otherwise, // we can run into problems during aggregation // RELEASE_OBJECT(m_pClientSite); RELEASE_OBJECT(m_pControlSite); RELEASE_OBJECT(m_pSimpleFrameSite); // store away the new client site // m_pClientSite = pClientSite; // if we've actually got one, then get some other interfaces we want to keep // around, and keep a handle on it // if (m_pClientSite) { m_pClientSite->AddRef(); m_pClientSite->QueryInterface(IID_IOleControlSite, (void **)&m_pControlSite); if (OLEMISCFLAGSOFCONTROL(m_ObjectType) & OLEMISC_SIMPLEFRAME) m_pClientSite->QueryInterface(IID_ISimpleFrameSite, (void **)&m_pSimpleFrameSite); } else { // if they're telling us to clear our site pointers, go and release // everything else as well // RELEASE_OBJECT(m_pInPlaceSite); RELEASE_OBJECT(m_pInPlaceSiteWndless); RELEASE_OBJECT(m_pDispAmbient); } // now get the user to clear out/re-establish the pointers they want // return OnSetClientSite(); } //=--------------------------------------------------------------------------= // COleControl::GetClientSite [IOleObject] //=--------------------------------------------------------------------------= // obtains a pointer to the controls client site. // // Parameters: // IOleClientSite ** - [out] // // Output: // HRESULT - S_OK // // Notes: // STDMETHODIMP COleControl::GetClientSite ( IOleClientSite **ppClientSite ) { CHECK_POINTER(ppClientSite); *ppClientSite = m_pClientSite; ADDREF_OBJECT(*ppClientSite); return S_OK; } //=--------------------------------------------------------------------------= // COleControl::SetHostNames [IOleObject] //=--------------------------------------------------------------------------= // Provides the control with the name of its container application and the // compound document in which it is embedded // // Parameters: // LPCOLESTR - [in] name of container application // LPCOLESTR - [in] name of container document // // Output: // HRESULT - S_OK // // Notes: // - we don't care about this // STDMETHODIMP COleControl::SetHostNames ( LPCOLESTR szContainerApp, LPCOLESTR szContainerObject ) { // we don't care about these // return S_OK; } //=--------------------------------------------------------------------------= // COleControl::Close [IOleObject] //=--------------------------------------------------------------------------= // Changes the control from the running to the loaded state // // Parameters: // DWORD - [in] indicates whether to save the object before closing // // Output: // HRESULT - S_OK, OLE_E_PROMPTSAVECANCELLED // // Notes: // STDMETHODIMP COleControl::Close ( DWORD dwSaveOption ) { HRESULT hr; if (m_fInPlaceActive) { hr = InPlaceDeactivate(); RETURN_ON_FAILURE(hr); } // handle the save flag. // if ((dwSaveOption == OLECLOSE_SAVEIFDIRTY || dwSaveOption == OLECLOSE_PROMPTSAVE) && m_fDirty) { if (m_pClientSite) m_pClientSite->SaveObject(); if (m_pOleAdviseHolder) m_pOleAdviseHolder->SendOnSave(); } return S_OK; } //=--------------------------------------------------------------------------= // COleControl::SetMoniker [IOleObject] //=--------------------------------------------------------------------------= // Notifies an object of its container's moniker, the object's own moniker // relative to the container, or the object's full moniker // // Parameters: // DWORD - [in] which moniker is being set // IMoniker * - [in] the moniker // // Output: // HRESULT - S_OK, E_FAIL // // Notes: // - we don't support monikers. // STDMETHODIMP COleControl::SetMoniker ( DWORD dwWhichMoniker, IMoniker *pMoniker ) { return E_NOTIMPL; } //=--------------------------------------------------------------------------= // COleControl::GetMoniker [IOleObject] //=--------------------------------------------------------------------------= // Returns a embedded object's moniker, which the caller can use to link to // the object // // Parameters: // DWORD - [in] how it's assigned // DWORD - [in] which moniker // IMoniker ** - [out] duh. // // Output: // HRESULT - E_NOTIMPL // // Notes: // - we don't support monikers // STDMETHODIMP COleControl::GetMoniker ( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppMonikerOut ) { return E_NOTIMPL; } //=--------------------------------------------------------------------------= // COleControl::InitFromData [IOleObject] //=--------------------------------------------------------------------------= // Initializes a newly created object with data from a specified data object, // which can reside either in the same container or on the Clipboard // // Parameters: // IDataObject* - [in] data object with the data // BOOL - [in] how object is created // DWORD - reserved // // Output: // HRESULT - S_OK, S_FALSE, E_NOTIMPL, OLE_E_NOTRUNNING // // Notes: // - we don't have data object support // STDMETHODIMP COleControl::InitFromData ( IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved ) { return E_NOTIMPL; } //=--------------------------------------------------------------------------= // COleControl::GetClipboardData [IOleObject] //=--------------------------------------------------------------------------= // Retrieves a data object containing the current contents of the control. // Using the pointer to this data object, it is possible to create a new control // with the same data as the original // // Parameters: // DWORD - reserved // IDataObject ** - [out] data object for this control // // Output: // HREUSLT - S_OK, E_NOTIMPL, OLE_E_NOTRUNNING // // Notes: // STDMETHODIMP COleControl::GetClipboardData ( DWORD dwReserved, IDataObject **ppDataObject ) { *ppDataObject = NULL; // be a good neighbour return E_NOTIMPL; } //=--------------------------------------------------------------------------= // COleControl::DoVerb [IOleObject] //=--------------------------------------------------------------------------= // Requests an object to perform an action in response to an end-user's // action. // // Parameters: // LONG - [in] verb to be performed // LPMSG - [in] event that invoked the verb // IOleClientSite * - [in] the controls active client site // LONG - [in] reserved // HWND - [in] handle of window containing the object. // LPCRECT - [in] pointer to objects's display rectangle // // Output: // HRESULT - S_OK, OLE_E_NOTINPLACEACTIVE, OLE_E_CANT_BINDTOSOURCE, // DV_E_LINK, OLEOBJ_S_CANNOT_DOVERB_NOW, OLEOBJ_S_INVALIDHWND, // OLEOBJ_E_NOVERBS, OLEOBJ_S_INVALIDVERB, MK_E_CONNECT, // OLE_CLASSDIFF, E_NOTIMPL // // Notes: // STDMETHODIMP COleControl::DoVerb ( LONG lVerb, LPMSG pMsg, IOleClientSite *pActiveSite, LONG lIndex, HWND hwndParent, LPCRECT prcPosRect ) { HRESULT hr; switch (lVerb) { case OLEIVERB_SHOW: case OLEIVERB_INPLACEACTIVATE: case OLEIVERB_UIACTIVATE: return InPlaceActivate(lVerb); case OLEIVERB_HIDE: UIDeactivate(); if (m_fInPlaceVisible) SetInPlaceVisible(FALSE); return S_OK; // we used to have OLEIVERB_PRIMARY InPlaceActivate Ourselves, but it // turns out that the CDK and certain hosts expect this to show the // properties instead. Users can change what this verb does at will. // case OLEIVERB_PRIMARY: case CTLIVERB_PROPERTIES: case OLEIVERB_PROPERTIES: { int iPage; CLSID *prgPropPages; // Only allow the Property Page to be displayed in design-mode. // if (!DesignMode()) return S_OK; // show the frame ourselves if the host can't. // if (m_pControlSite) { hr = m_pControlSite->ShowPropertyFrame(); if (hr != E_NOTIMPL) return hr; } IUnknown *pUnk = (IUnknown *)(IOleObject *)this; MAKE_WIDEPTR_FROMANSI(pwsz, NAMEOFOBJECT(m_ObjectType)); // Allocate an array of CLSIDs // prgPropPages = (CLSID *) CtlHeapAlloc(g_hHeap, 0, CPROPPAGESOFCONTROL(m_ObjectType) * sizeof(CLSID)); if (!prgPropPages) return E_OUTOFMEMORY; // Copy the CLSIDs pointed to by the array of CLSID pointers to // an array of CLSIDs. This conversion is necessary since OleCreatePropertyFrame // expects a pointer to an array of CLSIDs. CPROPPAGESOFCONTROL(index) returns // a pointer to an array of CLSID pointers. // for (iPage = 0; iPage < CPROPPAGESOFCONTROL(m_ObjectType); iPage++) prgPropPages[iPage] = *((PPROPPAGESOFCONTROL(m_ObjectType))[iPage]); ModalDialog(TRUE); ENTERCRITICALSECTION1(&g_CriticalSection); // This is for g_lcidLocale. hr = OleCreatePropertyFrame(GetActiveWindow(), GetSystemMetrics(SM_CXSCREEN) / 2, GetSystemMetrics(SM_CYSCREEN) / 2, pwsz, 1, &pUnk, CPROPPAGESOFCONTROL(m_ObjectType), prgPropPages, g_lcidLocale, NULL, NULL); LEAVECRITICALSECTION1(&g_CriticalSection); ModalDialog(FALSE); CtlHeapFree(g_hHeap, 0, prgPropPages); return hr; } default: // if it's a derived-control defined verb, pass it on to them // if (lVerb > 0) { hr = DoCustomVerb(lVerb); if (hr == OLEOBJ_S_INVALIDVERB) { // unrecognised verb -- just do the primary verb and // activate the sucker. // hr = InPlaceActivate(OLEIVERB_PRIMARY); return (FAILED(hr)) ? hr : OLEOBJ_S_INVALIDVERB; } else return hr; } else { // it's a verb we don't implement. // return E_NOTIMPL; } break; } // dead code FAIL("this should be dead code!"); } //=--------------------------------------------------------------------------= // COleControl::EnumVerbs [IOleObject] //=--------------------------------------------------------------------------= // create an enumerator object for the verbs this object supports. // // Parameters: // IEnumOleVERB ** - [out] new enumerator. // // Output: // HRESULT - S_OK, E_OUTOFMEMORY // // Notes: // STDMETHODIMP COleControl::EnumVerbs ( IEnumOLEVERB **ppEnumVerbs ) { int cVerbs; OLEVERB *rgVerbs, *pVerb; DWORD dw = OLEMISCFLAGSOFCONTROL(m_ObjectType); BOOL fCanInPlace = !(dw & OLEMISC_INVISIBLEATRUNTIME) || (dw & OLEMISC_ACTIVATEWHENVISIBLE); BOOL fCanUIActivate = !(dw & OLEMISC_NOUIACTIVATE); BOOL fHasProperties = (CPROPPAGESOFCONTROL(m_ObjectType) != 0); int cVerbExtra = CCUSTOMVERBSOFCONTROL(m_ObjectType); // count up all the verbs // cVerbs = (fCanInPlace ? CINPLACEVERBS : 0) + (fCanUIActivate ? 1 : 0) + (fHasProperties ? 1 : 0) + cVerbExtra; // if there aren't any, this suddenly gets really easy ! // if (cVerbs == 0) return OLEOBJ_E_NOVERBS; // HeapAlloc some storage for these dudes so that we can pass them on to // the standard enumerator! // if (! (rgVerbs = (OLEVERB *)CtlHeapAlloc(g_hHeap, 0, cVerbs * sizeof(OLEVERB)))) return E_OUTOFMEMORY; // start copying over verbs. first, the in-place guys // pVerb = rgVerbs; if (fCanInPlace) { memcpy(pVerb, rgInPlaceVerbs, CINPLACEVERBS * sizeof(OLEVERB)); pVerb += CINPLACEVERBS; } if (fCanUIActivate) memcpy(pVerb++, &ovUIActivate, sizeof(OLEVERB)); // if their control has properties, copy that over now. // if (fHasProperties) { memcpy(pVerb, &ovProperties, sizeof(OLEVERB)); pVerb++; } // finally, any custom verbs! // if (cVerbExtra) { memcpy(pVerb, CUSTOMVERBSOFCONTROL(m_ObjectType), sizeof(OLEVERB) * cVerbExtra); } *ppEnumVerbs = (IEnumOLEVERB *) (IEnumGeneric *) New CStandardEnum(IID_IEnumOLEVERB, cVerbs, sizeof(OLEVERB), rgVerbs, CopyOleVerb); if (!*ppEnumVerbs) return E_OUTOFMEMORY; // this forces us to go and look for the Localized DLLs. This is necessary here // because the CopyOleVerb will get information from localized resources, but // will only use the global GetResourceHandle, which only uses the global value // for the LCID. This turns out to not be a big performance hit, since this // function is typically only called in design mode, and we stash this value. // GetResourceHandle(); return S_OK; } //=--------------------------------------------------------------------------= // COleControl::Update [IOleObject] //=--------------------------------------------------------------------------= // Updates an object handler's or link object's data or view caches. // // Output: // HRESULT - S_OK // // Notes: // STDMETHODIMP COleControl::Update ( void ) { // nothing to do!!! // return S_OK; } //=--------------------------------------------------------------------------= // COleControl::IsUpToDate [IOleObject] //=--------------------------------------------------------------------------= // Checks recursively whether or not an object is up to date. // // Output: // HRESULT - S_OK, S_FALSE, OLE_E_UNVAILABLE // // Notes: // STDMETHODIMP COleControl::IsUpToDate ( void ) { // we're always up to date // return S_OK; } //=--------------------------------------------------------------------------= // COleControl::GetUserClassID [IOleObject] //=--------------------------------------------------------------------------= // Returns the controls class identifier, the CLSID corresponding to the // string identifying the object to an end user. // // Parameters: // CLSID * - [in] where to put the CLSID // // Output: // HRESULT - S_OK, E_FAIL // // Notes: // STDMETHODIMP COleControl::GetUserClassID ( CLSID *pclsid ) { // this is the same as IPersist::GetClassID // return GetClassID(pclsid); } //=--------------------------------------------------------------------------= // COleControl::GetUserType [IOleObject] //=--------------------------------------------------------------------------= // Retrieves the user-type name of the control for display in user-interface // elements such as menus, list boxes, and dialog boxes. // // Parameters: // DWORD - [in] specifies the form of the type name. // LPOLESTR * - [out] where to put user type // // Output: // HRESULT - S_OK, OLE_S_USEREG, E_OUTOFMEMORY // // Notes: // STDMETHODIMP COleControl::GetUserType ( DWORD dwFormOfType, LPOLESTR *ppszUserType ) { *ppszUserType = OLESTRFROMANSI(NAMEOFOBJECT(m_ObjectType)); return (*ppszUserType) ? S_OK : E_OUTOFMEMORY; } //=--------------------------------------------------------------------------= // COleControl::SetExtent [IOleObject] //=--------------------------------------------------------------------------= // Informs the control of how much display space its container has assigned it. // // Parameters: // DWORD - [in] which form or 'aspect' is to be displayed. // SIZEL * - [in] size limit for the control. // // Output: // HRESULT - S_OK, E_FAIL, OLE_E_NOTRUNNING // // Notes: // STDMETHODIMP COleControl::SetExtent ( DWORD dwDrawAspect, SIZEL *psizel ) { SIZEL sl, slOld; RECT rect; BOOL f; if (dwDrawAspect & DVASPECT_CONTENT) { // Call to OnPosRectChange may cause our extents to be set again. Accept the extents if this happens. // if (m_fChangingExtents) return S_OK; m_fChangingExtents = TRUE; // change the units to pixels, and resize the control. // HiMetricToPixel(psizel, &sl); // first call the user version. if they return FALSE, they want // to keep their current size // slOld = m_Size; f = OnSetExtent(&sl); if (f) m_Size = sl; /// Note: subclassing control may change the passed in &sl extents if (slOld.cx != m_Size.cx || slOld.cy != m_Size.cy) m_fDirty = TRUE; // set things up with our HWND if we've got one. // if (!m_pInPlaceSiteWndless) { if (m_fInPlaceActive) { // theoretically, one should not need to call OnPosRectChange // here, but there appear to be a few host related issues that // will make us keep it here. we won't, however, both with // windowless ole controls, since they are all new hosts who // should know better // if (m_hwnd) { rect = m_rcLocation; rect.right = rect.left + m_Size.cx; rect.bottom = rect.top + m_Size.cy; GetInPlaceSite()->OnPosRectChange(&rect); // May cause container to call our SetObjectRects } } else if (m_hwnd) { SetWindowPos(m_hwnd, NULL, 0, 0, m_Size.cx, m_Size.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); } else { ViewChanged(); } } if (!m_fInPlaceActive) { // Due to trident, we need to call RequestNewObjectLayout // here so we visually display our new extents. if (m_pClientSite) m_pClientSite->RequestNewObjectLayout(); } m_fChangingExtents = FALSE; // return code depending on whether or not user accepted given // size // return (f) ? S_OK : E_FAIL; } else { // we don't support any other aspects. // return DV_E_DVASPECT; } // dead code FAIL("This should be dead code"); } //=--------------------------------------------------------------------------= // COleControl::GetExtent [IOleObject] //=--------------------------------------------------------------------------= // Retrieves the control's current display size. // // Parameters: // DWORD - [in] aspect // SIZEL * - [in] where to put results // // Output: // S_OK, E_INVALIDARG // // Notes: // STDMETHODIMP COleControl::GetExtent ( DWORD dwDrawAspect, SIZEL *pSizeLOut ) { if (dwDrawAspect & DVASPECT_CONTENT) { PixelToHiMetric((const SIZEL *)&m_Size, pSizeLOut); return S_OK; } else { return DV_E_DVASPECT; } // dead code } //=--------------------------------------------------------------------------= // COleControl::Advise [IOleObject] //=--------------------------------------------------------------------------= // establishes and advisory connection between the control and the container, // in which the control will notify the container of certain events. // // Parameters: // IAdviseSink * - [in] advise sink of calling object // DWORD - [out] cookie // // Output: // HRESULT - S_OK, E_OUTOFMEMORY // // Notes: // STDMETHODIMP COleControl::Advise ( IAdviseSink *pAdviseSink, DWORD *pdwConnection ) { HRESULT hr; // if we haven't yet created a standard advise holder object, do so // now // if (!m_pOleAdviseHolder) { hr = CreateOleAdviseHolder(&m_pOleAdviseHolder); RETURN_ON_FAILURE(hr); } // just get it to do the work for us! // return m_pOleAdviseHolder->Advise(pAdviseSink, pdwConnection); } //=--------------------------------------------------------------------------= // COleControl::Unadvise [IOleObject] //=--------------------------------------------------------------------------= // Deletes a previously established advisory connection. // // Parameters: // DWORD - [in] connection cookie // // Output: // HRESULT - S_OK, E_FAIL, OLE_E_NOCONNECTION // // Notes: // STDMETHODIMP COleControl::Unadvise ( DWORD dwConnection ) { if (!m_pOleAdviseHolder) { FAIL("Somebody called Unadvise on IOleObject without calling Advise!"); CONNECT_E_NOCONNECTION; } return m_pOleAdviseHolder->Unadvise(dwConnection); } //=--------------------------------------------------------------------------= // COleControl::EnumAdvise [IOleObject] //=--------------------------------------------------------------------------= // Enumerates the advisory connections registered for an object, so a container // can know what to release prior to closing down. // // Parameters: // IEnumSTATDATA ** - [out] where to put enumerator // // Output: // HRESULT - S_OK, E_FAIL, E_NOTIMPL // // Notes: // STDMETHODIMP COleControl::EnumAdvise ( IEnumSTATDATA **ppEnumOut ) { if (!m_pOleAdviseHolder) { FAIL("Somebody Called EnumAdvise without setting up any connections"); *ppEnumOut = NULL; return E_FAIL; } return m_pOleAdviseHolder->EnumAdvise(ppEnumOut); } //=--------------------------------------------------------------------------= // COleControl::GetMiscStatus [IOleObject] //=--------------------------------------------------------------------------= // Returns a value indicating the status of an object at creation and loading. // // Parameters: // DWORD - [in] aspect desired // DWORD * - [out] where to put the bits. // // Output: // HRESULT - S_OK, OLE_S_USEREG, CO_E_CLASSNOTREG, CO_E_READREGDB // // Notes: // STDMETHODIMP COleControl::GetMiscStatus ( DWORD dwAspect, DWORD *pdwStatus ) { CHECK_POINTER(pdwStatus); if (dwAspect == DVASPECT_CONTENT) { *pdwStatus = OLEMISCFLAGSOFCONTROL(m_ObjectType); return S_OK; } else { return DV_E_DVASPECT; } // dead code } //=--------------------------------------------------------------------------= // COleControl::SetColorScheme [IOleObject] //=--------------------------------------------------------------------------= // Specifies the color palette that the object application should use when it // edits the specified object. // // Parameters: // LOGPALETTE * - [in] new palette // // Output: // HRESULT - S_OK, E_NOTIMPL, OLE_E_PALETTE, OLE_E_NOTRUNNING // // Notes: // - we don't care. // STDMETHODIMP COleControl::SetColorScheme ( LOGPALETTE *pLogpal ) { // OVERRIDE: control writers can use this if they want to // return S_OK; } //=--------------------------------------------------------------------------= // COleControl::GetWindow [IOleWindow/IOleInPlaceObject] //=--------------------------------------------------------------------------= // Returns the window handle to one of the windows participating in in-place // activation (frame, document, parent, or in-place object window). // // Parameters: // HWND * - [out] where to return window handle. // // Output: // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED, E_FAIL // // Notes: // - this routine has slightly different semantics for windowless controls // STDMETHODIMP COleControl::GetWindow ( HWND *phwnd ) { // if we're windowles, then we want to return E_FAIL for this so hosts // know we're windowless. we'll also fail if we're not in-place active // if (m_pInPlaceSiteWndless || !m_fInPlaceActive) return E_FAIL; // otherwise, just return our outer window. // *phwnd = GetOuterWindow(); return (*phwnd) ? S_OK : E_UNEXPECTED; } //=--------------------------------------------------------------------------= // COleControl::ContextSensitiveHelp [IOleWindow/IOleInPlaceObject] //=--------------------------------------------------------------------------= // Determines whether context-sensitive help mode should be entered during an // in-place activation session. // // Parameters: // BOOL - [in] whether or not to enter help mode. // // Output: // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED // // Notes: // STDMETHODIMP COleControl::ContextSensitiveHelp ( BOOL fEnterMode ) { return E_NOTIMPL; } //=--------------------------------------------------------------------------= // COleControl::InPlaceActivate //=--------------------------------------------------------------------------= // activates the control, and depending on the verb, optionally ui activates // it as well. // // Parameters: // LONG - [in] the verb that caused us to activate // // Output: // HRESULT // // Notes: // - this is spaghetti code at it's worst. effectively, we have to // be able to handle three types of site pointers -- IOleInPlaceSIte, // IOleInPlaceSiteEx, and IOleInPlaceSiteWindowless. not terribly // pretty. // HRESULT COleControl::InPlaceActivate ( LONG lVerb ) { BOOL f; SIZEL sizel; IOleInPlaceSiteEx *pIPSEx = NULL; HRESULT hr; BOOL fNoRedraw = FALSE; HWND hwndParent; // if we don't have a client site, then there's not much to do. // if (!m_pClientSite) return S_OK; // get an InPlace site pointer. // if (!GetInPlaceSite()) { // if they want windowless support, then we want IOleInPlaceSiteWindowless // if (FCONTROLISWINDOWLESS(m_ObjectType)) m_pClientSite->QueryInterface(IID_IOleInPlaceSiteWindowless, (void **)&m_pInPlaceSiteWndless); // if we're not able to do windowless siting, then we'll just get an // IOleInPlaceSite pointer. // if (!m_pInPlaceSiteWndless) { hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite); RETURN_ON_FAILURE(hr); } } // now, we want an IOleInPlaceSiteEx pointer for windowless and flicker free // activation. if we're windowless, we've already got it, else we need to // try and get it // if (m_pInPlaceSiteWndless) { pIPSEx = (IOleInPlaceSiteEx *)m_pInPlaceSiteWndless; pIPSEx->AddRef(); } else m_pClientSite->QueryInterface(IID_IOleInPlaceSiteEx, (void **)&pIPSEx); // if we're not already active, go and do it. // if (!m_fInPlaceActive || !m_fInPlaceVisible) { OLEINPLACEFRAMEINFO InPlaceFrameInfo; RECT rcPos, rcClip; BOOL fJustSetPosition = m_fInPlaceActive; // if we have a windowless site, see if we can go in-place windowless // active // hr = S_FALSE; if (fJustSetPosition) hr = S_OK; else if (m_pInPlaceSiteWndless) { hr = m_pInPlaceSiteWndless->CanWindowlessActivate(); CLEANUP_ON_FAILURE(hr); // if they refused windowless, we'll try windowed // if (S_OK != hr) { ASSERT(m_pInPlaceSite == NULL, "In-place site is non-NULL. We're gonna leak."); RELEASE_OBJECT(m_pInPlaceSiteWndless); hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite); CLEANUP_ON_FAILURE(hr); } } // just try regular windowed in-place activation // if (hr != S_OK) { hr = m_pInPlaceSite->CanInPlaceActivate(); if (hr != S_OK) { hr = (FAILED(hr)) ? E_FAIL : hr; goto CleanUp; } } if (!fJustSetPosition) { // if we are here, then we have permission to go in-place active. // now, announce our intentions to actually go ahead and do this. // hr = (pIPSEx) ? pIPSEx->OnInPlaceActivateEx(&fNoRedraw, (m_pInPlaceSiteWndless) ? ACTIVATE_WINDOWLESS : 0) : m_pInPlaceSite->OnInPlaceActivate(); CLEANUP_ON_FAILURE(hr); // if we're here, we're ready to go in-place active. we just need // to set up some flags, and then create the window [if we have // one] // m_fInPlaceActive = TRUE; } // In VB4, the position could have been changed while we // were invisible, so if we were already InPlaceActive but not visible // we need to get our size. // REVIEW: Is this much of a performance hit? Is there a way to tell // we've been resized in this case? // we need to get some information about our location in the parent // window, as well as some information about the parent // InPlaceFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO); hr = GetInPlaceSite()->GetWindow(&hwndParent); if (SUCCEEDED(hr)) { #ifdef MDAC_BUILD #if 0 // hack fix for MDAC 8536 & 8738. // To be used if VB doesn't/can't fix the real bug(s); hwndParent (or it's parent) is not sized properly. // Unfortunately, this code also affects the hf grid. If we need to add a virtual function bool ResizeParentBeforeCreation() // to COleControl (it should return false) and to the de. if ( ResizeParentBeforeCreation() ) { SIZE parent_size = m_Size; if ( HWND grandparent = GetParent(hwndParent) ) { RECT grandparent_bounds; GetClientRect(grandparent,&grandparent_bounds); parent_size.cx = grandparent_bounds.right; parent_size.cy = grandparent_bounds.bottom; } if ( parent_size.cx > 0 && parent_size.cy > 0 ) { SetWindowPos(hwndParent,NULL,0,0,parent_size.cx,parent_size.cy,SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE); } } #endif #endif if(m_pInPlaceFrame) RELEASE_OBJECT(m_pInPlaceFrame); if(m_pInPlaceUIWindow) RELEASE_OBJECT(m_pInPlaceUIWindow); hr = GetInPlaceSite()->GetWindowContext(&m_pInPlaceFrame, &m_pInPlaceUIWindow, &rcPos, &rcClip, &InPlaceFrameInfo); } CLEANUP_ON_FAILURE(hr); // make sure we'll display ourselves in the correct location with the correct size // sizel.cx = rcPos.right - rcPos.left; sizel.cy = rcPos.bottom - rcPos.top; f = OnSetExtent(&sizel); if (f) m_Size = sizel; SetObjectRects(&rcPos, &rcClip); // finally, create our window if we have to! // if (!fJustSetPosition && !m_pInPlaceSiteWndless) { SetInPlaceParent(hwndParent); // create the window, and display it. die horribly if we couldnt' // if (!CreateInPlaceWindow(rcPos.left, rcPos.top, fNoRedraw)) { hr = E_FAIL; goto CleanUp; } // finally, tell the host of this // if (m_pClientSite) m_pClientSite->ShowObject(); } } // don't need this any more // RELEASE_OBJECT(pIPSEx); // if we're not inplace visible yet, do so now. // if (!m_fInPlaceVisible) SetInPlaceVisible(TRUE); // if we weren't asked to UIActivate, then we're done. // if (lVerb != OLEIVERB_PRIMARY && lVerb != OLEIVERB_UIACTIVATE) return S_OK; // if we're not already UI active, do sow now. // if (!m_fUIActive) { m_fUIActive = TRUE; // inform the container of our intent // GetInPlaceSite()->OnUIActivate(); // take the focus [which is what UI Activation is all about !] // SetFocus(TRUE); // set ourselves up in the host. // m_pInPlaceFrame->SetActiveObject((IOleInPlaceActiveObject *)this, NULL); if (m_pInPlaceUIWindow) m_pInPlaceUIWindow->SetActiveObject((IOleInPlaceActiveObject *)this, NULL); // we have to explicitly say we don't wany any border space. // m_pInPlaceFrame->SetBorderSpace(NULL); if (m_pInPlaceUIWindow) m_pInPlaceUIWindow->SetBorderSpace(NULL); } // be-de-be-de-be-de that's all folks! // return S_OK; CleanUp: // something catastrophic happened [or, at least something bad]. // die a horrible fiery mangled painful death. // QUICK_RELEASE(pIPSEx); m_fInPlaceActive = FALSE; return hr; } //=--------------------------------------------------------------------------= // COleControl::InPlaceDeactivate [IOleInPlaceObject] //=--------------------------------------------------------------------------= // Deactivates an active in-place object and discards the object's undo state. // // Output: // HRESULT - S_OK, E_UNEXPECTED // // Notes: // STDMETHODIMP COleControl::InPlaceDeactivate ( void ) { // if we're not in-place active yet, then this is easy. // if (!m_fInPlaceActive) return S_OK; // transition from UIActive back to active // if (m_fUIActive) UIDeactivate(); // tell the host we're going away // GetInPlaceSite()->OnInPlaceDeactivate(); m_fInPlaceActive = FALSE; m_fInPlaceVisible = FALSE; // if we have a window, tell it to go away. // if (m_hwnd) { ASSERT(!m_pInPlaceSiteWndless, "internal state really messed up"); DestroyWindow(m_hwnd); if (m_hwndReflect) { SetWindowLong(m_hwndReflect, GWL_USERDATA, 0); DestroyWindow(m_hwndReflect); m_hwndReflect = NULL; } } RELEASE_OBJECT(m_pInPlaceFrame); RELEASE_OBJECT(m_pInPlaceUIWindow); return S_OK; } //=--------------------------------------------------------------------------= // COleControl::UIDeactivate [IOleInPlaceObject] //=--------------------------------------------------------------------------= // transitions us from UI Active to merely being active [visible] for // a control, this doesn't mean all that much. // // Output: // HRESULT - S_OK, E_UNEXPECTED // // Notes: // STDMETHODIMP COleControl::UIDeactivate ( void ) { // if we're not UIActive, not much to do. // if (!m_fUIActive) return S_OK; m_fUIActive = FALSE; // notify frame windows, if appropriate, that we're no longer ui-active. // if (m_pInPlaceUIWindow) m_pInPlaceUIWindow->SetActiveObject(NULL, NULL); m_pInPlaceFrame->SetActiveObject(NULL, NULL); // we don't need to explicitly release the focus here since somebody // else grabbing the focus is what is likely to cause us to get lose it // GetInPlaceSite()->OnUIDeactivate(FALSE); return S_OK; } //=--------------------------------------------------------------------------= // COleControl::SetObjectRects [IOleInPlaceObject] //=--------------------------------------------------------------------------= // Indicates how much of the control is visible. // // Parameters: // LPCRECT - [in] position of the control. // LPCRECT - [in] clipping rectangle for the control. // // Output: // HRESULT - S_OK, E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED // // Notes: // STDMETHODIMP COleControl::SetObjectRects ( LPCRECT prcPos, LPCRECT prcClip ) { #ifdef DEBUG RECT rcDebug; POINT ptDebug; #endif BOOL fRemoveWindowRgn; // save out our current location. windowless controls want this more // that windowed ones do, but everybody can have it just in case // // VEGAS#25109: a-cmai 3/9/98 -- Update m_rcLocation prior to doing // work for windowed controls. This is because the SetWindowPos call // may reenter when the control resizes itself. SetExtent requires that // m_rcLocation contains the recent window location // m_rcLocation = *prcPos; // move our window to the new location and handle clipping. not applicable // for windowless controls, since the container will be responsible for all // clipping. // if (m_hwnd) { fRemoveWindowRgn = m_fUsingWindowRgn; if (prcClip) { // the container wants us to clip, so figure out if we really // need to // RECT rcIXect; if ( IntersectRect(&rcIXect, prcPos, prcClip) ) { if (!EqualRect(&rcIXect, prcPos)) { OffsetRect(&rcIXect, -(prcPos->left), -(prcPos->top)); SetWindowRgn(GetOuterWindow(), CreateRectRgnIndirect(&rcIXect), TRUE); m_fUsingWindowRgn = TRUE; fRemoveWindowRgn = FALSE; } } } if (fRemoveWindowRgn) { SetWindowRgn(GetOuterWindow(), NULL, TRUE); m_fUsingWindowRgn = FALSE; } RECT rc; POINT pt; pt.x = pt.y = 0; ClientToScreen(GetParent(GetOuterWindow()), &pt); GetWindowRect(GetOuterWindow(), &rc); OffsetRect(&rc, - pt.x, - pt.y); DWORD dwFlags = SWP_NOZORDER | SWP_NOACTIVATE; if (rc.left == prcPos->left && rc.top == prcPos->top) dwFlags |= SWP_NOMOVE; if ((rc.right - rc.left) == (prcPos->right - prcPos->left) && (rc.bottom - rc.top) == (prcPos->bottom - prcPos->top)) dwFlags |= SWP_NOSIZE; // We don't support zooming. Instead we resize the window // to the given size and redraw within the new size. // // Note: The OuterWindow is either the reflector or control window // SetWindowPos(GetOuterWindow(), NULL, prcPos->left, prcPos->top, prcPos->right - prcPos->left, prcPos->bottom - prcPos->top, dwFlags); #if DEBUG // Make sure we caused a size change // if (!(dwFlags & SWP_NOSIZE)) { ptDebug.x = ptDebug.y = 0; ClientToScreen(GetParent(GetOuterWindow()), &ptDebug); GetWindowRect(GetOuterWindow(), &rcDebug); OffsetRect(&rcDebug, - ptDebug.x, - ptDebug.y); // If these asserts get tripped that means the size changed between the SetWindowPos call and here // Note: SetWindowPos will generate WM_NCCALCSIZE, WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED along with // possible WM_NCPAINT, WM_PAINT and WM_SIZE. If in response to any of these messages we end up changing // the size, then we may have a problem. // if ((prcPos->right - prcPos->left) != (rcDebug.right - rcDebug.left)) OutputDebugString("Width not set to expected value"); if ((prcPos->bottom - prcPos->top) != (rcDebug.bottom - rcDebug.top)) OutputDebugString("Height not set to expected value"); } #endif // VEGAS#25109: a-cmai 3/9/98 -- Update m_rcLocation // after the call to SetWindowPos, since the window pos // and or size may have been altered by the control // GetWindowRect(GetOuterWindow(), &m_rcLocation); OffsetRect(&m_rcLocation, - pt.x, - pt.y); // No need to resize the window again if GetOuterWindow is the same // if (m_hwnd && GetOuterWindow() != m_hwnd) // We're position within the reflector window, so set position to 0, 0 // SetWindowPos(m_hwnd, 0, 0, 0, m_rcLocation.right - m_rcLocation.left, m_rcLocation.bottom - m_rcLocation.top, SWP_NOZORDER | SWP_NOACTIVATE); } return S_OK; } //=--------------------------------------------------------------------------= // COleControl::ReactivateAndUndo [IOleInPlaceObject] //=--------------------------------------------------------------------------= // Reactivates a previously deactivated object, undoing the last state of the object. // // Output: // HRESULT - S_OK, E_NOTUNDOABLE // // Notes: // STDMETHODIMP COleControl::ReactivateAndUndo ( void ) { return E_NOTIMPL; } //=--------------------------------------------------------------------------= // COleControl::OnWindowMessage [IOleInPlaceObjectWindowless] //=--------------------------------------------------------------------------= // this method lets the container dispatch a message to a windowless OLE // object. // // Parameters: // UINT - [in] the message // WPARAM - [in] the messages wparam // LPARAM - [in] duh. // LRESULT * - [out] the output value // // Output: // HRESULT - S_OK // // Notes: // - people should call m_pInPlaceSiteWndless->OnDefWindowMessage [control // writers should just call OcxDefWindowProc(msg, wparam, lparam)]; // STDMETHODIMP COleControl::OnWindowMessage ( UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *plResult ) { // little bit of pre-processing -- we need to handle some cases here // before passing the messages on // switch (msg) { // make sure our UI Activation correctly matches the focus // case WM_KILLFOCUS: case WM_SETFOCUS: // give the control site focus notification // if (m_fInPlaceActive && m_pControlSite) m_pControlSite->OnFocus(msg == WM_SETFOCUS); break; } // just pass it to the control's window proc. // *plResult = WindowProc(msg, wParam, lParam); return S_OK; } //=--------------------------------------------------------------------------= // COleControl::GetDropTarget [IOleInPlaceObjectWindowless] //=--------------------------------------------------------------------------= // this method returns a pointer to the objects IDropTarget interface. since // they do not have a window, windowless objects cannot register an IDropTarget // interface. // // Parameters: // IDropTarget ** - [out] // // Output: // HRESULT - S_OK, E_NOTIMPL // // Notes: // STDMETHODIMP COleControl::GetDropTarget ( IDropTarget **ppDropTarget ) { // OVERRIDE: if you want to do drag and drop and you're windowless, // override me. // return E_NOTIMPL; } //=--------------------------------------------------------------------------= // COleControl::TranslateAccelerator [IOleInPlaceActiveObject] //=--------------------------------------------------------------------------= // Processes menu accelerator-key messages from the container's message queue. // // Parameters: // LPMSG - [in] the message that has the special key in it. // // Output: // HRESULT - S_OK, S_FALSE, E_UNEXPECTED // // Notes: // STDMETHODIMP COleControl::TranslateAccelerator ( LPMSG pmsg ) { // see if we want it or not. // if (OnSpecialKey(pmsg)) return S_OK; // if not, then we want to forward it back to the site for further processing // if (m_pControlSite) return m_pControlSite->TranslateAccelerator(pmsg, _SpecialKeyState()); // we didn't want it. // return S_FALSE; } //=--------------------------------------------------------------------------= // COleControl::OnFrameWindowActivate [IOleInPlaceActiveObject] //=--------------------------------------------------------------------------= // Notifies the control when the container's top-level frame window is // activated or deactivated. // // Parameters: // BOOL - [in] state of containers top level window. // // Output: // HRESULT - S_OK // // Notes: // STDMETHODIMP COleControl::OnFrameWindowActivate ( BOOL fActivate ) { // OVERRIDE: override this routine if you want floating toolbars, // toolboxes, etc. // return S_OK; } //=--------------------------------------------------------------------------= // COleControl::OnDocWindowActivate [IOleInPlaceActiveObject] //=--------------------------------------------------------------------------= // Notifies the active control when the container's document window is // activated or deactivated. // // Parameters: // BOOL - state of mdi child window. // // Output: // HRESULT - S_OK // // Notes: // STDMETHODIMP COleControl::OnDocWindowActivate ( BOOL fActivate ) { // OVERRIDE: override this routine if you want floating toolbars, // toolboxes, etc. // if we're supposed to activate and we're UI active, then just go and // default to clearing out the toolbar space. // if (m_fUIActive && fActivate) m_pInPlaceFrame->SetBorderSpace(NULL); return S_OK; } //=--------------------------------------------------------------------------= // COleControl::ResizeBorder [IOleInPlaceActiveObject] //=--------------------------------------------------------------------------= // Alerts the control that it needs to resize its border space. // // Parameters: // LPCRECT - [in] new outer rectangle for border space // IOleInPlaceUIWindow * - [in] the document or frame who's border has changed // BOOL - [in] true if it was the fram window taht called. // // Output: // HRESULT - S_OK // // Notes: // STDMETHODIMP COleControl::ResizeBorder ( LPCRECT prcBorder, IOleInPlaceUIWindow *pInPlaceUIWindow, BOOL fFrame ) { // this is largely uninteresting to us, since we have no border. // return S_OK; } //=--------------------------------------------------------------------------= // COleControl::EnableModeless [IOleInPlaceActiveObject] //=--------------------------------------------------------------------------= // Enables or disables modeless dialog boxes when the container creates or // destroys a modal dialog box. // // Parameters: // BOOL - [in] enable or disable modeless dialogs. // // Output: // HRESULT - S_OK // // Notes: // STDMETHODIMP COleControl::EnableModeless ( BOOL fEnable ) { // phenomenally uninteresting // return S_OK; } //=--------------------------------------------------------------------------= // COleControl::GetClassInfo [IProvideClassInfo] //=--------------------------------------------------------------------------= // returns the TypeInfo for the control's coclass. // // Parameters: // ITypeInfo ** - [out] // // Output: // HRESULT // // Notes: // STDMETHODIMP COleControl::GetClassInfo ( ITypeInfo **ppTypeInfo ) { ITypeLib *pTypeLib; HRESULT hr; CHECK_POINTER(ppTypeInfo); *ppTypeInfo = NULL; // go and get our type library. // CONSIDER: - go to the same sorta scheme that we use for TypeInfo caching. // CONSIDER: - consider trying to register our typelib if this fails. // ENTERCRITICALSECTION1(&g_CriticalSection); // This is for g_lcidlocale. hr = LoadRegTypeLib(*g_pLibid, (USHORT)VERSIONOFOBJECT(m_ObjectType), (USHORT)VERSIONMINOROFOBJECT(m_ObjectType), LANGIDFROMLCID(g_lcidLocale), &pTypeLib); LEAVECRITICALSECTION1(&g_CriticalSection); RETURN_ON_FAILURE(hr); // got the typelib. get typeinfo for our coclass. // hr = pTypeLib->GetTypeInfoOfGuid((REFIID)CLSIDOFOBJECT(m_ObjectType), ppTypeInfo); pTypeLib->Release(); RETURN_ON_FAILURE(hr); return S_OK; } //=--------------------------------------------------------------------------= // COleControl::ViewChange [callable] //=--------------------------------------------------------------------------= // called whenever the view of the object has changed. // // Notes: // void COleControl::ViewChanged ( void ) { // send the view change notification to anybody listening. // if (m_pViewAdviseSink) { m_pViewAdviseSink->OnViewChange(DVASPECT_CONTENT, -1); // if they only asked to be advised once, kill the connection // if (m_fViewAdviseOnlyOnce) SetAdvise(DVASPECT_CONTENT, 0, NULL); } } //=--------------------------------------------------------------------------= // COleControl::SetInPlaceVisible [helper] //=--------------------------------------------------------------------------= // controls the visibility of the control window. // // Parameters: // BOOL - TRUE shows FALSE hides. // // Notes: // void COleControl::SetInPlaceVisible ( BOOL fShow ) { BOOL fVisible; m_fInPlaceVisible = fShow; // don't do anything if we don't have a window. otherwise, set it // if (m_hwnd) { fVisible = ((GetWindowLong(GetOuterWindow(), GWL_STYLE) & WS_VISIBLE) != 0); if (fVisible && !fShow) ShowWindow(GetOuterWindow(), SW_HIDE); else if (!fVisible && fShow) ShowWindow(GetOuterWindow(), SW_SHOWNA); } } //=--------------------------------------------------------------------------= // COleControl::AmbientPropertyChanged [overridable] //=--------------------------------------------------------------------------= // a method that derived controls can override to do whatever they want. // we don't particularily care about this event. // // Parameters: // DISPID - [in] dispid of prop that changed. // // Notes: // void COleControl::AmbientPropertyChanged ( DISPID dispid ) { // do nothing } //=--------------------------------------------------------------------------= // COleControl::DoCustomVerb [overridable] //=--------------------------------------------------------------------------= // we were asked to execute a verb we don't know about right away. see if // it's a verb that the dervied-control defined. // // Parameters: // LONG - [in] the verb. // // Output: // HRESULT - S_OK, OLEOBJ_S_INVALIDVERB // // Notes: // HRESULT COleControl::DoCustomVerb ( LONG lVerb ) { return OLEOBJ_S_INVALIDVERB; } //=--------------------------------------------------------------------------= // COleControl::OnSetExtent [overridable] //=--------------------------------------------------------------------------= // let the user do something in the resize, if they care. // // Parameters: // SIZEL * - [in] new values. // // Output: // BOOL - FALSE means keep current size // // Notes: // BOOL COleControl::OnSetExtent ( SIZEL *pSizeL ) { return TRUE; } //=--------------------------------------------------------------------------= // COleControl::OnSpecialKey [overridable] //=--------------------------------------------------------------------------= // allows controls to handle special keys such as arrows, CTRL+, etc ... // // Parameters: // LPMSG - [in] the special key msg. // // Output: // BOOL - TRUE we processed it, FALSE we didn't. // // Notes: // BOOL COleControl::OnSpecialKey ( LPMSG pmsg ) { // do nothing. // return FALSE; } //=--------------------------------------------------------------------------= // COleControl::ModalDialog [callable, utility] //=--------------------------------------------------------------------------= // should be called when the control is about to show and hide a modal dialog. // // Parameters: // BOOL - [in] true means showing a modal dialog, false means done // // Notes: // void COleControl::ModalDialog ( BOOL fShow ) { // notify the container of our intention to show a modal dialog... // if (m_pInPlaceFrame) m_pInPlaceFrame->EnableModeless(!fShow); } //=--------------------------------------------------------------------------= // COleControl::BeforeDestroyWindow [overridable] //=--------------------------------------------------------------------------= // called just before we destroy a window. gives the user the opportunity to // save information out, especially if they're a subclassed control, and this // is an interesting thing to do. // // Notes: // void COleControl::BeforeDestroyWindow ( void ) { // fweeee } //=--------------------------------------------------------------------------= // COleControl::OnSetClientSite [overrideable] //=--------------------------------------------------------------------------= // controls should implement this if they hold on to anything off the site. // this is important to correctly support aggregation. they must free up // everything they hold on to, and if m_pClientSite is not NULL, then they // can re-establish things as they wish. // // Parameters: // none // // Output: // HRESULT // // Notes: // HRESULT COleControl::OnSetClientSite ( void ) { // by default, the framework frees up everything in SetClientSite // return S_OK; }