/***************************************************************************
* DSOFCONTROL.CPP
*
* CDsoFramerControl: The Base Control
*
* Copyright �1999-2004; Microsoft Corporation. All rights reserved.
* Written by Microsoft Developer Support Office Integration (PSS DSOI)
*
* This code is provided via KB 311765 as a sample. It is not a formal
* product and has not been tested with all containers or servers. Use it
* for educational purposes only. See the EULA.TXT file included in the
* KB download for full terms of use and restrictions.
*
* THIS CODE 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.
*
***************************************************************************/
#include "dsoframer.h"
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl - The Main Control Class
//
// Serves as a base for the ActiveX Document site object which will do
// the actual embedding.
//
CDsoFramerControl::CDsoFramerControl(LPUNKNOWN punk)
{
ODS("CDsoFramerControl::CDsoFramerControl\n");
m_pOuterUnknown = ((punk) ? punk : (IUnknown*)&m_xInternalUnknown);
}
CDsoFramerControl::~CDsoFramerControl(void)
{
ODS("CDsoFramerControl::~CDsoFramerControl\n");
SAFE_RELEASE_INTERFACE(m_ptiDispType);
SAFE_RELEASE_INTERFACE(m_pClientSite);
SAFE_RELEASE_INTERFACE(m_pControlSite);
SAFE_RELEASE_INTERFACE(m_pInPlaceSite);
SAFE_RELEASE_INTERFACE(m_pInPlaceFrame);
SAFE_RELEASE_INTERFACE(m_pInPlaceUIWindow);
SAFE_RELEASE_INTERFACE(m_pViewAdviseSink);
SAFE_RELEASE_INTERFACE(m_pOleAdviseHolder);
SAFE_RELEASE_INTERFACE(m_pDataAdviseHolder);
SAFE_RELEASE_INTERFACE(m_dispEvents);
SAFE_RELEASE_INTERFACE(m_pOleStorage);
SAFE_FREESTRING(m_pwszHostName);
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::InitializeNewInstance
//
// Sets up the inital state for the control. Any other member variable
// not set here will be NULL/FALSE thanks to zero-init in MemAlloc.
//
STDMETHODIMP CDsoFramerControl::InitializeNewInstance()
{
m_clrBorderColor = 0x80000010; // System Button Shadow Color
m_clrBackColor = 0x80000005; // System Window Background Color
m_clrForeColor = 0x80000008; // System Window Text Color
m_clrTBarColor = 0x8000000D; // System Highlight Color
m_clrTBarTextColor = 0x8000000E; // System Highlight Text Color
m_fBorderStyle = dsoBorderFlat;
m_fShowTitlebar = TRUE;
m_fShowToolbars = TRUE;
m_fShowMenuBar = TRUE;
m_wFileMenuFlags = 0xFFFF; // All items are "enabled" by default
m_Size.cx = 240;
m_Size.cy = 240;
return S_OK;
}
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::InPlaceActivate
//
// Does all the work in-place activating and/or ui activating the
// control when asked to do so. Sets up the main control window, the
// needed interfaces, and (if not in design) subclasses the main top-level
// window we can monitor messages that must be forwarded to an ip active
// DocObject when we have one loaded.
//
STDMETHODIMP CDsoFramerControl::InPlaceActivate(LONG lVerb)
{
HRESULT hr;
SIZEL sizel;
TRACE1("CDsoFramerControl::InPlaceActivate - %d\n", lVerb);
// 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 (NULL == m_pInPlaceSite)
{
hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite);
RETURN_ON_FAILURE(hr);
}
// if we're not already active, go and do it.
if (!m_fInPlaceActive)
{
OLEINPLACEFRAMEINFO InPlaceFrameInfo;
RECT rcPos, rcClip;
hr = m_pInPlaceSite->CanInPlaceActivate();
if (hr != S_OK){ if (!FAILED(hr)) hr = E_FAIL; goto cleanup;}
// 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 = m_pInPlaceSite->OnInPlaceActivate();
GOTO_ON_FAILURE(hr, cleanup);
// 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;
// we need to get some information about our location in the parent
// window, as well as some information about the parent
hr = m_pInPlaceSite->GetWindow(&m_hwndParent);
if (FAILED(hr) || !IsWindow(m_hwndParent))
{
hr = OLE_E_INVALIDHWND;
goto cleanup;
}
InPlaceFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
hr = m_pInPlaceSite->GetWindowContext(&m_pInPlaceFrame, &m_pInPlaceUIWindow, &rcPos, &rcClip, &InPlaceFrameInfo);
GOTO_ON_FAILURE(hr, cleanup);
// 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;
m_Size = sizel;
m_xOleInplaceObject.SetObjectRects(&rcPos, &rcClip);
// finally, create our window if we have to!
if (NULL == m_hwnd)
{
WNDCLASS wndclass;
EnterCriticalSection(&v_csecThreadSynch);
// if class info has not yet been registered, need to do that now...
if (GetClassInfo(v_hModule, "DSOFramerOCXWnd", &wndclass) == 0)
{
memset(&wndclass, 0, sizeof(WNDCLASS));
wndclass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
wndclass.lpfnWndProc = CDsoFramerControl::ControlWindowProc;
wndclass.hInstance = v_hModule;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.lpszClassName = "DSOFramerOCXWnd";
RegisterClass(&wndclass);
}
// create the window with the extent size and position...
m_hwnd = CreateWindowEx(0, "DSOFramerOCXWnd", NULL,
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
rcPos.left, rcPos.top, m_Size.cx, m_Size.cy,
m_hwndParent, NULL, v_hModule, NULL);
if (m_hwnd) SetWindowLong(m_hwnd, GWL_USERDATA, (LONG)this);
LeaveCriticalSection(&v_csecThreadSynch);
if (!m_hwnd) {hr = E_FAIL; goto cleanup;}
}
// finally, tell the host of this
m_pClientSite->ShowObject();
}
// if we're not inplace visible yet, do so now.
if (!m_fInPlaceVisible)
SetInPlaceVisible(TRUE);
// if we were asked to UIActivate, and we currently are not, do so!
if ((lVerb == OLEIVERB_PRIMARY ||
lVerb == OLEIVERB_UIACTIVATE) && (!m_fUIActive))
{
// It is not typical to UI activate ocx during design mode, but if it happens and host
// has not customized the hook policy, let's switch to delay set so that we don't
// accidently hook the VS/VB IDE designer window.
if (FRunningInDesignMode() && (m_lHookPolicy == 0))
m_lHookPolicy = dsoSetOnFirstOpen;
// if we don't have it already, hook top-level parent window when we go
// ui active; this is needed to track WM_ACTIVATEAPP and other critical messages
// needed by ole docobjs....
if ((m_pHookManager == NULL) && FUseFrameHook() && !FDelayFrameHookSet())
{
m_pHookManager = CDsoFrameHookManager::RegisterFramerControl(m_hwndParent, m_hwnd);
if (!m_pHookManager)
{
ODS(" ** UIActivate FAILED (DSO_E_FRAMEHOOKFAILED)\n");
return ProvideErrorInfo(DSO_E_FRAMEHOOKFAILED);
}
}
// Now UI activate the control for the host. This implies taking focus and
// setting up the control as the current active object...
hr = UIActivate(FALSE);
}
// Setup drop file support (but only when there is no current embedding)...
if (m_pDocObjFrame == NULL)
EnableDropFile(TRUE);
return S_OK; // be-de-be-de-be-de that's all folks!
cleanup:
// something catastrophic happened [or, at least somethi
评论0