4313 lines
		
	
	
		
			144 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			4313 lines
		
	
	
		
			144 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/***************************************************************************
 | 
						|
 * 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 something bad].
 | 
						|
 // die a horrible fiery mangled painful death...
 | 
						|
	TRACE1(" *** InPlaceActivate FAILED (hr=0x%X) ***\n", hr);
 | 
						|
    m_fInPlaceActive = FALSE;
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::UIActivate
 | 
						|
//
 | 
						|
//  Make sure our control is UI Active and set as ActiveObject for host.
 | 
						|
//
 | 
						|
STDMETHODIMP CDsoFramerControl::UIActivate(BOOL fForceUIActive)
 | 
						|
{
 | 
						|
    HRESULT hr = S_FALSE;
 | 
						|
	TRACE1("CDsoFramerControl::UIActivate(fForceUIActive=%d)\n", fForceUIActive);
 | 
						|
 | 
						|
 // We can't do anything if we aren't inplace active and visible!
 | 
						|
    if (!(m_fInPlaceActive) || !(m_fInPlaceVisible))
 | 
						|
        return E_UNEXPECTED;
 | 
						|
 | 
						|
 // If we are not already UI active or are being asked to force it, do the call
 | 
						|
    if ((!(m_fUIActive) || (fForceUIActive)) && (m_pInPlaceSite))
 | 
						|
    {
 | 
						|
        m_fUIActive = TRUE;
 | 
						|
 | 
						|
     // inform the container of our intent
 | 
						|
        hr = m_pInPlaceSite->OnUIActivate();
 | 
						|
 | 
						|
        if (SUCCEEDED(hr) || (fForceUIActive))
 | 
						|
        {
 | 
						|
         // take the focus  [which is what UI Activation is all about !]
 | 
						|
	        SetFocus(m_hwnd);
 | 
						|
 | 
						|
         // set ourselves up in the host.
 | 
						|
		    if (m_pInPlaceFrame)
 | 
						|
	            m_pInPlaceFrame->SetActiveObject((IOleInPlaceActiveObject*)&m_xOleInplaceActiveObject, NULL);
 | 
						|
 | 
						|
            if (m_pInPlaceUIWindow)
 | 
						|
                m_pInPlaceUIWindow->SetActiveObject((IOleInPlaceActiveObject*)&m_xOleInplaceActiveObject, NULL);
 | 
						|
 | 
						|
         // we have to explicitly say we don't wany any border space.
 | 
						|
		    if (m_pInPlaceFrame)
 | 
						|
			    m_pInPlaceFrame->SetBorderSpace(NULL);
 | 
						|
			    
 | 
						|
            if (m_pInPlaceUIWindow)
 | 
						|
                m_pInPlaceUIWindow->SetBorderSpace(NULL);
 | 
						|
 | 
						|
         // Ensure docobj component state is active as well...
 | 
						|
            if (!m_fComponentActive)
 | 
						|
            {
 | 
						|
             // Tell manager we are the active component now...
 | 
						|
                if (m_pHookManager) m_pHookManager->SetActiveComponent(m_hwnd);
 | 
						|
                else OnComponentActivationChange(TRUE);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::SetInPlaceVisible
 | 
						|
//
 | 
						|
//  Make sure our control is visible or not (does not actually take ui
 | 
						|
//  focus, that should be done in InPlaceActivate).
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::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 = IsWindowVisible(m_hwnd);
 | 
						|
 | 
						|
        if (fVisible && !fShow)
 | 
						|
			ShowWindow(m_hwnd, SW_HIDE);
 | 
						|
        else if (!fVisible && fShow)
 | 
						|
			ShowWindow(m_hwnd, SW_SHOWNA);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnDraw
 | 
						|
//
 | 
						|
//  Drawing is largely limited to border and titlebar, except when in
 | 
						|
//  design mode. We don't do any background painting to avoid paint problems
 | 
						|
//  when we have an ui active DocObject. It should do any painting for us.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnDraw(DWORD dvAspect, HDC hdcDraw, LPRECT prcBounds, LPRECT prcWBounds, HDC hicTargetDev, BOOL fOptimize)
 | 
						|
{
 | 
						|
	COLORREF clrBackground, clrForeground, clrBorder, clrT;
 | 
						|
	HBRUSH   hbshBackground, hbshBorder;
 | 
						|
	HFONT    hfontText, hfontOld;
 | 
						|
	HPALETTE hpal, hpalOld;
 | 
						|
    LOGFONT  lfText = {-11,0,0,0,FW_NORMAL,0,0,0,0,0,0,0,FF_SWISS, "Tahoma"};
 | 
						|
	RECT     rc, rcT;
 | 
						|
	int      iTxtMode, iMapMode;
 | 
						|
 | 
						|
 // Copy out the bounding rect...
 | 
						|
	CopyRect(&rc, prcBounds);
 | 
						|
 | 
						|
 // On 256 color systems, we may need a palette...
 | 
						|
    if ((GetDeviceCaps(hdcDraw, RASTERCAPS) & RC_PALETTE) &&
 | 
						|
		((GetDeviceCaps(hdcDraw, BITSPIXEL) * GetDeviceCaps(hdcDraw, PLANES)) == 8))
 | 
						|
    {
 | 
						|
        hpal = CreateHalftonePalette(hdcDraw);
 | 
						|
		hpalOld = SelectPalette(hdcDraw, hpal, TRUE);
 | 
						|
		RealizePalette(hdcDraw);
 | 
						|
    }
 | 
						|
	else hpal = NULL;
 | 
						|
 | 
						|
 // Translate the OLE_COLOR values to a matching COLORREF in palette...
 | 
						|
	OleTranslateColor(m_clrBackColor,   hpal, &clrBackground);
 | 
						|
	OleTranslateColor(m_clrForeColor,   hpal, &clrForeground);
 | 
						|
	OleTranslateColor(m_clrBorderColor, hpal, &clrBorder);
 | 
						|
 | 
						|
 // Create the resources we need for drawing and setting up the DC...
 | 
						|
	hbshBackground = CreateSolidBrush(clrBackground);
 | 
						|
	hbshBorder     = CreateSolidBrush(clrBorder);
 | 
						|
 | 
						|
	hfontText = CreateFontIndirect(&lfText);
 | 
						|
	hfontOld = (HFONT)SelectObject(hdcDraw, hfontText);
 | 
						|
	iTxtMode = SetBkMode(hdcDraw, TRANSPARENT);
 | 
						|
    iMapMode = SetMapMode(hdcDraw, MM_TEXT);
 | 
						|
 | 
						|
 // Based on the choosen border style, draw the border and deflate the
 | 
						|
 // drawing rect accordingly...
 | 
						|
	switch (m_fBorderStyle)
 | 
						|
	{
 | 
						|
	case 1:
 | 
						|
		{
 | 
						|
		HBRUSH hbT = GetSysColorBrush(COLOR_BTNFACE);
 | 
						|
		FrameRect(hdcDraw, &rc, hbshBorder);	InflateRect(&rc, -1, -1);
 | 
						|
		FrameRect(hdcDraw, &rc, hbT);			InflateRect(&rc, -1, -1);
 | 
						|
		FrameRect(hdcDraw, &rc, hbshBorder);	InflateRect(&rc, -1, -1);
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case 2:
 | 
						|
		DrawEdge(hdcDraw, &rc, EDGE_SUNKEN, BF_RECT);	
 | 
						|
		InflateRect(&rc, -2, -2);
 | 
						|
		break;
 | 
						|
 | 
						|
	case 3:
 | 
						|
		DrawEdge(hdcDraw, &rc, BDR_SUNKENOUTER, BF_RECT);
 | 
						|
		InflateRect(&rc, -1, -1);
 | 
						|
		break;
 | 
						|
 | 
						|
	//default: no border...
 | 
						|
	}
 | 
						|
 | 
						|
 // Draw the titlebar if visible...
 | 
						|
	if (m_fShowTitlebar)
 | 
						|
	{
 | 
						|
		COLORREF clrTitlebar, clrTitlebarText;
 | 
						|
		HBRUSH   hbshTitlebar, hbshT;
 | 
						|
        LPWSTR   pwszDCaption = NULL;
 | 
						|
        LPWSTR   pwszROCaption = NULL;
 | 
						|
        LPWSTR   pwszCaption = ((m_bstrCustomCaption) ? 
 | 
						|
					m_bstrCustomCaption : L"KB311765: Office Framer Control Sample");
 | 
						|
 | 
						|
		CopyRect(&rcT, &rc);
 | 
						|
		rcT.bottom = rcT.top + 21;
 | 
						|
 | 
						|
		OleTranslateColor(m_clrTBarColor,     hpal, &clrTitlebar);
 | 
						|
		OleTranslateColor(m_clrTBarTextColor, hpal, &clrTitlebarText);
 | 
						|
 | 
						|
		hbshTitlebar = CreateSolidBrush(clrTitlebar);
 | 
						|
		FillRect(hdcDraw, &rcT, hbshTitlebar);
 | 
						|
 | 
						|
		DrawIconEx(hdcDraw, rcT.left+2, rcT.top+2, v_icoOffDocIcon, 16, 16, 0, NULL, DI_NORMAL);
 | 
						|
 | 
						|
		clrT = SetTextColor(hdcDraw, clrTitlebarText);
 | 
						|
		rcT.left += 22;
 | 
						|
 | 
						|
     // If we have an embedded object, check to see if it is an open doc and
 | 
						|
     // append the name to the titlebar. Also append "Read-Only" string if file
 | 
						|
     // was open in read-only mode. 
 | 
						|
        if (m_pDocObjFrame)
 | 
						|
        {
 | 
						|
            if ((pwszDCaption = (LPWSTR)m_pDocObjFrame->GetSourceDocName()) != NULL)
 | 
						|
            {
 | 
						|
                LPCWSTR pwszCat[2] = {L" - ", pwszDCaption};
 | 
						|
                pwszDCaption = DsoCopyStringCatEx(pwszCaption, 2, pwszCat);
 | 
						|
                pwszCaption = pwszDCaption;
 | 
						|
            }
 | 
						|
 | 
						|
            if (m_pDocObjFrame->IsReadOnly())
 | 
						|
            {
 | 
						|
                pwszROCaption = DsoCopyStringCat(pwszCaption, L" (Read-Only)");
 | 
						|
                pwszCaption = pwszROCaption;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 
 | 
						|
	 // Draw out the custom titlebar caption in Unicode if on NT/XP OS, since
 | 
						|
	 // a custom caption may have non-ANSI characters...
 | 
						|
        FDrawText(hdcDraw, pwszCaption, &rcT, DT_VCENTER|DT_SINGLELINE);
 | 
						|
 | 
						|
     // Cleanup temp strings...
 | 
						|
        if (pwszROCaption) DsoMemFree(pwszROCaption);
 | 
						|
        if (pwszDCaption) DsoMemFree(pwszDCaption);
 | 
						|
 | 
						|
		CopyRect(&rcT, &rc);
 | 
						|
		rcT.bottom = rcT.top + 21;
 | 
						|
		rcT.top = rcT.bottom - 1;
 | 
						|
 | 
						|
		hbshT = GetSysColorBrush(COLOR_BTNSHADOW);
 | 
						|
		FillRect(hdcDraw, &rcT, hbshT);
 | 
						|
 | 
						|
		SetTextColor(hdcDraw, clrT);
 | 
						|
		DeleteObject(hbshTitlebar);
 | 
						|
	}
 | 
						|
 | 
						|
 // Draw menu bar if visible...
 | 
						|
    if (m_fShowMenuBar)
 | 
						|
    {
 | 
						|
        GetSizeRectForMenuBar(prcBounds, &rcT);
 | 
						|
		FillRect(hdcDraw, &rcT, GetSysColorBrush(COLOR_BTNFACE));
 | 
						|
 | 
						|
     // When in design mode, we just draw placeholder...
 | 
						|
        if (FRunningInDesignMode())
 | 
						|
        {
 | 
						|
		    clrT = SetTextColor(hdcDraw, GetSysColor(COLOR_BTNSHADOW));
 | 
						|
		    DrawText(hdcDraw, "Menu Bar", -1, &rcT, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
 | 
						|
		    SetTextColor(hdcDraw, clrT);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            HMENU hCurMenu;
 | 
						|
            CHAR szbuf[DSO_MAX_MENUNAME_LENGTH];
 | 
						|
            UINT i, yTop, yBottom, xLast, xNext;
 | 
						|
            SIZE ptMItem; RECT rcMDraw;
 | 
						|
            BOOL fSelected;
 | 
						|
            DWORD dwDTFlags = (DT_SINGLELINE | DT_VCENTER);
 | 
						|
 | 
						|
         // Get the current menu and setup to draw the number of items in it...
 | 
						|
            if (hCurMenu = GetActivePopupMenu())
 | 
						|
            {
 | 
						|
                yTop = rcT.top + 3; yBottom = rcT.bottom - 3; xLast = rcT.left + 2;
 | 
						|
                if (hCurMenu == m_hmenuFilePopup)
 | 
						|
                    { m_cMenuItems = 1; }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    if ((m_cMenuItems = (USHORT)GetMenuItemCount(hCurMenu)) > DSO_MAX_MENUITEMS)
 | 
						|
                        m_cMenuItems = DSO_MAX_MENUITEMS;
 | 
						|
                }
 | 
						|
 | 
						|
             // If we are on an OS that supports it, hide the prefix when we are not UI active
 | 
						|
             // or if the host has disabled menu accelerators for this instance...
 | 
						|
                if (v_fWindows2KPlus && (!(m_fUIActive) || (m_fDisableMenuAccel)))
 | 
						|
                    dwDTFlags |= DT_HIDEPREFIX;
 | 
						|
 | 
						|
             // For each item in the menu, get the menu name and draw it to the 
 | 
						|
             // menu bar. We need to calculate the size taken by the font used and
 | 
						|
             // store the information in an array used by mouse move handler to 
 | 
						|
             // determine which menu item the user is over...
 | 
						|
				for (i = 0; i < m_cMenuItems; i++)
 | 
						|
				{
 | 
						|
					szbuf[0] = '\0';
 | 
						|
                    if (i == 0) lstrcpy(szbuf, "&File");
 | 
						|
                    else GetMenuString(hCurMenu, i, szbuf, DSO_MAX_MENUNAME_LENGTH, MF_BYPOSITION);
 | 
						|
 | 
						|
                    GetTextExtentPoint32(hdcDraw, szbuf, lstrlen(szbuf), &ptMItem);
 | 
						|
                    xNext = (xLast + ptMItem.cx + 2);
 | 
						|
                    if (xNext > (UINT)(rcT.right)){ m_cMenuItems = (USHORT)i; break; }
 | 
						|
                    SetRect(&rcMDraw, xLast, yTop, xNext, yBottom);
 | 
						|
 | 
						|
                    if (fOptimize)
 | 
						|
						CopyRect(&m_rgrcMenuItems[i], &rcMDraw);
 | 
						|
 | 
						|
                 // If user is over this particular item, we draw it as selected...
 | 
						|
                    fSelected = ((m_wSelMenuItem) && (i == (UINT)(m_wSelMenuItem - 1)));
 | 
						|
                    if (fSelected)
 | 
						|
                    {
 | 
						|
						FillRect(hdcDraw, &rcMDraw, GetSysColorBrush(COLOR_HIGHLIGHT));
 | 
						|
						clrT = SetTextColor(hdcDraw, GetSysColor(COLOR_HIGHLIGHTTEXT));
 | 
						|
                    }
 | 
						|
                    rcMDraw.left += 4;
 | 
						|
                    DrawText(hdcDraw, szbuf, lstrlen(szbuf), &rcMDraw, dwDTFlags);
 | 
						|
                    
 | 
						|
					if (fSelected)
 | 
						|
						SetTextColor(hdcDraw, clrT);
 | 
						|
 | 
						|
                    xLast = xNext + 2;
 | 
						|
				}
 | 
						|
            }
 | 
						|
        }
 | 
						|
		rcT.top = rcT.bottom - 1; // Draw a line to separate menu from workspace...
 | 
						|
		FillRect(hdcDraw, &rcT, GetSysColorBrush(COLOR_BTNSHADOW));
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 // Fill in the background (but only if there is no active object)...
 | 
						|
	if (!m_pDocObjFrame)
 | 
						|
	{
 | 
						|
		GetSizeRectForDocument(prcBounds, &rcT);
 | 
						|
		FillRect(hdcDraw, &rcT, hbshBackground);
 | 
						|
 | 
						|
     // When in design mode, we do a little extra stuff to help the 
 | 
						|
     // developer visualize some of the control settings (toolbars,
 | 
						|
     // foreground color, etc.)...
 | 
						|
        if (FRunningInDesignMode())
 | 
						|
        {
 | 
						|
		    if (m_fShowToolbars)
 | 
						|
		    {
 | 
						|
			    rcT.bottom = rcT.top + 25;
 | 
						|
			    FillRect(hdcDraw, &rcT, GetSysColorBrush(COLOR_BTNFACE));
 | 
						|
			    clrT = SetTextColor(hdcDraw, GetSysColor(COLOR_BTNSHADOW));
 | 
						|
			    DrawText(hdcDraw, "Toolbar Space", -1, &rcT, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
 | 
						|
			    SetTextColor(hdcDraw, clrT);
 | 
						|
 | 
						|
		        GetSizeRectForDocument(prcBounds, &rcT);
 | 
						|
			    rcT.top = rcT.top + 25;
 | 
						|
		    }
 | 
						|
 | 
						|
		    clrT = SetTextColor(hdcDraw, GetSysColor(COLOR_BTNSHADOW));
 | 
						|
		    DrawText(hdcDraw, "ActiveX Document Object", -1, &rcT, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
 | 
						|
		    SetTextColor(hdcDraw, clrT);
 | 
						|
        }
 | 
						|
	}
 | 
						|
	else if ((m_pDocObjFrame) && (!m_fAppActive || !m_fComponentActive) && (FDrawBitmapOnAppDeactive() || FIPDeactivateOnCompChange()))
 | 
						|
	{
 | 
						|
	 // In the case we have more than one component, and this component is
 | 
						|
	 // has an object but is not ui active we draw a bitmap representation
 | 
						|
	 // of the obect to fill the area. This gives the user a sense the object
 | 
						|
	 // is there but in background, and can click to reactivate...
 | 
						|
		GetSizeRectForDocument(prcBounds, &rcT);
 | 
						|
 | 
						|
		if (m_hbmDeactive)
 | 
						|
		{
 | 
						|
			HDC hdcT = CreateCompatibleDC(hdcDraw);
 | 
						|
			HBITMAP bmpOld = (HBITMAP)SelectObject(hdcT, m_hbmDeactive);
 | 
						|
			BITMAP bm;
 | 
						|
 | 
						|
			if (GetObject(m_hbmDeactive, sizeof(BITMAP), &bm))
 | 
						|
			{
 | 
						|
				StretchBlt(hdcDraw, rcT.left, rcT.top, 
 | 
						|
					(rcT.right - rcT.left), (rcT.bottom - rcT.top),
 | 
						|
					 hdcT, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				BitBlt(hdcDraw, rcT.left, rcT.top, 
 | 
						|
					(rcT.right - rcT.left), (rcT.bottom - rcT.top), hdcT, 0,0, SRCCOPY);
 | 
						|
			}
 | 
						|
 | 
						|
			SelectObject(hdcT, bmpOld);
 | 
						|
			DeleteDC(hdcT);
 | 
						|
		}
 | 
						|
		else if (!m_fInDocumentLoad)
 | 
						|
		{
 | 
						|
			FillRect(hdcDraw, &rcT, hbshBackground);
 | 
						|
			rcT.top = ((rc.bottom - rc.top) / 2);
 | 
						|
			clrT = SetTextColor(hdcDraw, clrForeground);
 | 
						|
			DrawText(hdcDraw, "Unable to display inactive document. Click here to reactivate the object.", -1, &rcT, DT_WORDBREAK | DT_CENTER);
 | 
						|
			SetTextColor(hdcDraw, clrT);
 | 
						|
		}
 | 
						|
	} // else The docobj draws the rest...
 | 
						|
 | 
						|
 // Cleanup the hDC as required...
 | 
						|
	DeleteObject(hbshBackground);
 | 
						|
	DeleteObject(hbshBorder);
 | 
						|
 | 
						|
	SelectObject(hdcDraw, hfontOld);
 | 
						|
	DeleteObject(hfontText);
 | 
						|
 | 
						|
	if (hpal)
 | 
						|
	{
 | 
						|
		SelectPalette(hdcDraw, hpalOld, TRUE);
 | 
						|
		DeleteObject(hpal);
 | 
						|
	}
 | 
						|
 | 
						|
	SetBkMode(hdcDraw, iTxtMode);
 | 
						|
    SetMapMode(hdcDraw, iMapMode);
 | 
						|
	return;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnDestroyWindow
 | 
						|
//
 | 
						|
//  When the window closes make sure the object closes and release the
 | 
						|
//  subclass we have on the parent's top-level window.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnDestroyWindow()
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::OnDestroyWindow\n");
 | 
						|
 | 
						|
	if (m_pDocObjFrame)
 | 
						|
        Close();
 | 
						|
 | 
						|
	if (m_pHookManager)
 | 
						|
	{
 | 
						|
		m_pHookManager->DetachComponent(m_hwnd);
 | 
						|
		m_pHookManager = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	m_hwnd = NULL;
 | 
						|
 | 
						|
    if (m_pServerLock)
 | 
						|
        SetTempServerLock(FALSE);
 | 
						|
 | 
						|
	if (m_hbmDeactive)
 | 
						|
	{
 | 
						|
		DeleteObject(m_hbmDeactive);
 | 
						|
		m_hbmDeactive = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if (m_hmenuFilePopup)
 | 
						|
	{
 | 
						|
		DestroyMenu(m_hmenuFilePopup);
 | 
						|
		m_hmenuFilePopup = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnResize
 | 
						|
//
 | 
						|
//  Resize the window and notify the doc site.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnResize()
 | 
						|
{
 | 
						|
	RECT rcPlace;
 | 
						|
	ODS("CDsoFramerControl::OnResize\n");
 | 
						|
	if (m_pDocObjFrame)
 | 
						|
	{
 | 
						|
        if (FChangeObjActiveOnFocusChange() && (!m_fUIActive))
 | 
						|
		    UIActivate(FALSE);
 | 
						|
 | 
						|
		GetSizeRectForDocument(NULL, &rcPlace);
 | 
						|
		m_pDocObjFrame->OnNotifySizeChange(&rcPlace);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnMouseMove
 | 
						|
//
 | 
						|
//  We watch for mouse movement on menu bar (when visible).
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnMouseMove(UINT x, UINT y)
 | 
						|
{
 | 
						|
 // TRACE2("CDsoFramerControl::OnMouseMove(%d, %d)\n", x, y);
 | 
						|
 // TRACE3("  fAppActive=%d, fUIActive=%d, fCompActive=%d\n", m_fAppActive, m_fUIActive, m_fComponentActive);
 | 
						|
 // TRACE2("  fModalState=%d, fNoInteractive=%d\n", m_fModalState, m_fNoInteractive);
 | 
						|
 | 
						|
 // When we are in mouse move, watch for menu selection. Only need to
 | 
						|
 // do this if bar is visible and we are not in modal state...
 | 
						|
    if ((m_fShowMenuBar) && (m_fComponentActive) && (m_fUIActive) && (m_fAppActive) &&
 | 
						|
       (!m_fModalState) && (!m_fNoInteractive))
 | 
						|
    {
 | 
						|
        UINT item;
 | 
						|
        POINT pt; pt.x = x; pt.y = y;
 | 
						|
 | 
						|
     // If we already have item selected, check to see if we are still
 | 
						|
     // over it. If so, we can exit now. If not, we sould unselect it.
 | 
						|
        if (m_wSelMenuItem)
 | 
						|
        {
 | 
						|
            item = m_wSelMenuItem - 1;
 | 
						|
            if (PtInRect(&m_rgrcMenuItems[item], pt))
 | 
						|
                return;
 | 
						|
 | 
						|
            ReleaseCapture(); m_wSelMenuItem = 0;
 | 
						|
		    InvalidateRect(m_hwnd, &m_rgrcMenuItems[item], FALSE);
 | 
						|
        }
 | 
						|
 | 
						|
     // Now loop through the menu items and see if mouse is over them.
 | 
						|
     // If it is, we set a mouse capture and draw item as selected...
 | 
						|
        for (item = 0; item < m_cMenuItems; item++)
 | 
						|
        {
 | 
						|
            if (PtInRect(&m_rgrcMenuItems[item], pt))
 | 
						|
            {
 | 
						|
                SetCapture(m_hwnd);
 | 
						|
                m_wSelMenuItem = (USHORT)(item + 1);
 | 
						|
		        InvalidateRect(m_hwnd, &m_rgrcMenuItems[item], FALSE);
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnButtonDown
 | 
						|
//
 | 
						|
//  We watch for mouse button down events when the titlebar is visible
 | 
						|
//  so we can drop down our popup menu if the user clicks around the 
 | 
						|
//  area of the file icon. This is our workaround for menu merging.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnButtonDown(UINT x, UINT y)
 | 
						|
{
 | 
						|
	HMENU hCurMenu = NULL;
 | 
						|
	RECT rc;
 | 
						|
 | 
						|
 // Don't do anything if we are in modal state...
 | 
						|
    if (m_fModalState) return;
 | 
						|
 | 
						|
 // We don't handle commands when m_fNoInteractive is set, except for the
 | 
						|
 // condition where we are in print preview and want to display custom menu
 | 
						|
 // item to end the preview. Office apps have toolbar button to do this, but
 | 
						|
 // we will provide this option just in case user needs it to exit preview mode...
 | 
						|
    if (m_fNoInteractive)
 | 
						|
    {
 | 
						|
        if ((m_pDocObjFrame) && (m_pDocObjFrame->InPrintPreview()))
 | 
						|
        {
 | 
						|
         // If we don't have UI focus, take it...
 | 
						|
	        if (!m_fUIActive) UIActivate(TRUE);
 | 
						|
 | 
						|
         // Create a temp popup menu. We do this on fly to save resources since
 | 
						|
         // this is only needed in rare cases...
 | 
						|
	        if ((m_fShowTitlebar) && ((x < 22) && (y < 22)))
 | 
						|
	        {
 | 
						|
                hCurMenu = CreatePopupMenu();
 | 
						|
		        if (hCurMenu)
 | 
						|
		        {
 | 
						|
                 // Add the command to the menu...
 | 
						|
                    AppendMenu(hCurMenu, MF_STRING,  MNU_PRINTPV, "E&xit Preview");
 | 
						|
                 // Display the menu...
 | 
						|
			        GetSizeRectAfterTitlebar(NULL, &rc);
 | 
						|
			        MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
 | 
						|
			        TrackPopupMenu(hCurMenu, 0, rc.left, rc.top - 1, 0, m_hwnd, NULL);
 | 
						|
                 // Cleanup...
 | 
						|
                    DestroyMenu(hCurMenu);
 | 
						|
                    hCurMenu = NULL;
 | 
						|
		        }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
     // Otherwise we do nothing when m_fNoInteractive == TRUE.
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
 // We know we must be app active if user clicked on control...
 | 
						|
    if (!m_fAppActive) m_fAppActive = TRUE;
 | 
						|
 | 
						|
 // If we don't have UI focus, take it...
 | 
						|
	if (!m_fUIActive) UIActivate(TRUE);
 | 
						|
 | 
						|
 // If the caption is showing, we are not modal, and user clicked in the 
 | 
						|
 // area around the office doc icon, show the popup menu...
 | 
						|
	if ((m_fShowTitlebar) && (!m_fShowMenuBar) && ((x < 22) && (y < 22)))
 | 
						|
	{
 | 
						|
	 // This will get the File menu or the merged menu based on current state...
 | 
						|
		hCurMenu = GetActivePopupMenu();
 | 
						|
		if (hCurMenu)
 | 
						|
		{
 | 
						|
		 // We'll place it right below the titlebar just like sys menu...
 | 
						|
			GetSizeRectAfterTitlebar(NULL, &rc);
 | 
						|
			MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
 | 
						|
			TrackPopupMenu(hCurMenu, 0, rc.left, rc.top - 1, 0, m_hwnd, NULL);
 | 
						|
		}
 | 
						|
	}
 | 
						|
    else if ((m_fShowMenuBar) && (m_wSelMenuItem))
 | 
						|
    {
 | 
						|
        POINT pt;
 | 
						|
        UINT item = m_wSelMenuItem - 1;
 | 
						|
 | 
						|
     // If we are over a visible menu bar item, find the right popup
 | 
						|
     // menu for the item using the selitem as an index...
 | 
						|
        if (item == 0)
 | 
						|
        {   hCurMenu = m_hmenuFilePopup;  }
 | 
						|
        else
 | 
						|
        {
 | 
						|
		    hCurMenu = GetActivePopupMenu();
 | 
						|
		    if (hCurMenu) hCurMenu = GetSubMenu(hCurMenu, item);
 | 
						|
        }
 | 
						|
 | 
						|
     // Map the location to display the popup into screen points...
 | 
						|
        pt.x = m_rgrcMenuItems[item].left;
 | 
						|
        pt.y = m_rgrcMenuItems[item].bottom;
 | 
						|
        MapWindowPoints(m_hwnd, HWND_DESKTOP, (POINT*)&pt, 1);
 | 
						|
 | 
						|
		HWND hwndCurFocus = GetFocus();
 | 
						|
		m_fInFocusChange = TRUE;
 | 
						|
		if (hwndCurFocus && (hwndCurFocus != m_hwnd))
 | 
						|
			SetFocus(m_hwnd);
 | 
						|
 | 
						|
     // Display the menu...
 | 
						|
		TrackPopupMenu(hCurMenu, 0, pt.x, pt.y, 0, m_hwnd, NULL);
 | 
						|
 | 
						|
		if (hwndCurFocus && (hwndCurFocus != m_hwnd))
 | 
						|
			SetFocus(hwndCurFocus);
 | 
						|
		m_fInFocusChange = FALSE;
 | 
						|
 | 
						|
     // When user clicks off, we will resolve the mouse location to
 | 
						|
     // our control coordinates and call mousemove to free/reset selection...
 | 
						|
        if (GetCursorPos(&pt))
 | 
						|
        {
 | 
						|
            RECT rcMenu; GetSizeRectForMenuBar(NULL, &rcMenu);
 | 
						|
            MapWindowPoints(HWND_DESKTOP, m_hwnd, (POINT*)&pt, 1);
 | 
						|
            if (!PtInRect(&rcMenu, pt)) {pt.x = 0; pt.y = 0;}
 | 
						|
        }
 | 
						|
        else {pt.x = 0; pt.y = 0;}
 | 
						|
        OnMouseMove(pt.x, pt.y);
 | 
						|
    }
 | 
						|
	return;
 | 
						|
}
 | 
						|
 | 
						|
	
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnMenuMessage
 | 
						|
//
 | 
						|
//  We should get these messages when we are displaying the popup menu.
 | 
						|
//  The "File" menu is ours, but the popup may have other menus copied
 | 
						|
//  from the merged menu set by the ui active docobject, so we need to
 | 
						|
//  forward those messages (as needed) to the right window handler.
 | 
						|
//
 | 
						|
//  In addition, code is added to enable/disable File menu items based
 | 
						|
//  on flags set by developer in EnableFileCommand, and/or call the
 | 
						|
//  correct function if one of those commands was selected by user.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnMenuMessage(UINT msg, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	HMENU hmenu, hmenuMerged = NULL;
 | 
						|
	BOOL  fAlwaysSendMessage = FALSE;
 | 
						|
	HWND  hwndObjectMenu = NULL;
 | 
						|
 | 
						|
	if (m_pDocObjFrame)
 | 
						|
	{
 | 
						|
		hwndObjectMenu = m_pDocObjFrame->GetMenuHWND();
 | 
						|
		hmenuMerged = m_pDocObjFrame->GetMergedMenu();
 | 
						|
	}
 | 
						|
 | 
						|
	switch (msg)
 | 
						|
	{
 | 
						|
	case WM_INITMENU:  m_fObjectMenu = FALSE;      //fall through...
 | 
						|
	case WM_ENTERIDLE: fAlwaysSendMessage = TRUE;
 | 
						|
		break;
 | 
						|
 | 
						|
	case WM_MENUSELECT:
 | 
						|
		if ((lParam == 0) && (HIWORD(wParam) == 0xFFFF))
 | 
						|
			fAlwaysSendMessage = TRUE;
 | 
						|
		break;
 | 
						|
 | 
						|
	case WM_INITMENUPOPUP:
 | 
						|
		hmenu = (HMENU)wParam;
 | 
						|
		m_fObjectMenu = ((hmenu != m_hmenuFilePopup) && (hmenu != hmenuMerged));
 | 
						|
 | 
						|
		if ((!m_fObjectMenu) && (hmenu == m_hmenuFilePopup))
 | 
						|
		{
 | 
						|
			EnableMenuItem(hmenu, MNU_NEW,     MF_BYCOMMAND | ((m_wFileMenuFlags & 1) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
			EnableMenuItem(hmenu, MNU_OPEN,    MF_BYCOMMAND | ((m_wFileMenuFlags & 2) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
			EnableMenuItem(hmenu, MNU_CLOSE,   MF_BYCOMMAND | (((m_wFileMenuFlags &   4) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
			EnableMenuItem(hmenu, MNU_SAVE,    MF_BYCOMMAND | (((m_wFileMenuFlags &   8) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
			EnableMenuItem(hmenu, MNU_SAVEAS,  MF_BYCOMMAND | (((m_wFileMenuFlags &  16) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
			EnableMenuItem(hmenu, MNU_PGSETUP, MF_BYCOMMAND | (((m_wFileMenuFlags &  64) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
			EnableMenuItem(hmenu, MNU_PRINTPV, MF_BYCOMMAND | (((m_wFileMenuFlags & 256) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
			EnableMenuItem(hmenu, MNU_PRINT,   MF_BYCOMMAND | (((m_wFileMenuFlags &  32) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
			EnableMenuItem(hmenu, MNU_PROPS,   MF_BYCOMMAND | (((m_wFileMenuFlags & 128) && (m_pDocObjFrame)) ? MF_ENABLED : (MF_DISABLED | MF_GRAYED)));
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	case WM_COMMAND:
 | 
						|
     // We handle one special case for print preview exit, but otherwise
 | 
						|
     // we need to either forward to the merged menu handler (if enabled),
 | 
						|
     // or handle command through an asynchronous callback...
 | 
						|
        if ((m_fNoInteractive) && (LOWORD(wParam) == MNU_PRINTPV))
 | 
						|
        {
 | 
						|
            PrintPreviewExit();
 | 
						|
        }
 | 
						|
		else if ((m_fObjectMenu) && (hwndObjectMenu))
 | 
						|
        {
 | 
						|
			PostMessage(hwndObjectMenu, msg, wParam, lParam);
 | 
						|
        }
 | 
						|
		else
 | 
						|
		{
 | 
						|
			DWORD dwCmd = 0;
 | 
						|
			switch ((int)LOWORD(wParam))
 | 
						|
			{
 | 
						|
			case MNU_NEW:     dwCmd = OLECMDID_NEW;  break;
 | 
						|
			case MNU_OPEN:    dwCmd = OLECMDID_OPEN;  break;
 | 
						|
			case MNU_SAVE:    dwCmd = OLECMDID_SAVE;  break;
 | 
						|
			case MNU_SAVEAS:  dwCmd = OLECMDID_SAVEAS;  break;
 | 
						|
			case MNU_PGSETUP: dwCmd = OLECMDID_PAGESETUP;  break;
 | 
						|
			case MNU_PRINT:   dwCmd = OLECMDID_PRINT;  break;
 | 
						|
			case MNU_PROPS:   dwCmd = OLECMDID_PROPERTIES;  break;
 | 
						|
            case MNU_PRINTPV: dwCmd = OLECMDID_PRINTPREVIEW; break;
 | 
						|
			}
 | 
						|
			PostMessage(m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, dwCmd, 0);
 | 
						|
		}
 | 
						|
 | 
						|
		return; // we just return
 | 
						|
	}
 | 
						|
 | 
						|
	if ((hwndObjectMenu) && ((m_fObjectMenu) || (fAlwaysSendMessage)))
 | 
						|
		SendMessage(hwndObjectMenu, msg, wParam, lParam);
 | 
						|
 | 
						|
	return;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnToolbarAction
 | 
						|
//
 | 
						|
//  Does an associated OLECMDID action and raises the OnFileCommand event
 | 
						|
//  for developer to override as needed. The name comes from the fact that
 | 
						|
//  most Office servers will call this (via IOleCommandTarget) when user
 | 
						|
//  clicks on a toolbar button for file-command item. It also serves for
 | 
						|
//  our menu commands to keep the code consistant. Both menu and toolbar
 | 
						|
//  call this method asynchronously (via PostMessage) to avoid blocking the
 | 
						|
//  remote docobject server.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnToolbarAction(DWORD cmd)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::OnToolbarAction\n");
 | 
						|
	HRESULT hr = S_OK;
 | 
						|
	VARIANT_BOOL wCancelAction = VARIANT_FALSE;
 | 
						|
	VARIANT rgargs[2];
 | 
						|
	VARIANT vtT = {0};
 | 
						|
 | 
						|
 // We don't reenter if in a modal state already...
 | 
						|
    if (m_fModalState) return;
 | 
						|
 | 
						|
 // If not interactive, we cannot run command...
 | 
						|
    if (m_fNoInteractive)
 | 
						|
    {
 | 
						|
     // unless we are in preview, in which case we can force exit 
 | 
						|
     // and then run command after preview completes...
 | 
						|
        if ((m_pDocObjFrame) && (m_pDocObjFrame->InPrintPreview()))
 | 
						|
        {
 | 
						|
            PrintPreviewExit();
 | 
						|
			if (cmd != OLECMDID_PRINTPREVIEW)
 | 
						|
				PostMessage(m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, cmd, 0);
 | 
						|
        }
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
 // We will do a default action by default, but give developer a chance
 | 
						|
 // to override in OnFileCommand event...
 | 
						|
	rgargs[0].vt = VT_BOOL|VT_BYREF;
 | 
						|
	rgargs[0].pboolVal = &wCancelAction;
 | 
						|
 | 
						|
 // Map the OLECMDID to one of our values...
 | 
						|
	rgargs[1].vt = VT_I4;
 | 
						|
	switch (cmd)
 | 
						|
	{
 | 
						|
	case OLECMDID_NEW:           rgargs[1].lVal = dsoFileNew; break;
 | 
						|
	case OLECMDID_OPEN:          rgargs[1].lVal = dsoFileOpen; break;
 | 
						|
	case OLECMDID_SAVE:          rgargs[1].lVal = dsoFileSave; break;
 | 
						|
	case OLECMDID_SAVEAS:        rgargs[1].lVal = dsoFileSaveAs; break;
 | 
						|
	case OLECMDID_PRINT:         rgargs[1].lVal = dsoFilePrint; break;
 | 
						|
	case OLECMDID_PAGESETUP:     rgargs[1].lVal = dsoFilePageSetup; break;
 | 
						|
	case OLECMDID_PROPERTIES:    rgargs[1].lVal = dsoFileProperties; break;
 | 
						|
    case OLECMDID_PRINTPREVIEW:  rgargs[1].lVal = dsoFilePrintPreview; break;
 | 
						|
	default:    rgargs[1].lVal = dsoFileClose;
 | 
						|
	}
 | 
						|
	
 | 
						|
 // Only do action if item is enabled...
 | 
						|
	if ((1 << rgargs[1].lVal) & m_wFileMenuFlags)
 | 
						|
	{
 | 
						|
	 // Let control developer handle the event first...
 | 
						|
		hr = RaiseAutomationEvent(DSOF_DISPID_FILECMD,  2, rgargs);
 | 
						|
		TRACE1("Disp event returned 0x%X \n", hr);
 | 
						|
 | 
						|
     // If the event was canceled (or event handler threw an
 | 
						|
     // unhandled error from user code), bail out now...
 | 
						|
        if ((wCancelAction) || (hr == DISP_E_EXCEPTION))
 | 
						|
            return;
 | 
						|
 | 
						|
     // Do the action based on the event...
 | 
						|
        switch (rgargs[1].lVal)
 | 
						|
        {
 | 
						|
        case dsoFileClose:		hr = Close();	break;
 | 
						|
        case dsoFilePrint:		hr = ShowDialog(dsoDialogPrint); break;
 | 
						|
        case dsoFilePageSetup:	hr = ShowDialog(dsoDialogPageSetup); break;
 | 
						|
        case dsoFileProperties:	hr = ShowDialog(dsoDialogProperties); break;
 | 
						|
        case dsoFilePrintPreview: hr = PrintPreview(); break;
 | 
						|
 | 
						|
        case dsoFileSave:
 | 
						|
	        hr = Save(vtT, vtT, vtT, vtT);
 | 
						|
	        if ((hr != DSO_E_DOCUMENTREADONLY) && 
 | 
						|
				(hr != DSO_E_NOTBEENSAVED))
 | 
						|
		        break; // fall through to SaveAs if file is read-only or never been saved...
 | 
						|
 | 
						|
        default:
 | 
						|
	        hr = DoDialogAction(
 | 
						|
		        (rgargs[1].lVal == dsoFileNew) ? dsoDialogNew : 
 | 
						|
		        (rgargs[1].lVal == dsoFileOpen) ? dsoDialogOpen : dsoDialogSave);
 | 
						|
        }
 | 
						|
 | 
						|
     // Display error information to user if we failed...
 | 
						|
        if (FAILED(hr) && (hr != E_ABORT))
 | 
						|
            FAlertUser(hr, NULL);
 | 
						|
	}
 | 
						|
 | 
						|
	return;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::FAlertUser
 | 
						|
//
 | 
						|
//  Display an error alert to the user based on failed HRESULT.
 | 
						|
//
 | 
						|
STDMETHODIMP_(BOOL) CDsoFramerControl::FAlertUser(HRESULT hr, LPWSTR pwsFileName)
 | 
						|
{
 | 
						|
    LPSTR pszError = NULL;
 | 
						|
    LPSTR pszTitle = NULL;
 | 
						|
    DWORD dwFlags  = MB_ICONINFORMATION|MB_SETFOREGROUND;
 | 
						|
 | 
						|
    switch (hr)
 | 
						|
    {
 | 
						|
    case STG_E_ACCESSDENIED:
 | 
						|
    case STG_E_SHAREVIOLATION:
 | 
						|
    case STG_E_LOCKVIOLATION:
 | 
						|
    case MK_E_CANTOPENFILE:
 | 
						|
    case E_ACCESSDENIED:
 | 
						|
        pszError = "Unable to Open/Save the file selected due to security permissions or a share violation.";
 | 
						|
        pszTitle = "Access Denied";
 | 
						|
        break;
 | 
						|
 | 
						|
    case DSO_E_DOCUMENTNOTOPEN:
 | 
						|
        pszError = "The operation could not be performed because no document is currently open.";
 | 
						|
        pszTitle = "Unable to Perform Command";
 | 
						|
        break;
 | 
						|
 | 
						|
    case DSO_E_DOCUMENTREADONLY:
 | 
						|
        pszError = "The operation could not be performed because the document was opened read-only.";
 | 
						|
        pszTitle = "Unable to Update Document";
 | 
						|
        break;
 | 
						|
 | 
						|
    case CO_E_MSI_ERROR:
 | 
						|
    case DSO_E_INVALIDSERVER:
 | 
						|
    case DSO_E_INVALIDPROGID:
 | 
						|
    case STG_E_NOTFILEBASEDSTORAGE:
 | 
						|
        pszError = "There is no ActiveX Document server currently registered or installed for the item selected. "
 | 
						|
                   "It cannot be loaded into the control.";
 | 
						|
        pszTitle = "Unable to Insert Document";
 | 
						|
        break;
 | 
						|
 | 
						|
    case DSO_E_INMODALSTATE:
 | 
						|
        MessageBeep(0);
 | 
						|
        return FALSE; // Unable to alert user if in a modal condition!
 | 
						|
 | 
						|
    case DSO_E_COMMANDNOTSUPPORTED:
 | 
						|
        pszError = "This operation could not be performed because the document server "
 | 
						|
		           "does not support the command, or it is disabled when embedded.";
 | 
						|
        pszTitle = "Command Not Supported";
 | 
						|
        break;
 | 
						|
 | 
						|
    case STG_E_TOOMANYOPENFILES:
 | 
						|
        pszError = "You can only open one document at a time. Please choose a single file to open.";
 | 
						|
        pszTitle = "Command Not Supported";
 | 
						|
        break;
 | 
						|
 | 
						|
    case DSO_E_REQUIRESMSDAIPP:
 | 
						|
        pszError = "You cannot open/save to a web folder unless MDAC 2.5 is installed. The operation cannot be performed.";
 | 
						|
        pszTitle = "Unable to Gain Write Access for URL";
 | 
						|
        break;
 | 
						|
 | 
						|
    default:
 | 
						|
        pszError = "The program encountered an error trying to perform the command. "					
 | 
						|
		           "If the problem persists, contact the program vendor for a possible solution.";
 | 
						|
        pszTitle = "Command Error";
 | 
						|
        dwFlags  = MB_ICONHAND|MB_SETFOREGROUND;
 | 
						|
    }
 | 
						|
 | 
						|
    MessageBox(m_hwnd, pszError, pszTitle, dwFlags);
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::EnableDropFile
 | 
						|
//
 | 
						|
//  Decide when to allow file drop for open.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::EnableDropFile(BOOL fEnable)
 | 
						|
{
 | 
						|
    TRACE1("CDsoFramerControl::EnableDropFile(%d)\n", fEnable);
 | 
						|
    DragAcceptFiles(m_hwnd, fEnable);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnDropFile
 | 
						|
//
 | 
						|
//  Open file dropped by user on the control.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnDropFile(HDROP hdrpFile)
 | 
						|
{
 | 
						|
    DWORD cbItems;
 | 
						|
    CHAR szFileDrop[MAX_PATH];
 | 
						|
    VARIANT vtFile;
 | 
						|
 | 
						|
    ODS("CDsoFramerControl::OnDropFile()\n");
 | 
						|
    cbItems = DragQueryFile(hdrpFile, 0xFFFFFFFF, NULL, 0);
 | 
						|
    if (cbItems == 0)
 | 
						|
        return;
 | 
						|
 | 
						|
    if (cbItems > 1)
 | 
						|
    {
 | 
						|
        FAlertUser(STG_E_TOOMANYOPENFILES, NULL);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    szFileDrop[0] = 0;
 | 
						|
    vtFile.vt = VT_BSTR;
 | 
						|
 | 
						|
    if (DragQueryFile(hdrpFile, 0, szFileDrop, MAX_PATH) &&
 | 
						|
        (vtFile.bstrVal = DsoConvertToBSTR(szFileDrop)))
 | 
						|
    {
 | 
						|
        HRESULT hr;
 | 
						|
        VARIANT vtMissing;
 | 
						|
        vtMissing.vt = VT_ERROR;
 | 
						|
        vtMissing.scode = DISP_E_PARAMNOTFOUND;
 | 
						|
 | 
						|
        hr = Open(vtFile, vtMissing, vtMissing, vtMissing, vtMissing);
 | 
						|
        if (FAILED(hr)) FAlertUser(hr, vtFile.bstrVal);
 | 
						|
        
 | 
						|
        VariantClear(&vtFile);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnTimer
 | 
						|
//
 | 
						|
//  Timer event fired.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnTimer(UINT id)
 | 
						|
{
 | 
						|
 // TRACE1("CDsoFramerControl::OnTimer(%d)\n", id);
 | 
						|
    switch (id)
 | 
						|
    {
 | 
						|
    case SYNCPAINT_TIMER_ID:
 | 
						|
        {
 | 
						|
            DWORD dwTick = GetTickCount();
 | 
						|
            if ((dwTick - m_uiSyncPaint) > 300)
 | 
						|
            {
 | 
						|
                ODS("CDsoFramerControl::OnSyncPaint() Invalidate\n");
 | 
						|
                KillTimer(m_hwnd, SYNCPAINT_TIMER_ID);
 | 
						|
                m_fSyncPaintTimer = FALSE;
 | 
						|
				InvalidateAllChildWindows(m_hwnd);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnSyncPaint
 | 
						|
//
 | 
						|
//  Notifies redraw is needed b/c of external window movement.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnSyncPaint()
 | 
						|
{
 | 
						|
 // ODS("CDsoFramerControl::OnSyncPaint()\n");
 | 
						|
    m_uiSyncPaint = GetTickCount();
 | 
						|
    if ((!m_fSyncPaintTimer) && (!m_fAppActive))
 | 
						|
    {
 | 
						|
        SetTimer(m_hwnd, SYNCPAINT_TIMER_ID, 50, NULL);
 | 
						|
        m_fSyncPaintTimer = TRUE;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnForegroundCompChange
 | 
						|
//
 | 
						|
//  Shows/Hide embedding when window goes foreground/background active. 
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnForegroundCompChange(BOOL fCompActive)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::OnForegroundCompChange\n");
 | 
						|
    if (m_pDocObjFrame)
 | 
						|
    {
 | 
						|
        HWND hwndEmbed = m_pDocObjFrame->GetDocWindow();
 | 
						|
 | 
						|
        if (fCompActive)
 | 
						|
        {
 | 
						|
         // Make sure embed window is visible when active...
 | 
						|
            if (!IsWindowVisible(hwndEmbed))
 | 
						|
			    ShowWindow(hwndEmbed, SW_SHOW);
 | 
						|
 | 
						|
            if (m_hbmDeactive) DeleteObject(m_hbmDeactive);
 | 
						|
            m_hbmDeactive = NULL;
 | 
						|
        }
 | 
						|
        else if ((FDrawBitmapOnAppDeactive() || FIPDeactivateOnCompChange()) && (m_hbmDeactive == NULL))
 | 
						|
        {
 | 
						|
         // The default behavior on app deactive is to grap bitmap of active object before
 | 
						|
         // telling it we lost app activation. This allows us to draw the last state of the 
 | 
						|
         // object while it is deactive. There is now an option to avoid this and keep object
 | 
						|
         // UI active while app deactive, but it may not work for all DocObj servers.
 | 
						|
		    m_hbmDeactive = DsoGetBitmapFromWindow(hwndEmbed);
 | 
						|
		    ShowWindow(hwndEmbed, SW_HIDE);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnAppActivationChange
 | 
						|
//
 | 
						|
//  Notifes embedded object when the host app gains/loses foreground status
 | 
						|
//  as the active application. This notification is critical to DocObjects since
 | 
						|
//  it is the primary means for the host and server to synch which top-level 
 | 
						|
//  frame window (the host or the server's native main window) should be on the
 | 
						|
//  z-order stack for the shared thread input state. Thus allowing dialogs and tool
 | 
						|
//  windows to appear the correct order when displayed.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnAppActivationChange(BOOL fAppActive, DWORD dwThreadID)
 | 
						|
{
 | 
						|
	TRACE2("CDsoFramerControl::OnAppActivationChange(fAppActive=%d, tid=0x%X)\n", fAppActive, dwThreadID);
 | 
						|
    m_fAppActive = fAppActive;
 | 
						|
 | 
						|
    if ((m_pDocObjFrame) && (m_fComponentActive))
 | 
						|
    {
 | 
						|
     // Create/Free bitmap for background appearance..
 | 
						|
        OnForegroundCompChange(fAppActive);
 | 
						|
 | 
						|
     // Notify it that it should be app active ofr deactive...
 | 
						|
		m_pDocObjFrame->OnNotifyAppActivate(fAppActive, (dwThreadID ? dwThreadID : GetCurrentThreadId()));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnComponentActivationChange
 | 
						|
//
 | 
						|
//  Handles showing/hiding doc object during activation state changes.
 | 
						|
//  This is needed to properly handle focus changes when more than one
 | 
						|
//  instance of the control is running on the same top-level window.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnComponentActivationChange(BOOL fActivate)
 | 
						|
{
 | 
						|
	TRACE1("CDsoFramerControl::OnComponentActivationChange(fActive=%d)\n", fActivate);
 | 
						|
 | 
						|
	if (fActivate)
 | 
						|
	{
 | 
						|
	 // Set us active if we currently are not and raise activation change event...
 | 
						|
		if (!m_fComponentActive)
 | 
						|
		{
 | 
						|
			m_fComponentActive = TRUE;
 | 
						|
            OnForegroundCompChange(TRUE);
 | 
						|
		 // Raise event to component host on state change...
 | 
						|
			PostMessage(m_hwnd, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_ACTIVATION, (LPARAM)fActivate);
 | 
						|
		}
 | 
						|
 | 
						|
     // Notify the embedded object...
 | 
						|
        if (m_pDocObjFrame)
 | 
						|
		{
 | 
						|
         // Determine if we should restore from IP deactivation... 
 | 
						|
			if (FIPDeactivateOnCompChange() && !(m_pDocObjFrame->IsIPActive()))
 | 
						|
            {
 | 
						|
               m_pDocObjFrame->IPActivateView();
 | 
						|
 		       OnForegroundCompChange(TRUE);
 | 
						|
            }
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
 | 
						|
     // Inform embedded object we lost activation...
 | 
						|
		if (m_pDocObjFrame)
 | 
						|
		{
 | 
						|
         // If we are in print preview, we need to exit in case other control will
 | 
						|
         // end up talking to same OLE server...
 | 
						|
		    if (m_pDocObjFrame->InPrintPreview())
 | 
						|
            {
 | 
						|
                PrintPreviewExit();
 | 
						|
                UpdateWindow(m_hwnd);
 | 
						|
            }
 | 
						|
 | 
						|
         // Provide control host option to IP deactive view when another framer control 
 | 
						|
         // takes primary focus. This helps certain resource problems if you a lot of controls
 | 
						|
         // all IP active at the same time.  This should not normally be used.
 | 
						|
			if (FIPDeactivateOnCompChange() && m_pDocObjFrame->IsIPActive())
 | 
						|
            {
 | 
						|
		        OnForegroundCompChange(FALSE);
 | 
						|
                m_pDocObjFrame->IPDeactivateView();
 | 
						|
            }
 | 
						|
			
 | 
						|
		}
 | 
						|
 | 
						|
	 // Change the current activation state and raise event...
 | 
						|
		if (m_fComponentActive)
 | 
						|
		{
 | 
						|
			m_fComponentActive = FALSE;
 | 
						|
            OnForegroundCompChange(FALSE);
 | 
						|
		 // Raise event to component host on state change...
 | 
						|
			PostMessage(m_hwnd, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_ACTIVATION, (LPARAM)fActivate);
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnCtrlFocusChange
 | 
						|
//
 | 
						|
//  Checks if window (or one of its children) is getting or losing focus so
 | 
						|
//  that can notify both the host and embed server using OnUIFocusChange.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnCtrlFocusChange(BOOL fCtlGotFocus, HWND hFocusWnd)
 | 
						|
{
 | 
						|
	TRACE2("CDsoFramerControl::OnCtrlFocusChange(fCtlGotFocus=%d, hwndCurFocus=%x)\n", fCtlGotFocus, hFocusWnd);
 | 
						|
    if (!(m_fInFocusChange) && ((fCtlGotFocus) || !IsWindowChild(m_hwnd, hFocusWnd)))
 | 
						|
    {
 | 
						|
        OnUIFocusChange(fCtlGotFocus);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnUIFocusChange
 | 
						|
//
 | 
						|
//  Selectively handle focus changes to make sure both host and ui 
 | 
						|
//  active docobject are in synch.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnUIFocusChange(BOOL fUIActive)
 | 
						|
{
 | 
						|
    BOOL fFocusUpdated = FALSE;
 | 
						|
	TRACE1("CDsoFramerControl::OnUIFocusChange(fUIActive=%d)\n", fUIActive);
 | 
						|
 | 
						|
 // We shouldn't try to do focus change when modal...
 | 
						|
    if ((m_fModalState) || (m_fInFocusChange))
 | 
						|
    {
 | 
						|
        ODS(" -- Got focus while modal or in change (do nothing) --\n");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
  // When IP active, notify the control host of focus change...
 | 
						|
	if ((m_fInPlaceActive) && (m_pControlSite))
 | 
						|
	{
 | 
						|
 | 
						|
     // Set flag to prevent recursion during focus changes...
 | 
						|
		m_fInFocusChange = TRUE;
 | 
						|
 | 
						|
		if (fUIActive) // If we got focus...
 | 
						|
		{
 | 
						|
		 // Notify host we have focus (we only need
 | 
						|
		 // to do this if we are not already UI Active)...
 | 
						|
			if (!(m_fHasFocus))
 | 
						|
			{
 | 
						|
				ODS(" -- Tell host app we should have focus --\n");
 | 
						|
                m_fHasFocus = (fFocusUpdated = TRUE);
 | 
						|
				m_pControlSite->OnFocus(TRUE); 
 | 
						|
			}
 | 
						|
 | 
						|
		 // Let the hook manager know that this control is the active object...
 | 
						|
			if (m_pHookManager)
 | 
						|
				m_pHookManager->SetActiveComponent(m_hwnd);
 | 
						|
 | 
						|
         // If so configured, force component to show up active...
 | 
						|
		    if (FChangeObjActiveOnFocusChange())
 | 
						|
		    {
 | 
						|
                ODS(" -- Do component active on focus gain --\n");
 | 
						|
			    OnComponentActivationChange(TRUE);
 | 
						|
		    }
 | 
						|
 | 
						|
		 // If we have an active document, forward the focus...
 | 
						|
			if (m_pDocObjFrame)
 | 
						|
				m_pDocObjFrame->OnNotifyControlFocus(TRUE);
 | 
						|
 | 
						|
		}
 | 
						|
		else // else we lost focus...
 | 
						|
		{
 | 
						|
 | 
						|
	     // When we lose focus, only notify host if we lost to window
 | 
						|
	     // that does not belong to us...
 | 
						|
			if (m_pDocObjFrame)
 | 
						|
				m_pDocObjFrame->OnNotifyControlFocus(FALSE);
 | 
						|
 | 
						|
         // If so configured, force component loss on focus loss...
 | 
						|
		    if (FChangeObjActiveOnFocusChange())
 | 
						|
		    {
 | 
						|
                ODS(" -- Do component deactive on focus loss --\n");
 | 
						|
			    OnComponentActivationChange(FALSE);
 | 
						|
			    m_fActivateOnStatus = TRUE;
 | 
						|
		    }
 | 
						|
 | 
						|
         // If we are UI active still, we need to tell host that we lost 
 | 
						|
         // focus and are now UI deactive.
 | 
						|
            if (m_fHasFocus)
 | 
						|
            {
 | 
						|
			    ODS(" -- Notify host of lost focus (ie, UI deactivate us) --\n");
 | 
						|
                m_fHasFocus = FALSE; fFocusUpdated = TRUE;
 | 
						|
			    m_pControlSite->OnFocus(FALSE);
 | 
						|
            }
 | 
						|
		}
 | 
						|
 | 
						|
     // Clear focus change flag...
 | 
						|
		m_fInFocusChange = FALSE;
 | 
						|
 | 
						|
     // Redraw menu bar in case of state change
 | 
						|
        if ((fFocusUpdated) && (m_fShowMenuBar))
 | 
						|
        {
 | 
						|
            RECT rc; GetSizeRectForMenuBar(NULL, &rc);
 | 
						|
            InvalidateRect(m_hwnd, &rc, TRUE);
 | 
						|
        }
 | 
						|
	}
 | 
						|
 | 
						|
	return;
 | 
						|
}
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::UpdateModalState
 | 
						|
//
 | 
						|
//  Called either by developer (ModalState property) or by the embedded
 | 
						|
//  DocObject to notify host (VB/IE) that we are modal.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::UpdateModalState(BOOL fModeless, BOOL fNotifyIPObject)
 | 
						|
{
 | 
						|
	TRACE2("CDsoFramerControl::UpdateModalState(AllowModeless=%d, NotifyIP=%d)\n", fModeless, fNotifyIPObject);
 | 
						|
	if (fModeless == (int)m_fModalState)
 | 
						|
	{
 | 
						|
		IOleInPlaceActiveObject* pipao;
 | 
						|
 | 
						|
		m_fModalState = !(fModeless);
 | 
						|
		ODS("Modal state changed\n");
 | 
						|
 | 
						|
	  // Excel doesn't like us to notify the host of changes in modality
 | 
						|
	  // if it is the one who initialied the call. So, we check the
 | 
						|
	  // NotifyIPObj flag and only notify host when the IPObj is not the caller...
 | 
						|
		if ((fNotifyIPObject) && (m_pInPlaceFrame))
 | 
						|
			m_pInPlaceFrame->EnableModeless(fModeless);
 | 
						|
 | 
						|
	  // Again, if IPObj is not the caller and we have Ipobj, let it know 
 | 
						|
	  // of the change in modal state...
 | 
						|
		if ((fNotifyIPObject) && (m_pDocObjFrame) && 
 | 
						|
			(pipao = m_pDocObjFrame->GetActiveObject()))
 | 
						|
			pipao->EnableModeless(fModeless);
 | 
						|
 | 
						|
	 // Post notification of return from modal...
 | 
						|
		if (fModeless)
 | 
						|
			PostMessage(m_hwnd, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_RETURNFROMMODAL, (LPARAM)TRUE);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::UpdateInteractiveState
 | 
						|
//
 | 
						|
//  Called when interactivity changes (mostly due to print preview).
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::UpdateInteractiveState(BOOL fActive)
 | 
						|
{
 | 
						|
    if (fActive)
 | 
						|
    {
 | 
						|
        m_fNoInteractive = FALSE;
 | 
						|
        if (m_fShowMenuPrev) put_Menubar(VARIANT_TRUE);
 | 
						|
        if (!m_fShowToolsPrev) put_Toolbars(VARIANT_FALSE);
 | 
						|
 | 
						|
	 // Notify control host that preview mode has ended...
 | 
						|
    	RaiseAutomationEvent(DSOF_DISPID_ENDPREVIEW, 0, NULL);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        m_fShowMenuPrev = m_fShowMenuBar;
 | 
						|
		m_fShowToolsPrev = m_fShowToolbars;
 | 
						|
        if (m_fShowMenuBar) put_Menubar(VARIANT_FALSE);
 | 
						|
        if (!m_fShowToolbars) put_Toolbars(VARIANT_TRUE);
 | 
						|
        m_fNoInteractive = TRUE;
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnPaletteChanged
 | 
						|
//
 | 
						|
//  This method is also called from the subclassed parent. Per docobject
 | 
						|
//  spec, a ui active object should get first chance of any palette updates.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::OnPaletteChanged(HWND hwndPalChg)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::OnPaletteChanged\n");
 | 
						|
	if (m_pDocObjFrame)	m_pDocObjFrame->OnNotifyPaletteChanged(hwndPalChg);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::OnSysCommandMenu
 | 
						|
//
 | 
						|
//  Checks for menu shortcut keys when ui active.
 | 
						|
//
 | 
						|
STDMETHODIMP_(BOOL) CDsoFramerControl::OnSysCommandMenu(CHAR ch)
 | 
						|
{
 | 
						|
    if (m_fUIActive)
 | 
						|
    {
 | 
						|
        TRACE1("CDsoFramerControl::OnSysCommandMenu(%d)\n", (DWORD)ch);
 | 
						|
        return TRUE;
 | 
						|
    }
 | 
						|
    return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::GetActivePopupMenu
 | 
						|
//
 | 
						|
//  Constructs our popup menu and returns the handle. The menu can be
 | 
						|
//  either the File menu by itself (no docobj is open) or the merged
 | 
						|
//  menu as a popup.
 | 
						|
//
 | 
						|
STDMETHODIMP_(HMENU) CDsoFramerControl::GetActivePopupMenu()
 | 
						|
{
 | 
						|
	HMENU hPopup, hMergedMenu, hServerMenu;
 | 
						|
 | 
						|
 // If we haven't made a File menu yet, make it. Here is where you might
 | 
						|
 // want to add custom items if you have other file-level commands you would
 | 
						|
 // the control to support. These are the basics...
 | 
						|
	if (!m_hmenuFilePopup)
 | 
						|
	{
 | 
						|
		m_hmenuFilePopup = CreatePopupMenu(); m_cMenuItems = 0;
 | 
						|
		if (!m_hmenuFilePopup) return NULL;
 | 
						|
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_NEW,     "&New...\tCtrl+N");
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_OPEN,    "&Open...\tCtrl+O");
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_CLOSE,   "&Close");
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_SEPARATOR, 0,            NULL);
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_SAVE,    "&Save\tCtrl+S");
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_SAVEAS,  "Save &As...");
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_SEPARATOR, 0,            NULL);
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_PGSETUP, "Page Set&up...");
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_PRINTPV, "Print Pre&view");
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_PRINT,   "&Print...");
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_SEPARATOR, 0,            NULL);
 | 
						|
		AppendMenu(m_hmenuFilePopup, MF_STRING,    MNU_PROPS,   "Propert&ies");
 | 
						|
	}
 | 
						|
 | 
						|
 // If we have a docobj and it has a merged menu, then lets return a 
 | 
						|
 // merged menu between the docobj and our file menu...
 | 
						|
	if ((m_pDocObjFrame) && (m_pDocObjFrame->GetMenuHWND()))
 | 
						|
	{
 | 
						|
	 // We only need to create the merged copy once.
 | 
						|
		if (!(hMergedMenu = m_pDocObjFrame->GetMergedMenu()))
 | 
						|
		{
 | 
						|
			hMergedMenu = CreatePopupMenu(); m_cMenuItems = 0;
 | 
						|
			if ((hMergedMenu) && (hServerMenu = (m_pDocObjFrame->GetActiveMenu())))
 | 
						|
			{
 | 
						|
				CHAR szbuf[MAX_PATH];
 | 
						|
				HMENU hT;
 | 
						|
                CHAR *pch;
 | 
						|
 | 
						|
				InsertMenu(hMergedMenu, 0, MF_BYPOSITION|MF_POPUP, (UINT)m_hmenuFilePopup, "&File");
 | 
						|
				m_rgchMenuAccel[0] = 'f';
 | 
						|
 | 
						|
				int cbMenuCnt = GetMenuItemCount(hServerMenu);
 | 
						|
				if (cbMenuCnt > DSO_MAX_MENUITEMS) cbMenuCnt = DSO_MAX_MENUITEMS;
 | 
						|
 | 
						|
				for (int i = 0; i < cbMenuCnt; i++)
 | 
						|
				{
 | 
						|
					hT = GetSubMenu(hServerMenu, i);
 | 
						|
					if (hT)
 | 
						|
					{
 | 
						|
						szbuf[0] = '\0';
 | 
						|
						GetMenuString(hServerMenu, i, szbuf, MAX_PATH, MF_BYPOSITION);
 | 
						|
						InsertMenu(hMergedMenu, (i + 1), MF_BYPOSITION|MF_POPUP, (UINT)hT, szbuf);
 | 
						|
 | 
						|
                        pch = szbuf;
 | 
						|
                        while (*pch && (*pch++ != '&'))
 | 
						|
                            ;
 | 
						|
                        m_rgchMenuAccel[i + 1] = (CHAR)((*pch) ? ASCII_LOWERCASE(*pch) : 0xFF);
 | 
						|
					}
 | 
						|
				}
 | 
						|
 | 
						|
				if (cbMenuCnt < DSO_MAX_MENUITEMS)
 | 
						|
					m_rgchMenuAccel[cbMenuCnt + 1] = 0x00;
 | 
						|
 | 
						|
				m_pDocObjFrame->SetMergedMenu(hMergedMenu);                
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		hPopup = hMergedMenu;
 | 
						|
	}
 | 
						|
	else
 | 
						|
    {
 | 
						|
        hPopup = m_hmenuFilePopup;
 | 
						|
        m_rgchMenuAccel[0] = 'f';
 | 
						|
        m_rgchMenuAccel[1] = 0;
 | 
						|
    }
 | 
						|
 | 
						|
	return hPopup;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::FRunningInDesignMode
 | 
						|
//
 | 
						|
//  Determines if we are in design mode. Called when painting the control
 | 
						|
//  and when deciding whether to subclass the parent.
 | 
						|
//
 | 
						|
STDMETHODIMP_(BOOL) CDsoFramerControl::FRunningInDesignMode()
 | 
						|
{
 | 
						|
	IDispatch *pdisp;
 | 
						|
 | 
						|
 // We must have a control site.
 | 
						|
	CHECK_NULL_RETURN(m_pClientSite, FALSE);
 | 
						|
 | 
						|
 // If we have done this before, we don't need to keep doing it unless
 | 
						|
 // the host has notified us of the state change (see our code in 
 | 
						|
 // XOleControl::OnAmbientPropertyChange)...
 | 
						|
	if ((!m_fModeFlagValid) && 
 | 
						|
		SUCCEEDED(m_pClientSite->QueryInterface(IID_IDispatch, (void **)&pdisp)))
 | 
						|
	{
 | 
						|
		VARIANT vtUserMode;
 | 
						|
		m_fDesignMode = FALSE; // assume run mode
 | 
						|
 | 
						|
		if (SUCCEEDED(DsoDispatchInvoke(pdisp, NULL, 
 | 
						|
				DISPID_AMBIENT_USERMODE, DISPATCH_PROPERTYGET, 0, NULL, &vtUserMode)))
 | 
						|
		{
 | 
						|
		 // UserMode is True when control is in Run mode, False when in design.
 | 
						|
		 // We assume run mode, so we only care to set the flag if in design.
 | 
						|
			m_fDesignMode = !(BOOL_FROM_VARIANT(vtUserMode, TRUE));
 | 
						|
			VariantClear(&vtUserMode);
 | 
						|
		}
 | 
						|
 | 
						|
		m_fModeFlagValid = TRUE;
 | 
						|
     // Release the IDispatch pointer...
 | 
						|
        pdisp->Release();
 | 
						|
	}
 | 
						|
 | 
						|
	return m_fDesignMode;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::InvalidateAllChildWindows
 | 
						|
//
 | 
						|
//  Invalidate all child windows attached to the window passed.
 | 
						|
//
 | 
						|
STDMETHODIMP_(BOOL) CDsoFramerControl::InvalidateAllChildWindows(HWND hwnd)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::InvalidateAllChildWindows()\n");
 | 
						|
	return EnumChildWindows(hwnd, InvalidateAllChildWindowsCallback, 0);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP_(BOOL) CDsoFramerControl::InvalidateAllChildWindowsCallback(HWND hwnd, LPARAM lParam)
 | 
						|
{
 | 
						|
	RECT rc; 
 | 
						|
	GetClientRect(hwnd, &rc);
 | 
						|
	InvalidateRect(hwnd, &rc, TRUE);
 | 
						|
	return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::RaiseAutomationEvent
 | 
						|
//
 | 
						|
//  Raises automation events to host application.
 | 
						|
//
 | 
						|
STDMETHODIMP CDsoFramerControl::RaiseAutomationEvent(DISPID did, ULONG cargs, VARIANT *pvtargs)
 | 
						|
{
 | 
						|
    HRESULT hr = ((m_fModalState) ? DISP_E_EXCEPTION : S_FALSE);
 | 
						|
    TRACE1("CDsoFramerControl::RaiseAutomationEvent(%d)\n", did);
 | 
						|
 | 
						|
 // We should only raise event if we have sink, not already in a event, and 
 | 
						|
 // we are not in modal condition with respect to the remote server...
 | 
						|
    if ((m_dispEvents) && (!m_fFreezeEvents) && (!m_fModalState))
 | 
						|
    {
 | 
						|
        m_fFreezeEvents = TRUE;
 | 
						|
        hr = DsoDispatchInvoke(m_dispEvents, NULL, did, 0, cargs, pvtargs, NULL);
 | 
						|
        m_fFreezeEvents = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::DoDialogAction
 | 
						|
//
 | 
						|
//  A very simple implementation of a New/Open/Save dialogs to serve as
 | 
						|
//  default actions in case developer does not override these "File"
 | 
						|
//  commands in OnFileCommand.
 | 
						|
//
 | 
						|
STDMETHODIMP CDsoFramerControl::DoDialogAction(dsoShowDialogType item)
 | 
						|
{
 | 
						|
	HRESULT    hr = S_FALSE;
 | 
						|
    BSTR       bstr;
 | 
						|
    BOOL       fReadOnly;
 | 
						|
	VARIANT    vT[3];
 | 
						|
 | 
						|
    static const WCHAR v_wszFileFilter[] =
 | 
						|
        L"Microsoft Office Files\0*.doc;*.docx;*.docm;*.rtf;*.xls;*.xlsx;*.xlsm;*.csv;*.ppt;*.pptx;*.pptm;*.mpp;*.vsd;*.vdx\0"
 | 
						|
		L"Microsoft Word Files\0*.doc;*.docx;*.docm;*.rtf\0"
 | 
						|
		L"Microsoft Excel Files\0*.xls;*.xlsx;*.xlsm;*.csv\0"
 | 
						|
		L"Microsoft PowerPoint Files\0*.ppt;*.pptx;*.pptm\0"
 | 
						|
		L"Microsoft Project Files\0*.mpp\0"
 | 
						|
		L"Microsoft Visio Files\0*.vsd;*.vdx\0"
 | 
						|
		L"All Files (*.*)\0*.*\0\0";
 | 
						|
 | 
						|
 // Switch on the action type... 
 | 
						|
    switch (item)
 | 
						|
    {
 | 
						|
    case dsoDialogOpen: // Get file from user and call Open...
 | 
						|
        if (SUCCEEDED(DsoGetFileFromUser(m_hwnd, NULL, (OFN_FILEMUSTEXIST|OFN_EXPLORER),
 | 
						|
            v_wszFileFilter, 1, NULL, NULL, FALSE, &bstr, &fReadOnly)))
 | 
						|
        {
 | 
						|
			vT[0].vt = VT_BSTR;  vT[0].bstrVal = bstr;
 | 
						|
            vT[1].vt = VT_BOOL;	 vT[1].boolVal = (fReadOnly ? VARIANT_TRUE : VARIANT_FALSE);
 | 
						|
            vT[2].vt = VT_ERROR; vT[2].scode = DISP_E_PARAMNOTFOUND;
 | 
						|
 | 
						|
			hr = Open(vT[0], vT[1], vT[2], vT[2], vT[2]);
 | 
						|
			SysFreeString(bstr);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
    case dsoDialogSave: // Get file from user and call Save...
 | 
						|
        {
 | 
						|
            LPWSTR pwszSaveType = NULL;
 | 
						|
            LPWSTR pwszDefExt = NULL;
 | 
						|
 | 
						|
            if (m_pDocObjFrame)
 | 
						|
                m_pDocObjFrame->GetDocumentTypeAndFileExtension(&pwszSaveType, &pwszDefExt);
 | 
						|
 | 
						|
            if (SUCCEEDED(DsoGetFileFromUser(m_hwnd, NULL, (OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER),
 | 
						|
                ((pwszSaveType) ? pwszSaveType : v_wszFileFilter), 1, pwszDefExt, NULL, TRUE, &bstr, NULL)))
 | 
						|
            {
 | 
						|
			    vT[0].vt = VT_BSTR;  vT[0].bstrVal = bstr;
 | 
						|
			    vT[1].vt = VT_BOOL;	 vT[1].boolVal = VARIANT_TRUE;
 | 
						|
                vT[2].vt = VT_ERROR; vT[2].scode = DISP_E_PARAMNOTFOUND;
 | 
						|
 | 
						|
			    hr = Save(vT[0], vT[1], vT[2], vT[2]);
 | 
						|
			    SysFreeString(bstr);
 | 
						|
            }
 | 
						|
 | 
						|
            if (pwszSaveType) DsoMemFree(pwszSaveType);
 | 
						|
            if (pwszDefExt) DsoMemFree(pwszDefExt);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
    case dsoDialogNew: // Get either ProgID or File to create new object from...
 | 
						|
        if (SUCCEEDED(DsoGetOleInsertObjectFromUser(m_hwnd, L"Insert New Document Object",
 | 
						|
            (IOF_SELECTCREATENEW | IOF_DISABLELINK | IOF_DISABLEDISPLAYASICON | IOF_HIDECHANGEICON),
 | 
						|
            TRUE, FALSE, &bstr, NULL)))
 | 
						|
        {
 | 
						|
			hr = CreateNew(bstr);
 | 
						|
			SysFreeString(bstr);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
    default: MessageBeep(0);
 | 
						|
    }
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::SetTempServerLock
 | 
						|
//
 | 
						|
//  Sets up lock of OLE server to make unload and new load of files faster
 | 
						|
//  and to avoid race conditions on reload of file.
 | 
						|
//
 | 
						|
STDMETHODIMP CDsoFramerControl::SetTempServerLock(BOOL fLock)
 | 
						|
{
 | 
						|
    HRESULT hr = S_FALSE;
 | 
						|
    TRACE1("CDsoFramerControl::SetTempServerLock(%d)\n", fLock);
 | 
						|
 | 
						|
    if (fLock)
 | 
						|
    {
 | 
						|
        CLSID *pclsid;
 | 
						|
 | 
						|
     // First get the the CLSID of the current loaded object...
 | 
						|
        pclsid = m_pDocObjFrame->GetServerCLSID();
 | 
						|
 | 
						|
     // If we already have a lock, determine if user is asking us to lock
 | 
						|
     // the same server (we only lock once for a given server type)...
 | 
						|
		if (m_pServerLock)
 | 
						|
		{
 | 
						|
            if (*(m_pServerLock->GetServerCLSID()) == *pclsid)
 | 
						|
                return S_FALSE;
 | 
						|
 | 
						|
         // If the current document is from a different server, free the old lock...
 | 
						|
            hr = SetTempServerLock(FALSE);
 | 
						|
			ASSERT(SUCCEEDED(hr)); // Sanity check in debug...
 | 
						|
		}
 | 
						|
 | 
						|
     // To lock the server, just make a dummy OLE object and don't ever site it...
 | 
						|
        m_pServerLock = CDsoDocObject::CreateInstance((IDsoDocObjectSite*)&m_xDsoDocObjectSite);
 | 
						|
        hr = ((m_pServerLock) ? m_pServerLock->CreateDocObject(*pclsid) : E_OUTOFMEMORY);
 | 
						|
        if (SUCCEEDED(hr))
 | 
						|
        {
 | 
						|
			hr = m_pServerLock->SetRunningServerLock(TRUE);
 | 
						|
 | 
						|
          // If we lock Excel, it steals focus from this host to the lock object, so we
 | 
						|
          // need to take it back so the real object isn't mixed up state...
 | 
						|
            if (SUCCEEDED(hr) && (m_pServerLock->IsExcelObject()) && (m_fAppActive))
 | 
						|
            {
 | 
						|
                OnAppActivationChange(TRUE, 0);
 | 
						|
            }
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
            delete m_pServerLock;
 | 
						|
            m_pServerLock = NULL;
 | 
						|
        }
 | 
						|
 | 
						|
	}
 | 
						|
	else if (m_pServerLock)
 | 
						|
	{
 | 
						|
        SEH_TRY
 | 
						|
			hr = m_pServerLock->SetRunningServerLock(FALSE);
 | 
						|
            hr = m_pServerLock->Close();
 | 
						|
        SEH_EXCEPT(hr)
 | 
						|
 | 
						|
		ASSERT(SUCCEEDED(hr)); // Sanity check in debug...
 | 
						|
        delete m_pServerLock;
 | 
						|
        m_pServerLock = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::ResetFrameHook
 | 
						|
//
 | 
						|
//  Allows host to reset the frame hook. 
 | 
						|
//
 | 
						|
STDMETHODIMP CDsoFramerControl::ResetFrameHook(HWND hwndFrameWindow)
 | 
						|
{
 | 
						|
	DWORD dwProcessId;
 | 
						|
	TRACE1("CDsoFramerControl::ResetFrameHook(%d)\n", hwndFrameWindow);
 | 
						|
 | 
						|
 // If the control is in modal state, we can't do anything...
 | 
						|
    if ((m_fModalState) || (m_fNoInteractive))
 | 
						|
        return ProvideErrorInfo(DSO_E_INMODALSTATE);
 | 
						|
 | 
						|
 // Verify that hwnd passed is a valid window handle and belogs to same thread
 | 
						|
 // as the control for parenting purposes...
 | 
						|
	if ((hwndFrameWindow) && (!IsWindow(hwndFrameWindow) || 
 | 
						|
		 (GetWindowThreadProcessId(hwndFrameWindow, &dwProcessId), dwProcessId != GetCurrentProcessId())))
 | 
						|
			return E_INVALIDARG;
 | 
						|
 | 
						|
 // We must have a window already created for this to work...
 | 
						|
	if ((m_hwnd == NULL) || !IsWindow(m_hwnd) ||
 | 
						|
		(m_hwndParent == NULL) || !IsWindow(m_hwndParent))
 | 
						|
		return E_ACCESSDENIED;
 | 
						|
 | 
						|
 // Detach from the current window (removing that hook if this is the last component)...
 | 
						|
	if (m_pHookManager)
 | 
						|
	{
 | 
						|
		HRESULT hr = m_pHookManager->DetachComponent(m_hwnd);
 | 
						|
		if (FAILED(hr)) return hr;
 | 
						|
		m_pHookManager = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
 // Now attach to the new parent window (or reattach based on the parent from our window)...
 | 
						|
	m_pHookManager = CDsoFrameHookManager::RegisterFramerControl((hwndFrameWindow ? hwndFrameWindow : m_hwndParent), m_hwnd);
 | 
						|
	if (m_pHookManager == NULL) return E_FAIL;
 | 
						|
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::RaiseActivationEvent
 | 
						|
//
 | 
						|
//  Called to raise component change event on activation switch.
 | 
						|
//
 | 
						|
STDMETHODIMP_(void) CDsoFramerControl::RaiseActivationEvent(BOOL fActive)
 | 
						|
{
 | 
						|
    VARIANT rgargs[1]; rgargs[0].vt = VT_BOOL;
 | 
						|
    rgargs[0].boolVal = (fActive ? VARIANT_TRUE : VARIANT_FALSE);
 | 
						|
    RaiseAutomationEvent(DSOF_DISPID_ACTIVATE, 1, rgargs);
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::ControlWindowProc
 | 
						|
//
 | 
						|
//  The window proc for our control.
 | 
						|
//
 | 
						|
STDMETHODIMP_(LRESULT) CDsoFramerControl::ControlWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	CDsoFramerControl* pCtl = (CDsoFramerControl*)GetWindowLong(hwnd, GWL_USERDATA);
 | 
						|
	if (pCtl)
 | 
						|
	{
 | 
						|
		switch (msg)
 | 
						|
		{
 | 
						|
			case WM_PAINT:
 | 
						|
			{
 | 
						|
				// call the OnDraw routine.
 | 
						|
				PAINTSTRUCT ps;
 | 
						|
				RECT        rc;
 | 
						|
				HDC         hdc;
 | 
						|
				hdc = BeginPaint(hwnd, &ps);
 | 
						|
				GetClientRect(hwnd, &rc);
 | 
						|
				pCtl->OnDraw(DVASPECT_CONTENT, hdc, (RECT*)&rc, NULL, NULL, TRUE);
 | 
						|
				EndPaint(hwnd, &ps);
 | 
						|
			}
 | 
						|
			break;
 | 
						|
 | 
						|
			case WM_SIZE:
 | 
						|
				pCtl->OnResize();
 | 
						|
				break;
 | 
						|
 | 
						|
			case WM_DESTROY:
 | 
						|
				pCtl->OnDestroyWindow();
 | 
						|
				SetWindowLong(hwnd, GWL_USERDATA, 0);
 | 
						|
				break;
 | 
						|
 | 
						|
			case WM_SETFOCUS:
 | 
						|
			case WM_KILLFOCUS:
 | 
						|
                pCtl->OnCtrlFocusChange((BOOL)(msg == WM_SETFOCUS), (HWND)wParam);
 | 
						|
				break;
 | 
						|
 | 
						|
			case WM_MOUSEMOVE:
 | 
						|
				pCtl->OnMouseMove(LOWORD(lParam), HIWORD(lParam));
 | 
						|
				break;
 | 
						|
 | 
						|
			case WM_LBUTTONDOWN:
 | 
						|
				pCtl->OnButtonDown(LOWORD(lParam), HIWORD(lParam));
 | 
						|
				break;
 | 
						|
 | 
						|
			case DSO_WM_ASYNCH_OLECOMMAND:
 | 
						|
                ODS(" -- Got DSO_WM_ASYNCH_OLECOMMAND -- \n");
 | 
						|
				pCtl->OnToolbarAction((DWORD)wParam);
 | 
						|
				break;
 | 
						|
 | 
						|
			case DSO_WM_ASYNCH_STATECHANGE:
 | 
						|
                TRACE1(" -- Got DSO_WM_ASYNCH_STATECHANGE %d --\n", wParam);
 | 
						|
                {
 | 
						|
                    BOOL fCondition = (lParam != 0);
 | 
						|
                    switch (wParam)
 | 
						|
                    {
 | 
						|
                    case DSO_STATE_MODAL:
 | 
						|
                        pCtl->UpdateModalState(fCondition, FALSE);
 | 
						|
                        break;
 | 
						|
                    case DSO_STATE_ACTIVATION:
 | 
						|
                        pCtl->RaiseActivationEvent(fCondition);
 | 
						|
                        break;
 | 
						|
                    case DSO_STATE_INTERACTIVE:
 | 
						|
                        pCtl->UpdateInteractiveState(fCondition);
 | 
						|
                        break;
 | 
						|
					case DSO_STATE_RETURNFROMMODAL:
 | 
						|
						{
 | 
						|
							if ((pCtl->m_fModalState == FALSE) && 
 | 
						|
                                (pCtl->m_fAppActive))
 | 
						|
							{
 | 
						|
                                pCtl->OnUIFocusChange(TRUE);
 | 
						|
							}
 | 
						|
						}
 | 
						|
						break;
 | 
						|
 | 
						|
					default:
 | 
						|
						ODS(" -- Unknown State Change!! --\n");
 | 
						|
						break;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                break;
 | 
						|
 | 
						|
			case DSO_WM_HOOK_NOTIFY_COMPACTIVE:
 | 
						|
				pCtl->OnComponentActivationChange((BOOL)wParam);
 | 
						|
                wParam = lParam; lParam = 0;
 | 
						|
                // falls through with wParam swapped...
 | 
						|
 | 
						|
			case DSO_WM_HOOK_NOTIFY_APPACTIVATE:
 | 
						|
				pCtl->OnAppActivationChange((BOOL)wParam, (DWORD)lParam);
 | 
						|
				break;
 | 
						|
 | 
						|
			case DSO_WM_HOOK_NOTIFY_SYNCPAINT:
 | 
						|
				pCtl->OnSyncPaint();
 | 
						|
				break;
 | 
						|
 | 
						|
			case DSO_WM_HOOK_NOTIFY_PALETTECHANGE:
 | 
						|
				pCtl->OnPaletteChanged((HWND)wParam);
 | 
						|
				break;
 | 
						|
 | 
						|
            case WM_ENABLE:
 | 
						|
                pCtl->OnWindowEnable((BOOL)wParam);
 | 
						|
                break;
 | 
						|
 | 
						|
			case WM_MENUSELECT:
 | 
						|
			case WM_DRAWITEM:
 | 
						|
			case WM_MEASUREITEM:
 | 
						|
			case WM_ENTERIDLE:
 | 
						|
			case WM_INITMENU:
 | 
						|
			case WM_INITMENUPOPUP:
 | 
						|
			case WM_COMMAND:
 | 
						|
				pCtl->OnMenuMessage(msg, wParam, lParam);
 | 
						|
				break;
 | 
						|
 | 
						|
            case WM_DROPFILES:
 | 
						|
                pCtl->OnDropFile((HDROP)wParam);
 | 
						|
                break;
 | 
						|
 | 
						|
            case WM_TIMER:
 | 
						|
                pCtl->OnTimer((UINT)wParam);
 | 
						|
                break;
 | 
						|
 | 
						|
            case WM_SYSCOMMAND:
 | 
						|
                if ((wParam & 0xFFF0) == SC_KEYMENU)
 | 
						|
                {
 | 
						|
                    if (pCtl->m_xDsoDocObjectSite.SysMenuCommand((UINT)lParam) == S_OK)
 | 
						|
                    {
 | 
						|
                        ODS(" -- Eat SC_KeyMenu message --\n");
 | 
						|
                        return 1;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                // fall through to defwinproc...
 | 
						|
 | 
						|
            default:
 | 
						|
                return DefWindowProc(hwnd, msg, wParam, lParam);
 | 
						|
 | 
						|
		}
 | 
						|
 | 
						|
        return (LRESULT)0;
 | 
						|
	}
 | 
						|
 | 
						|
	return DefWindowProc(hwnd, msg, wParam, lParam);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// OCX Interfaces for CDsoFramerControl
 | 
						|
//
 | 
						|
//  NOTE: The automation interfaces are implemented in dsofauto.cpp.
 | 
						|
//  The interfaces that follow are largely the interfaces used by the
 | 
						|
//  OCX host for normal control containment.
 | 
						|
//
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XInternalUnknown -- Internal IUnknown interface
 | 
						|
//     !!! Controls lifetime of CDsoFramerControl !!!
 | 
						|
//
 | 
						|
//   STDMETHODIMP         QueryInterface(REFIID riid, void ** ppv);
 | 
						|
//   STDMETHODIMP_(ULONG) AddRef(void);
 | 
						|
//   STDMETHODIMP_(ULONG) Release(void);
 | 
						|
//
 | 
						|
STDMETHODIMP CDsoFramerControl::XInternalUnknown::QueryInterface(REFIID riid, void** ppv)
 | 
						|
{
 | 
						|
 // ODS("CDsoFramerControl::InternalQueryInterface\n");
 | 
						|
	CHECK_NULL_RETURN(ppv, E_POINTER);
 | 
						|
	
 | 
						|
	HRESULT hr = S_OK;
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, InternalUnknown);
 | 
						|
 | 
						|
	if (IID_IUnknown == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IUnknown*)this;
 | 
						|
	}
 | 
						|
	else if ((IID_IDispatch == riid) || (IID__FramerControl == riid))
 | 
						|
	{
 | 
						|
		*ppv = (_FramerControl*)pThis;
 | 
						|
	}
 | 
						|
	else if (IID_IOleObject == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IOleObject*)&(pThis->m_xOleObject);
 | 
						|
	}
 | 
						|
	else if (IID_IOleControl == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IOleControl*)&(pThis->m_xOleControl);
 | 
						|
	}
 | 
						|
	else if (IID_IPersistPropertyBag == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IPersistPropertyBag*)&(pThis->m_xPersistPropertyBag);
 | 
						|
	}
 | 
						|
	else if ((IID_IPersistStreamInit == riid) || (IID_IPersistStream == riid) || (IID_IPersist == riid))
 | 
						|
	{
 | 
						|
		*ppv = (IPersistStreamInit*)&(pThis->m_xPersistStreamInit);
 | 
						|
	}
 | 
						|
	else if ((IID_IOleInPlaceObject == riid) || (IID_IOleWindow == riid))
 | 
						|
	{
 | 
						|
		*ppv = (IOleInPlaceObject*)&(pThis->m_xOleInplaceObject);
 | 
						|
	}	
 | 
						|
	else if (IID_IOleInPlaceActiveObject == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IOleInPlaceActiveObject*)&(pThis->m_xOleInplaceActiveObject);
 | 
						|
	}
 | 
						|
	else if ((IID_IViewObjectEx == riid) || (IID_IViewObject == riid) || (IID_IViewObject2 == riid))
 | 
						|
	{
 | 
						|
		*ppv = (IViewObjectEx*)&(pThis->m_xViewObjectEx);
 | 
						|
	}
 | 
						|
    else if (IID_IDataObject == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IDataObject*)&(pThis->m_xDataObject);
 | 
						|
	}
 | 
						|
	else if (IID_ISupportErrorInfo == riid)
 | 
						|
	{
 | 
						|
		*ppv = (ISupportErrorInfo*)&(pThis->m_xSupportErrorInfo);
 | 
						|
	}
 | 
						|
	else if (IID_IProvideClassInfo == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IProvideClassInfo*)&(pThis->m_xProvideClassInfo);
 | 
						|
	}
 | 
						|
	else if (IID_IConnectionPointContainer == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IConnectionPointContainer*)&(pThis->m_xConnectionPointContainer);
 | 
						|
	}
 | 
						|
	else if (IID_IConnectionPoint == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IConnectionPoint*)&(pThis->m_xConnectionPoint);
 | 
						|
	}
 | 
						|
	else if (IID_IEnumConnectionPoints == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IEnumConnectionPoints*)&(pThis->m_xEnumConnectionPoints);
 | 
						|
	}
 | 
						|
    else if (IID_IPersistStorage == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IPersistStorage*)&(pThis->m_xPersistStorage);
 | 
						|
	}
 | 
						|
	else if (IID_IObjectSafety == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IObjectSafety*)&(pThis->m_xObjectSafety);
 | 
						|
	}
 | 
						|
    else if (IID_IOleCommandTarget == riid)
 | 
						|
	{
 | 
						|
		*ppv = (IOleCommandTarget*)&(pThis->m_xOleCommandTarget);
 | 
						|
	}
 | 
						|
	else if ((IID_IDsoDocObjectSite == riid) || (IID_IServiceProvider == riid))
 | 
						|
	{
 | 
						|
		*ppv = (IDsoDocObjectSite*)&(pThis->m_xDsoDocObjectSite);
 | 
						|
	}
 | 
						|
    else 
 | 
						|
	{
 | 
						|
		*ppv = NULL;
 | 
						|
		hr = E_NOINTERFACE;
 | 
						|
	}
 | 
						|
 | 
						|
	if (NULL != *ppv) // AddRef those interfaces we will return...
 | 
						|
        ((IUnknown*)(*ppv))->AddRef();
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP_(ULONG) CDsoFramerControl::XInternalUnknown::AddRef(void)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, InternalUnknown);
 | 
						|
	//TRACE1("CDsoFramerControl::InternalAddRef - %d\n", (pThis->m_cRef + 1));
 | 
						|
    return ++(pThis->m_cRef);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP_(ULONG) CDsoFramerControl::XInternalUnknown::Release(void)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, InternalUnknown);
 | 
						|
	//TRACE1("CDsoFramerControl::InternalRelease - %d\n", (pThis->m_cRef - 1));
 | 
						|
    if (0 != --(pThis->m_cRef)) return (pThis->m_cRef);
 | 
						|
	ODS("CDsoFramerControl delete\n");
 | 
						|
	InterlockedDecrement((LPLONG)&v_cLocks);
 | 
						|
	delete pThis; return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XPersistStreamInit -- IPersistStreamInit Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP GetClassID(CLSID *pClassID);
 | 
						|
//	 STDMETHODIMP IsDirty(void);
 | 
						|
//	 STDMETHODIMP Load(LPSTREAM pStm);
 | 
						|
//	 STDMETHODIMP Save(LPSTREAM pStm, BOOL fClearDirty);
 | 
						|
//	 STDMETHODIMP GetSizeMax(ULARGE_INTEGER* pcbSize);
 | 
						|
//	 STDMETHODIMP InitNew(void);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, PersistStreamInit)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStreamInit::GetClassID(CLSID *pClassID)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XPersistStreamInit::GetClassID\n");
 | 
						|
	if (pClassID) *pClassID = CLSID_FramerControl;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStreamInit::IsDirty(void)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStreamInit);
 | 
						|
    ODS("CDsoFramerControl::XPersistStreamInit::IsDirty\n");
 | 
						|
    return (pThis->m_fDirty) ? S_OK : S_FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#define STREAMHDR_SIGNATURE_OLD 0x1234ABCD  // Signature to identify our format (avoid crashes!)
 | 
						|
#define STREAMHDR_SIGNATURE_NEW 0xD501D501  // Signature to identify our format (avoid crashes!)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStreamInit::Load(LPSTREAM pStm)
 | 
						|
{
 | 
						|
    HRESULT hr;
 | 
						|
	DWORD dwSig, dwT;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStreamInit);
 | 
						|
    ODS("CDsoFramerControl::XPersistStreamInit::Load\n");
 | 
						|
 | 
						|
 // look for our header structure, so we can verify stream validity.
 | 
						|
    hr = pStm->Read(&dwSig, sizeof(DWORD), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    if ((dwSig != STREAMHDR_SIGNATURE_NEW) && 
 | 
						|
		(dwSig != STREAMHDR_SIGNATURE_OLD))
 | 
						|
        return E_UNEXPECTED;
 | 
						|
 | 
						|
 // we like the stream.  let's go load in our two properties.
 | 
						|
    hr = pStm->Read(&(pThis->m_Size), sizeof(SIZEL), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	DsoHimetricToPixels(&(pThis->m_Size.cx), &(pThis->m_Size.cy));
 | 
						|
 | 
						|
    hr = pStm->Read(&(pThis->m_clrBorderColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Read(&(pThis->m_clrBackColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Read(&(pThis->m_clrForeColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Read(&(pThis->m_clrTBarColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Read(&(pThis->m_clrTBarTextColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Read(&dwT, sizeof(DWORD), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	pThis->m_fBorderStyle  = LOBYTE(LOWORD(dwT));
 | 
						|
    pThis->m_fShowMenuBar  = HIBYTE(LOWORD(dwT));
 | 
						|
	pThis->m_fShowToolbars = LOBYTE(HIWORD(dwT));
 | 
						|
	pThis->m_fShowTitlebar = HIBYTE(HIWORD(dwT));
 | 
						|
 | 
						|
    hr = pStm->Read(&dwT, sizeof(DWORD), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	if (dwT)
 | 
						|
	{
 | 
						|
		LPWSTR pwsz = (LPWSTR)DsoMemAlloc(dwT+2);
 | 
						|
		if (pwsz)
 | 
						|
		{
 | 
						|
			hr = pStm->Read(pwsz, dwT, NULL);
 | 
						|
			if (SUCCEEDED(hr))
 | 
						|
				pThis->m_bstrCustomCaption = SysAllocString(pwsz);
 | 
						|
		}
 | 
						|
		DsoMemFree(pwsz);
 | 
						|
	}
 | 
						|
 | 
						|
 // Read in new properties for 1.3 version control...
 | 
						|
	if (dwSig == STREAMHDR_SIGNATURE_NEW)
 | 
						|
	{
 | 
						|
		DWORD dwValue;
 | 
						|
 | 
						|
		hr = pStm->Read(&dwValue, sizeof(DWORD), NULL);
 | 
						|
		RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
		pThis->m_lActivationPolicy  = LOWORD(dwValue);
 | 
						|
		pThis->m_lHookPolicy		= HIWORD(dwValue);
 | 
						|
 | 
						|
		hr = pStm->Read(&dwValue, sizeof(DWORD), NULL);
 | 
						|
		RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
		pThis->m_fDisableMenuAccel = LOBYTE(LOWORD(dwT));
 | 
						|
	}
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStreamInit::Save(LPSTREAM pStm, BOOL fClearDirty)
 | 
						|
{
 | 
						|
    HRESULT hr;
 | 
						|
	DWORD   dwT, dwSig = STREAMHDR_SIGNATURE_NEW;
 | 
						|
	SIZEL   slSize;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStreamInit);
 | 
						|
    ODS("CDsoFramerControl::XPersistStreamInit::Save\n");
 | 
						|
 | 
						|
 // first thing to do is write out our stream sig...
 | 
						|
    hr = pStm->Write(&dwSig, sizeof(DWORD), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
 // the only properties we're currently persisting here are the size
 | 
						|
 // properties for this control.  make sure we do that in HiMetric
 | 
						|
	slSize = pThis->m_Size;
 | 
						|
	DsoPixelsToHimetric(&(slSize.cx), &(slSize.cy));
 | 
						|
 | 
						|
    hr = pStm->Write(&slSize, sizeof(SIZEL), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Write(&(pThis->m_clrBorderColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Write(&(pThis->m_clrBackColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Write(&(pThis->m_clrForeColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Write(&(pThis->m_clrTBarColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    hr = pStm->Write(&(pThis->m_clrTBarTextColor), sizeof(OLE_COLOR), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	dwT = (DWORD)MAKELONG(
 | 
						|
        MAKEWORD((BYTE)(pThis->m_fBorderStyle), (BYTE)(pThis->m_fShowMenuBar)),
 | 
						|
		MAKEWORD((BYTE)(pThis->m_fShowToolbars), (BYTE)(pThis->m_fShowTitlebar)));
 | 
						|
 | 
						|
    hr = pStm->Write(&dwT, sizeof(DWORD), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	dwT = 0;
 | 
						|
	if (pThis->m_bstrCustomCaption)
 | 
						|
		dwT = SysStringByteLen(pThis->m_bstrCustomCaption);
 | 
						|
 | 
						|
	hr = pStm->Write(&dwT, sizeof(DWORD), NULL);
 | 
						|
	RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	if (dwT)
 | 
						|
	{
 | 
						|
		hr = pStm->Write(pThis->m_bstrCustomCaption, dwT, NULL);
 | 
						|
		RETURN_ON_FAILURE(hr);
 | 
						|
	}
 | 
						|
 | 
						|
 // Version 1.3 added properties...
 | 
						|
	dwT = (DWORD)MAKELONG((WORD)(pThis->m_lActivationPolicy), (WORD)(pThis->m_lHookPolicy));
 | 
						|
    hr = pStm->Write(&dwT, sizeof(DWORD), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	dwT = (DWORD)MAKELONG(MAKEWORD((BYTE)(pThis->m_fDisableMenuAccel), 0), 0);
 | 
						|
    hr = pStm->Write(&dwT, sizeof(DWORD), NULL);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
 // clear out dirty flag and notify that we're done with save.
 | 
						|
    if (fClearDirty)
 | 
						|
        pThis->m_fDirty = FALSE;
 | 
						|
 | 
						|
    if (pThis->m_pOleAdviseHolder)
 | 
						|
        pThis->m_pOleAdviseHolder->SendOnSave();
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStreamInit::GetSizeMax(ULARGE_INTEGER *pcbSize)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XPersistStreamInit::GetSizeMax\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStreamInit::InitNew(void)
 | 
						|
{
 | 
						|
    METHOD_PROLOGUE(CDsoFramerControl, PersistStreamInit);
 | 
						|
    ODS("CDsoFramerControl::XPersistStreamInit::InitNew\n");
 | 
						|
 // If we are new control, we are dirty by default...
 | 
						|
	pThis->m_fDirty	= TRUE;  
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XPersistPropertyBag -- IPersistPropertyBag Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP GetClassID(CLSID *pClassID);
 | 
						|
//	 STDMETHODIMP InitNew();
 | 
						|
//	 STDMETHODIMP Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog);
 | 
						|
//	 STDMETHODIMP Save(IPropertyBag* pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, PersistPropertyBag)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistPropertyBag::GetClassID(CLSID *pClassID)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XPersistPropertyBag::GetClassID\n");
 | 
						|
	if (pClassID) *pClassID = CLSID_FramerControl;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistPropertyBag::InitNew()
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistPropertyBag);
 | 
						|
    ODS("CDsoFramerControl::XPersistPropertyBag::InitNew\n");
 | 
						|
	return pThis->m_xPersistStreamInit.InitNew();
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistPropertyBag::Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog)
 | 
						|
{
 | 
						|
    VARIANT v;
 | 
						|
    HRESULT hr;
 | 
						|
	SIZEL sl = {5000, 3000};
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistPropertyBag);
 | 
						|
    ODS("CDsoFramerControl::XPersistPropertyBag::Load\n");
 | 
						|
 | 
						|
    v.vt = VT_I4;
 | 
						|
	v.lVal = 0;
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"_ExtentX", &v, pErrorLog);
 | 
						|
    if (SUCCEEDED(hr)){sl.cx = v.lVal;}
 | 
						|
    
 | 
						|
    v.lVal = 0;
 | 
						|
    hr = pPropBag->Read(L"_ExtentY", &v, pErrorLog);
 | 
						|
    if (SUCCEEDED(hr)){sl.cy = v.lVal;}
 | 
						|
 | 
						|
	DsoHimetricToPixels(&(sl.cx), &(sl.cy));
 | 
						|
	pThis->m_Size = sl;
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"Titlebar", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_fShowTitlebar = v.boolVal;}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"Toolbars", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_fShowToolbars = v.boolVal;}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"BorderStyle", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_fBorderStyle = v.lVal;}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"BorderColor", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_clrBorderColor = v.lVal;}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"BackColor", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_clrBackColor = v.lVal;}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"ForeColor", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_clrForeColor = v.lVal;}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"TitlebarColor", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_clrTBarColor = v.lVal;}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"TitlebarTextColor", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_clrTBarTextColor = v.lVal;}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"Caption", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr))
 | 
						|
	{
 | 
						|
		LPWSTR pwsz = LPWSTR_FROM_VARIANT(v);
 | 
						|
		if (pwsz) pThis->m_bstrCustomCaption = SysAllocString(pwsz);
 | 
						|
		VariantClear(&v);
 | 
						|
	}
 | 
						|
 | 
						|
    pThis->m_fShowMenuBar = FALSE;
 | 
						|
    hr = pPropBag->Read(L"Menubar", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_fShowMenuBar = BOOL_FROM_VARIANT(v, FALSE);}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"ActivationPolicy", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_lActivationPolicy = LONG_FROM_VARIANT(v, 0);}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"FrameHookPolicy", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_lHookPolicy = LONG_FROM_VARIANT(v, 0);}
 | 
						|
 | 
						|
    hr = pPropBag->Read(L"MenuAccelerators", &v, pErrorLog);
 | 
						|
	if (SUCCEEDED(hr)){pThis->m_fDisableMenuAccel = !BOOL_FROM_VARIANT(v, TRUE);}
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistPropertyBag::Save(IPropertyBag* pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties)
 | 
						|
{
 | 
						|
    HRESULT hr;
 | 
						|
    VARIANT v;
 | 
						|
    SIZEL   sl;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistPropertyBag);
 | 
						|
    ODS("CDsoFramerControl::XPersistPropertyBag::Save\n");
 | 
						|
 | 
						|
	sl = pThis->m_Size;
 | 
						|
    DsoPixelsToHimetric(&(sl.cx), &(sl.cy));
 | 
						|
 | 
						|
    v.vt = VT_I4; v.lVal = sl.cx;
 | 
						|
    hr = pPropBag->Write(L"_ExtentX", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.lVal = sl.cy;
 | 
						|
    hr = pPropBag->Write(L"_ExtentY", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.lVal = pThis->m_clrBorderColor;
 | 
						|
    hr = pPropBag->Write(L"BorderColor", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.lVal = pThis->m_clrBackColor;
 | 
						|
    hr = pPropBag->Write(L"BackColor", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.lVal = pThis->m_clrForeColor;
 | 
						|
    hr = pPropBag->Write(L"ForeColor", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.lVal = pThis->m_clrTBarColor;
 | 
						|
    hr = pPropBag->Write(L"TitlebarColor", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.lVal = pThis->m_clrTBarTextColor;
 | 
						|
    hr = pPropBag->Write(L"TitlebarTextColor", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.lVal = pThis->m_fBorderStyle;
 | 
						|
    hr = pPropBag->Write(L"BorderStyle", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.vt = VT_BOOL;	v.boolVal = pThis->m_fShowTitlebar;
 | 
						|
    hr = pPropBag->Write(L"Titlebar", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	v.boolVal = pThis->m_fShowToolbars;
 | 
						|
    hr = pPropBag->Write(L"Toolbars", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
	if (pThis->m_bstrCustomCaption)
 | 
						|
	{
 | 
						|
		v.vt = VT_BSTR;	v.bstrVal = pThis->m_bstrCustomCaption;
 | 
						|
		hr = pPropBag->Write(L"Caption", &v);
 | 
						|
		RETURN_ON_FAILURE(hr);
 | 
						|
	}
 | 
						|
 | 
						|
    v.vt = VT_BOOL; v.boolVal = pThis->m_fShowMenuBar;
 | 
						|
    hr = pPropBag->Write(L"Menubar", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.vt = VT_I4; v.lVal = pThis->m_lActivationPolicy;
 | 
						|
    hr = pPropBag->Write(L"ActivationPolicy", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.vt = VT_I4; v.lVal = pThis->m_lHookPolicy;
 | 
						|
    hr = pPropBag->Write(L"FrameHookPolicy", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
    v.vt = VT_BOOL;	v.boolVal = !(pThis->m_fDisableMenuAccel);
 | 
						|
    hr = pPropBag->Write(L"MenuAccelerators", &v);
 | 
						|
    RETURN_ON_FAILURE(hr);
 | 
						|
 | 
						|
 // now clear the dirty flag and send out notification 
 | 
						|
 // that we're done.  
 | 
						|
    if (fClearDirty)
 | 
						|
        pThis->m_fDirty = FALSE;
 | 
						|
 | 
						|
    if (pThis->m_pOleAdviseHolder)
 | 
						|
        pThis->m_pOleAdviseHolder->SendOnSave();
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XPersistStorage -- IPersistStorage Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP GetClassID(CLSID *pClassID);
 | 
						|
//	 STDMETHODIMP IsDirty(void);
 | 
						|
//	 STDMETHODIMP InitNew(LPSTORAGE pStg);
 | 
						|
//	 STDMETHODIMP Load(LPSTORAGE pStg);
 | 
						|
//	 STDMETHODIMP Save(LPSTORAGE pStg, BOOL fSameAsLoad);
 | 
						|
//	 STDMETHODIMP SaveCompleted(LPSTORAGE pStg);
 | 
						|
//	 STDMETHODIMP HandsOffStorage(void);
 | 
						|
//	 
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, PersistStorage)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStorage::GetClassID(CLSID *pClassID)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XPersistStorage::GetClassID\n");
 | 
						|
	if (pClassID) *pClassID = CLSID_FramerControl;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStorage::IsDirty(void)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStorage);
 | 
						|
    ODS("CDsoFramerControl::XPersistStorage::IsDirty\n");
 | 
						|
    return (pThis->m_fDirty) ? S_OK : S_FALSE;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStorage::InitNew(LPSTORAGE pStg)
 | 
						|
{
 | 
						|
    HRESULT hr;
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStorage);
 | 
						|
    ODS("CDsoFramerControl::XPersistStorage::InitNew\n");
 | 
						|
 | 
						|
    CHECK_NULL_RETURN(pStg, E_POINTER);
 | 
						|
    SAFE_RELEASE_INTERFACE(pThis->m_pOleStorage);
 | 
						|
 | 
						|
    hr = pThis->m_xPersistStreamInit.InitNew();
 | 
						|
    if (SUCCEEDED(hr))
 | 
						|
        { SAFE_SET_INTERFACE(pThis->m_pOleStorage, pStg); };
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStorage::Load(LPSTORAGE pStg)
 | 
						|
{
 | 
						|
    HRESULT hr;
 | 
						|
    IStream* pstm;
 | 
						|
    DWORD dwStmMode = (STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE);
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStorage);
 | 
						|
    ODS("CDsoFramerControl::XPersistStorage::Load\n");
 | 
						|
 | 
						|
    CHECK_NULL_RETURN(pStg, E_POINTER);
 | 
						|
    SAFE_RELEASE_INTERFACE(pThis->m_pOleStorage);
 | 
						|
 | 
						|
    hr = pStg->OpenStream(L"DsoFrameCtlContents", 0, dwStmMode, 0, &pstm);
 | 
						|
    if (SUCCEEDED(hr) && (pstm))
 | 
						|
    {
 | 
						|
        hr = pThis->m_xPersistStreamInit.Load(pstm);
 | 
						|
        if (SUCCEEDED(hr))
 | 
						|
            { SAFE_SET_INTERFACE(pThis->m_pOleStorage, pStg); };
 | 
						|
 | 
						|
        pstm->Release();
 | 
						|
    }
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStorage::Save(LPSTORAGE pStg, BOOL fSameAsLoad)
 | 
						|
{
 | 
						|
    HRESULT hr;
 | 
						|
    IStream* pstm;
 | 
						|
    DWORD dwStmMode = (STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE);
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStorage);
 | 
						|
    ODS("CDsoFramerControl::XPersistStorage::Save\n");
 | 
						|
 | 
						|
	if (fSameAsLoad)
 | 
						|
	{
 | 
						|
		if ((pThis->m_pOleStorage == NULL) || 
 | 
						|
			((pStg) && (pStg != pThis->m_pOleStorage)))
 | 
						|
		{
 | 
						|
			SAFE_RELEASE_INTERFACE(pThis->m_pOleStorage);
 | 
						|
			SAFE_SET_INTERFACE(pThis->m_pOleStorage, pStg);
 | 
						|
		}
 | 
						|
 | 
						|
		CHECK_NULL_RETURN(pThis->m_pOleStorage, E_POINTER);
 | 
						|
		pStg = pThis->m_pOleStorage;
 | 
						|
	}
 | 
						|
 | 
						|
    CHECK_NULL_RETURN(pStg, E_POINTER);
 | 
						|
 | 
						|
    hr = pStg->OpenStream(L"DsoFrameCtlContents", 0, dwStmMode, 0, &pstm);
 | 
						|
    if (hr == STG_E_FILENOTFOUND)
 | 
						|
        hr = pStg->CreateStream(L"DsoFrameCtlContents", dwStmMode, 0, 0, &pstm);
 | 
						|
 | 
						|
    if (SUCCEEDED(hr) && (pstm))
 | 
						|
    {
 | 
						|
        hr = pThis->m_xPersistStreamInit.Save(pstm, FALSE);
 | 
						|
        pstm->Release();
 | 
						|
    }
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStorage::SaveCompleted(LPSTORAGE pStg)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStorage);
 | 
						|
    ODS("CDsoFramerControl::XPersistStorage::SaveCompleted\n");
 | 
						|
    pThis->m_fDirty = FALSE;
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XPersistStorage::HandsOffStorage(void)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, PersistStorage);
 | 
						|
    ODS("CDsoFramerControl::XPersistStorage::HandsOffStorage\n");
 | 
						|
    SAFE_RELEASE_INTERFACE(pThis->m_pOleStorage);
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XOleObject -- IOleObject Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP SetClientSite(IOleClientSite *pClientSite);
 | 
						|
//	 STDMETHODIMP GetClientSite(IOleClientSite **ppClientSite);
 | 
						|
//	 STDMETHODIMP SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj);
 | 
						|
//	 STDMETHODIMP Close(DWORD dwSaveOption);
 | 
						|
//	 STDMETHODIMP SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk);
 | 
						|
//	 STDMETHODIMP GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk);
 | 
						|
//	 STDMETHODIMP InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved);
 | 
						|
//	 STDMETHODIMP GetClipboardData(DWORD dwReserved, IDataObject **ppDataObject);
 | 
						|
//	 STDMETHODIMP DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect);
 | 
						|
//	 STDMETHODIMP EnumVerbs(IEnumOleVerb **ppEnumOleVerb);
 | 
						|
//	 STDMETHODIMP Update();
 | 
						|
//	 STDMETHODIMP IsUpToDate();
 | 
						|
//	 STDMETHODIMP GetUserClassID(CLSID *pClsid);
 | 
						|
//	 STDMETHODIMP GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType);
 | 
						|
//	 STDMETHODIMP SetExtent(DWORD dwDrawAspect, SIZEL *psizel);
 | 
						|
//	 STDMETHODIMP GetExtent(DWORD dwDrawAspect, SIZEL *psizel);
 | 
						|
//	 STDMETHODIMP Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection);
 | 
						|
//	 STDMETHODIMP Unadvise(DWORD dwConnection);
 | 
						|
//	 STDMETHODIMP EnumAdvise(IEnumSTATDATA **ppenumAdvise);
 | 
						|
//	 STDMETHODIMP GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus);
 | 
						|
//	 STDMETHODIMP SetColorScheme(LOGPALETTE *pLogpal);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleObject)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::SetClientSite(IOleClientSite *pClientSite)
 | 
						|
{
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::SetClientSite\n");
 | 
						|
 | 
						|
    SAFE_RELEASE_INTERFACE(pThis->m_pClientSite);
 | 
						|
    SAFE_RELEASE_INTERFACE(pThis->m_pControlSite);
 | 
						|
 | 
						|
 // store away the new client site
 | 
						|
    pThis->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 (pClientSite)
 | 
						|
	{
 | 
						|
        pClientSite->AddRef();
 | 
						|
        pClientSite->QueryInterface(IID_IOleControlSite, (void **)&(pThis->m_pControlSite));
 | 
						|
    }
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::GetClientSite(IOleClientSite **ppClientSite)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::GetClientSite\n");
 | 
						|
    if (ppClientSite) { SAFE_SET_INTERFACE(*ppClientSite, pThis->m_pClientSite); }
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::SetHostNames(LPCOLESTR /*szContainerApp*/, LPCOLESTR /*szContainerObj*/)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::SetHostNames\n");
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::Close(DWORD dwSaveOption)
 | 
						|
{
 | 
						|
	HRESULT hr;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::Close\n");
 | 
						|
 | 
						|
    if (pThis->m_fInPlaceActive)
 | 
						|
	{
 | 
						|
        hr = pThis->m_xOleInplaceObject.InPlaceDeactivate();
 | 
						|
        RETURN_ON_FAILURE(hr);
 | 
						|
    }
 | 
						|
 | 
						|
 // handle the save flag.
 | 
						|
    if ((pThis->m_fDirty) && (pThis->m_pClientSite) &&
 | 
						|
		(dwSaveOption == OLECLOSE_SAVEIFDIRTY || 
 | 
						|
		 dwSaveOption == OLECLOSE_PROMPTSAVE))
 | 
						|
	{
 | 
						|
		pThis->m_pClientSite->SaveObject();
 | 
						|
    }
 | 
						|
 | 
						|
    if (pThis->m_pOleAdviseHolder)
 | 
						|
        pThis->m_pOleAdviseHolder->SendOnClose();
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::SetMoniker(DWORD dwWhichMoniker, IMoniker *pmk)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::SetMoniker\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::GetMoniker\n");
 | 
						|
	if (ppmk) *ppmk = NULL;
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::InitFromData(IDataObject *pDataObject, BOOL fCreation, DWORD dwReserved)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::InitFromData\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::GetClipboardData(DWORD /*dwReserved*/, IDataObject **ppDataObject)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::GetClipboardData\n");
 | 
						|
	if (ppDataObject) *ppDataObject = NULL;
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::DoVerb\n");
 | 
						|
 | 
						|
    switch (iVerb)
 | 
						|
	{
 | 
						|
    case OLEIVERB_PRIMARY:
 | 
						|
    case OLEIVERB_SHOW:
 | 
						|
    case OLEIVERB_INPLACEACTIVATE:
 | 
						|
    case OLEIVERB_UIACTIVATE:
 | 
						|
        return pThis->InPlaceActivate(iVerb);
 | 
						|
 | 
						|
    case OLEIVERB_HIDE:
 | 
						|
        pThis->m_xOleInplaceObject.UIDeactivate();
 | 
						|
        if (pThis->m_fInPlaceVisible)
 | 
						|
            pThis->SetInPlaceVisible(FALSE);
 | 
						|
        return S_OK;
 | 
						|
    }
 | 
						|
 | 
						|
    return OLEOBJ_S_INVALIDVERB;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::EnumVerbs(IEnumOLEVERB **ppEnumOleVerb)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::EnumVerbs\n");
 | 
						|
	return OleRegEnumVerbs(CLSID_FramerControl, ppEnumOleVerb);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::Update()
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::Update\n");
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::IsUpToDate()
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::IsUpToDate\n");
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::GetUserClassID(CLSID *pClsid)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::GetUserClassID\n");
 | 
						|
	if (pClsid) *pClsid = CLSID_FramerControl;
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR *pszUserType)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::GetUserType\n");
 | 
						|
    return OleRegGetUserType(CLSID_FramerControl, dwFormOfType, pszUserType);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
 | 
						|
{
 | 
						|
    SIZEL sl;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::SetExtent\n");
 | 
						|
 | 
						|
	CHECK_NULL_RETURN(psizel, E_POINTER);
 | 
						|
	sl = *psizel;
 | 
						|
 | 
						|
 // we don't support any other aspects.
 | 
						|
    if (!(dwDrawAspect & DVASPECT_CONTENT))
 | 
						|
        return DV_E_DVASPECT;
 | 
						|
 | 
						|
 // change the units to pixels, and resize the control.
 | 
						|
    DsoHimetricToPixels(&(sl.cx), &(sl.cy));
 | 
						|
 | 
						|
 // if the size already matches the extents, then don't do anything
 | 
						|
 // and don't mark the control dirty.
 | 
						|
	if (sl.cx != pThis->m_Size.cx || sl.cy != pThis->m_Size.cy)
 | 
						|
	{
 | 
						|
		pThis->m_Size = sl;
 | 
						|
		pThis->m_fDirty = TRUE; // changing size should dirty
 | 
						|
 | 
						|
		if (pThis->m_fInPlaceActive)
 | 
						|
		{
 | 
						|
			RECT rect;  
 | 
						|
 | 
						|
		 // Use OnPosRectChange for older OCX containters and Access
 | 
						|
		 // who just refuses to get with the times (like me <g>)...
 | 
						|
			GetWindowRect(pThis->m_hwnd, &rect);
 | 
						|
			MapWindowPoints(NULL, pThis->m_hwndParent, (LPPOINT)&rect, 2);
 | 
						|
			rect.right = rect.left + sl.cx;
 | 
						|
			rect.bottom = rect.top + sl.cy;
 | 
						|
			pThis->m_pInPlaceSite->OnPosRectChange(&rect);
 | 
						|
 | 
						|
		 // Resize the window based on the new size...
 | 
						|
			SetWindowPos(pThis->m_hwnd, NULL, 0, 0, sl.cx, sl.cy,
 | 
						|
					SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
 | 
						|
		}
 | 
						|
		else pThis->ViewChanged();
 | 
						|
	}
 | 
						|
    
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::GetExtent(DWORD dwDrawAspect, SIZEL *psizel)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::GetExtent\n");
 | 
						|
 | 
						|
	CHECK_NULL_RETURN(psizel, E_POINTER);
 | 
						|
 | 
						|
    if (!(dwDrawAspect & DVASPECT_CONTENT))
 | 
						|
        return DV_E_DVASPECT;
 | 
						|
 | 
						|
	*psizel = pThis->m_Size;
 | 
						|
	DsoPixelsToHimetric(&(psizel->cx), &(psizel->cy));
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::Advise(IAdviseSink *pAdvSink, DWORD *pdwConnection)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::Advise\n");
 | 
						|
 | 
						|
	if (NULL == pThis->m_pOleAdviseHolder)
 | 
						|
	{
 | 
						|
		if (FAILED(CreateOleAdviseHolder(&(pThis->m_pOleAdviseHolder))))
 | 
						|
			return E_FAIL;
 | 
						|
	}
 | 
						|
	return pThis->m_pOleAdviseHolder->Advise(pAdvSink, pdwConnection);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::Unadvise(DWORD dwConnection)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::Unadvise\n");
 | 
						|
 | 
						|
	CHECK_NULL_RETURN(pThis->m_pOleAdviseHolder, CONNECT_E_NOCONNECTION);
 | 
						|
    return pThis->m_pOleAdviseHolder->Unadvise(dwConnection);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::EnumAdvise(IEnumSTATDATA **ppenumAdvise)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleObject);
 | 
						|
    ODS("CDsoFramerControl::XOleObject::EnumAdvise\n");
 | 
						|
 | 
						|
	CHECK_NULL_RETURN(ppenumAdvise, E_POINTER);
 | 
						|
	*ppenumAdvise = NULL;
 | 
						|
 | 
						|
	CHECK_NULL_RETURN(pThis->m_pOleAdviseHolder, E_FAIL);
 | 
						|
    return pThis->m_pOleAdviseHolder->EnumAdvise(ppenumAdvise);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::GetMiscStatus\n");
 | 
						|
 | 
						|
    if (dwAspect != DVASPECT_CONTENT)
 | 
						|
        return DV_E_DVASPECT;
 | 
						|
    
 | 
						|
    if (pdwStatus)
 | 
						|
		*pdwStatus = 	OLEMISC_SETCLIENTSITEFIRST |
 | 
						|
						OLEMISC_ACTIVATEWHENVISIBLE | 
 | 
						|
						OLEMISC_RECOMPOSEONRESIZE |
 | 
						|
						OLEMISC_CANTLINKINSIDE | 
 | 
						|
						OLEMISC_INSIDEOUT;
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleObject::SetColorScheme(LOGPALETTE *pLogpal)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XOleObject::SetColorScheme\n");
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XOleControl -- IOleControl Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP GetControlInfo(CONTROLINFO* pCI);
 | 
						|
//	 STDMETHODIMP OnMnemonic(LPMSG pMsg);
 | 
						|
//	 STDMETHODIMP OnAmbientPropertyChange(DISPID dispID);
 | 
						|
//	 STDMETHODIMP FreezeEvents(BOOL bFreeze);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleControl)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleControl::GetControlInfo(CONTROLINFO* pCI)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XOleControl::GetControlInfo\n");
 | 
						|
	CHECK_NULL_RETURN(pCI, E_POINTER);
 | 
						|
    pCI->hAccel = NULL; pCI->cAccel = 0; pCI->dwFlags = 0;
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleControl::OnMnemonic(LPMSG pMsg)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleControl);
 | 
						|
	ODS("CDsoFramerControl::XOleControl::OnMnemonic\n");
 | 
						|
	return pThis->InPlaceActivate(OLEIVERB_UIACTIVATE);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleControl::OnAmbientPropertyChange(DISPID dispID)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleControl);
 | 
						|
	ODS("CDsoFramerControl::XOleControl::OnAmbientPropertyChange\n");
 | 
						|
 | 
						|
 // We keep track of state changes in design/run modes...
 | 
						|
    if (dispID == DISPID_AMBIENT_USERMODE || dispID == DISPID_UNKNOWN)
 | 
						|
        pThis->m_fModeFlagValid = FALSE;
 | 
						|
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleControl::FreezeEvents(BOOL bFreeze)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleControl);
 | 
						|
	TRACE1("CDsoFramerControl::XOleControl::FreezeEvents = %s\n", (bFreeze ? "TRUE" : "FALSE"));
 | 
						|
    pThis->m_fFreezeEvents = bFreeze;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XOleInplaceObject -- IOleInplaceObject Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP GetWindow(HWND *phwnd);
 | 
						|
//	 STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
 | 
						|
//	 STDMETHODIMP InPlaceDeactivate();
 | 
						|
//	 STDMETHODIMP UIDeactivate();
 | 
						|
//	 STDMETHODIMP SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect);
 | 
						|
//	 STDMETHODIMP ReactivateAndUndo();
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleInplaceObject)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceObject::GetWindow(HWND *phwnd)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleInplaceObject);
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceObject::GetWindow\n");
 | 
						|
	if (!(pThis->m_fInPlaceActive)) return E_FAIL;
 | 
						|
	if (phwnd) *phwnd = pThis->m_hwnd;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceObject::ContextSensitiveHelp(BOOL /*fEnterMode*/)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceObject::ContextSensitiveHelp\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceObject::InPlaceDeactivate()
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleInplaceObject);
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceObject::InPlaceDeactivate\n");
 | 
						|
 | 
						|
 // if we're not in-place active yet, then this is easy.
 | 
						|
    if (!(pThis->m_fInPlaceActive))
 | 
						|
        return S_OK;
 | 
						|
 | 
						|
 // transition from UIActive back to active
 | 
						|
    if (pThis->m_fUIActive)
 | 
						|
        UIDeactivate();
 | 
						|
 | 
						|
 // tell the host we're going away
 | 
						|
    pThis->m_pInPlaceSite->OnInPlaceDeactivate();
 | 
						|
 | 
						|
    pThis->m_fInPlaceActive = FALSE;
 | 
						|
    pThis->m_fInPlaceVisible = FALSE;
 | 
						|
 | 
						|
 // if we have a window, tell it to go away.
 | 
						|
    if (pThis->m_hwnd)
 | 
						|
		{DestroyWindow(pThis->m_hwnd); pThis->m_hwnd = NULL;}
 | 
						|
    
 | 
						|
    SAFE_RELEASE_INTERFACE(pThis->m_pInPlaceFrame);
 | 
						|
    SAFE_RELEASE_INTERFACE(pThis->m_pInPlaceUIWindow);
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceObject::UIDeactivate()
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleInplaceObject);
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceObject::UIDeactivate\n");
 | 
						|
 | 
						|
 // if we're not UIActive, not much to do.
 | 
						|
    if (!(pThis->m_fUIActive))
 | 
						|
        return S_OK;
 | 
						|
 | 
						|
    pThis->m_fUIActive = FALSE;
 | 
						|
 | 
						|
 // notify frame windows, if appropriate, that we're no longer ui-active.
 | 
						|
    if (pThis->m_pInPlaceUIWindow)
 | 
						|
		pThis->m_pInPlaceUIWindow->SetActiveObject(NULL, NULL);
 | 
						|
 | 
						|
    if (pThis->m_pInPlaceFrame)
 | 
						|
		pThis->m_pInPlaceFrame->SetActiveObject(NULL, NULL);
 | 
						|
 | 
						|
	pThis->OnUIFocusChange(FALSE);
 | 
						|
 | 
						|
 // 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
 | 
						|
    pThis->m_pInPlaceSite->OnUIDeactivate(FALSE);
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceObject::SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
 | 
						|
{
 | 
						|
    RECT rcIXect;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleInplaceObject);
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceObject::SetObjectRects\n");
 | 
						|
 | 
						|
  // move our window to the new location and handle clipping.
 | 
						|
    if (pThis->m_hwnd)
 | 
						|
	{
 | 
						|
	 // if asked to clip the window, we'll use a clip region...
 | 
						|
		if ((lprcClipRect) && (IntersectRect(&rcIXect, lprcPosRect, lprcClipRect)) &&
 | 
						|
			(!EqualRect(&rcIXect, lprcPosRect)))
 | 
						|
		{
 | 
						|
			OffsetRect(&rcIXect, -(lprcPosRect->left), -(lprcPosRect->top));
 | 
						|
			SetWindowRgn(pThis->m_hwnd, CreateRectRgnIndirect(&rcIXect), TRUE);
 | 
						|
			pThis->m_fUsingWindowRgn = TRUE;
 | 
						|
		}
 | 
						|
		else if (pThis->m_fUsingWindowRgn)
 | 
						|
		{
 | 
						|
            SetWindowRgn(pThis->m_hwnd, NULL, TRUE);
 | 
						|
            pThis->m_fUsingWindowRgn = FALSE;
 | 
						|
		}
 | 
						|
 | 
						|
        // set our control's location, but don't change it's size at all
 | 
						|
        // [people for whom zooming is important should set that up here]
 | 
						|
        SetWindowPos(pThis->m_hwnd, NULL, lprcPosRect->left, lprcPosRect->top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
 | 
						|
    }
 | 
						|
 | 
						|
 // save out our current location.
 | 
						|
    pThis->m_rcLocation = *lprcPosRect;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceObject::ReactivateAndUndo()
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceObject::ReactivateAndUndo\n");
 | 
						|
	return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XOleInplaceActiveObject -- IOleInplaceActiveObject Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP GetWindow(HWND *phwnd);
 | 
						|
//	 STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
 | 
						|
//	 STDMETHODIMP TranslateAccelerator(LPMSG lpmsg);
 | 
						|
//	 STDMETHODIMP OnFrameWindowActivate(BOOL fActivate);
 | 
						|
//	 STDMETHODIMP OnDocWindowActivate(BOOL fActivate);
 | 
						|
//	 STDMETHODIMP ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow);
 | 
						|
//	 STDMETHODIMP EnableModeless(BOOL fEnable);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleInplaceActiveObject)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::GetWindow(HWND *phwnd)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleInplaceActiveObject);
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceActiveObject::GetWindow\n");
 | 
						|
	if (phwnd) *phwnd = pThis->m_hwnd;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::ContextSensitiveHelp(BOOL /*fEnterMode*/)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceActiveObject::ContextSensitiveHelp\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFramerControl::XOleInplaceActiveObject::TranslateAccelerator
 | 
						|
//
 | 
						|
//  We handle certain keys as accelerators, but only if host does not
 | 
						|
//  implement it itself, and only when no document is open. The reason
 | 
						|
//  why is due to two factors:
 | 
						|
//
 | 
						|
//  (1) When an out-of-proc AxDoc server is embedded and has focus, 
 | 
						|
//      its thread (not ours) gets the accel keys. Word/PPT will treat
 | 
						|
//      these for us and contact us through IOleCommandTarget, so
 | 
						|
//      we don't want to handle them if AxDoc is handling them for us.
 | 
						|
//
 | 
						|
//  (2) We cannot know if a given host uses the same accel keys for 
 | 
						|
//      other tasks, and we don't want to impose ours on a host. By
 | 
						|
//      explicitly asking host to handle it first, we should be able 
 | 
						|
//      to avoid any conflicts, and give developer a change to override
 | 
						|
//      our handler as needed.
 | 
						|
//
 | 
						|
static short _SpecialKeyState()
 | 
						|
{
 | 
						|
    BOOL bShift = (GetKeyState(VK_SHIFT) < 0);
 | 
						|
    BOOL bCtrl  = (GetKeyState(VK_CONTROL) < 0);
 | 
						|
    BOOL bAlt   = (GetKeyState(VK_MENU) < 0);
 | 
						|
    return (short)(bShift + (bCtrl << 1) + (bAlt << 2));
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::TranslateAccelerator(LPMSG lpmsg)
 | 
						|
{
 | 
						|
    HRESULT hr = S_FALSE;
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleInplaceActiveObject);
 | 
						|
    CHECK_NULL_RETURN(lpmsg, E_POINTER);
 | 
						|
	TRACE2("CDsoFramerControl::XOleInplaceActiveObject::TranslateAccelerator(msg=%d, wparam=%d)\n", lpmsg->message, lpmsg->wParam);
 | 
						|
 | 
						|
 // Forward it back to the site for processing on its side...
 | 
						|
    if (pThis->m_pControlSite)
 | 
						|
    {
 | 
						|
        hr = pThis->m_pControlSite->TranslateAccelerator(lpmsg, _SpecialKeyState());
 | 
						|
        if (hr == S_OK) return S_OK; // If site handled it, nothing else we need to do..
 | 
						|
    }
 | 
						|
 | 
						|
    if ((GetKeyState(VK_CONTROL) < 0) && (!(pThis->m_fModalState)) && 
 | 
						|
        (lpmsg->message == WM_KEYUP) && (!(pThis->m_pDocObjFrame)))
 | 
						|
    {
 | 
						|
        TRACE1(" Handle Accelerator? (%d)\n", lpmsg->wParam);
 | 
						|
        switch (lpmsg->wParam) // Looking for Ctrl+N and Ctrl+O keys...
 | 
						|
        {
 | 
						|
        case 0x4E: PostMessage(pThis->m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, OLECMDID_NEW,  0); hr = S_OK; break;
 | 
						|
        case 0x4F: PostMessage(pThis->m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, OLECMDID_OPEN, 0); hr = S_OK; break;
 | 
						|
        case 0x53: PostMessage(pThis->m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, OLECMDID_SAVE, 0); hr = S_OK; break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 // we didn't want it.
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::OnFrameWindowActivate(BOOL fActivate)
 | 
						|
{
 | 
						|
	TRACE1("CDsoFramerControl::XOleInplaceActiveObject::OnFrameWindowActivate - %d\n", fActivate);
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::OnDocWindowActivate(BOOL fActivate)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleInplaceActiveObject);
 | 
						|
	TRACE1("CDsoFramerControl::XOleInplaceActiveObject::OnDocWindowActivate - %d\n", fActivate);
 | 
						|
    
 | 
						|
	if (pThis->m_fUIActive && fActivate && pThis->m_pInPlaceFrame)
 | 
						|
        pThis->m_pInPlaceFrame->SetBorderSpace(NULL);
 | 
						|
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fFrameWindow)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XOleInplaceActiveObject::ResizeBorder\n");
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleInplaceActiveObject::EnableModeless(BOOL fEnable)
 | 
						|
{
 | 
						|
	TRACE1("CDsoFramerControl::XOleInplaceActiveObject::EnableModeless(%d)\n", fEnable);
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XViewObjectEx -- IViewObjectEx Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP Draw(DWORD dwAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE * ptd, HDC hicTargetDev, HDC hdcDraw, const LPRECTL lprcBounds, const LPRECTL lprcWBounds, BOOL(*)(DWORD)pfnContinue, DWORD dwContinue); 
 | 
						|
//	 STDMETHODIMP GetColorSet(DWORD dwAspect, LONG lindex, void* pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE** ppColorSet);
 | 
						|
//	 STDMETHODIMP Freeze(DWORD dwAspect, LONG lindex, void* pvAspect, DWORD* pdwFreeze);
 | 
						|
//	 STDMETHODIMP Unfreeze(DWORD dwFreeze);
 | 
						|
//	 STDMETHODIMP SetAdvise(DWORD dwAspect, DWORD advf, IAdviseSink* pAdvSink);
 | 
						|
//	 STDMETHODIMP GetAdvise(DWORD* pdwAspect, DWORD* padvf, IAdviseSink** ppAdvSink);
 | 
						|
//	 STDMETHODIMP GetExtent(DWORD dwAspect, DWORD lindex, DVTARGETDEVICE ptd, LPSIZEL lpsizel);
 | 
						|
//	 STDMETHODIMP GetRect(DWORD dwAspect, LPRECTL pRect);
 | 
						|
//	 STDMETHODIMP GetViewStatus(DWORD* pdwStatus);
 | 
						|
//	 STDMETHODIMP QueryHitPoint(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG lCloseHint, DWORD *pHitResult);
 | 
						|
//	 STDMETHODIMP QueryHitRect(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT pRectLoc, LONG lCloseHint, DWORD *pHitResult);
 | 
						|
//	 STDMETHODIMP GetNaturalExtent(DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd, HDC hicTargetDev, DVEXTENTINFO *pExtentInfo, LPSIZEL pSizel);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ViewObjectEx)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::Draw(DWORD dwDrawAspect, LONG lIndex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDevice, HDC hdcDraw, LPCRECTL prcBounds, LPCRECTL prcWBounds, BOOL (__stdcall *pfnContinue)(DWORD dwContinue), DWORD dwContinue)
 | 
						|
{
 | 
						|
    RECT rc;
 | 
						|
    int iMode = 0;
 | 
						|
    POINT pVp = {0,0};
 | 
						|
	POINT pW = {0,0};
 | 
						|
    BOOL fOptimize = FALSE;
 | 
						|
    BOOL fMetafile = FALSE;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx);
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::Draw\n");
 | 
						|
 | 
						|
	if (!((dwDrawAspect == DVASPECT_CONTENT) || 
 | 
						|
		  (dwDrawAspect == DVASPECT_OPAQUE)))
 | 
						|
            return DV_E_DVASPECT;
 | 
						|
 | 
						|
	SaveDC(hdcDraw);
 | 
						|
	
 | 
						|
 // first, have to do a little bit to support printing.
 | 
						|
    if (GetDeviceCaps(hdcDraw, TECHNOLOGY) == DT_METAFILE)
 | 
						|
	{
 | 
						|
     // We are dealing with a metafile.
 | 
						|
        fMetafile = TRUE;
 | 
						|
    }
 | 
						|
/* 
 | 
						|
  // check to see if we have any flags passed in the pvAspect parameter.
 | 
						|
   if (pvAspect && ((DVASPECTINFO *)pvAspect)->cb == sizeof(DVASPECTINFO))
 | 
						|
        fOptimize = (((DVASPECTINFO *)pvAspect)->dwFlags & DVASPECTINFOFLAG_CANOPTIMIZE) ? TRUE : FALSE;
 | 
						|
*/
 | 
						|
  // Get the draw rect, if they didn't give us one, just copy over ours
 | 
						|
	memcpy(&rc, ((prcBounds) ? (RECT*)prcBounds : &(pThis->m_rcLocation)), sizeof(RECT));
 | 
						|
 | 
						|
    if (!fMetafile)
 | 
						|
	{
 | 
						|
        LPtoDP(hdcDraw, (POINT*)&rc, 2);
 | 
						|
        SetViewportOrgEx(hdcDraw, 0, 0, &pVp);
 | 
						|
        SetWindowOrgEx(hdcDraw, 0, 0, &pW);
 | 
						|
        iMode = SetMapMode(hdcDraw, MM_TEXT);
 | 
						|
    }
 | 
						|
 | 
						|
  // prcWBounds is NULL and not used if we are not dealing with a metafile.
 | 
						|
  // For metafiles, we pass on rc as *prcBounds, we should also include prcWBounds
 | 
						|
    pThis->OnDraw(dwDrawAspect, hdcDraw, &rc, (RECT*)prcWBounds, hicTargetDevice, fOptimize);
 | 
						|
 | 
						|
  // clean up the DC when we're done with it, if appropriate.
 | 
						|
    if (!fMetafile)
 | 
						|
	{
 | 
						|
        SetViewportOrgEx(hdcDraw, pVp.x, pVp.y, NULL);
 | 
						|
        SetWindowOrgEx(hdcDraw, pW.x, pW.y, NULL);
 | 
						|
        SetMapMode(hdcDraw, iMode);
 | 
						|
    }
 | 
						|
 | 
						|
	RestoreDC(hdcDraw, -1);
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetColorSet(DWORD dwAspect, LONG lindex, void* pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE** ppColorSet)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::GetColorSet\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::Freeze(DWORD dwAspect, LONG lindex, void* pvAspect, DWORD* pdwFreeze)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::Freeze\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::Unfreeze(DWORD dwFreeze)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::Unfreeze\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::SetAdvise(DWORD dwAspect, DWORD advf, IAdviseSink* pAdviseSink)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx);
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::SetAdvise\n");
 | 
						|
 | 
						|
 // if it's not a content aspect, we don't support it.
 | 
						|
    if (!(dwAspect & DVASPECT_CONTENT)) 
 | 
						|
        return DV_E_DVASPECT;
 | 
						|
 | 
						|
 // set up some flags  [we gotta stash for GetAdvise ...]
 | 
						|
    pThis->m_fViewAdvisePrimeFirst = (advf & ADVF_PRIMEFIRST) ? TRUE : FALSE;
 | 
						|
    pThis->m_fViewAdviseOnlyOnce = (advf & ADVF_ONLYONCE) ? TRUE : FALSE;
 | 
						|
 | 
						|
    SAFE_RELEASE_INTERFACE(pThis->m_pViewAdviseSink);
 | 
						|
    SAFE_SET_INTERFACE(pThis->m_pViewAdviseSink, pAdviseSink);
 | 
						|
 | 
						|
 // prime them if they want it [we need to store this so they can get flags later]
 | 
						|
    if (pThis->m_fViewAdvisePrimeFirst)
 | 
						|
        pThis->ViewChanged();
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetAdvise(DWORD* pdwAspect, DWORD* padvf, IAdviseSink** ppAdviseSink)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx);
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::GetAdvise\n");
 | 
						|
 | 
						|
    if (pdwAspect)
 | 
						|
        *pdwAspect = DVASPECT_CONTENT;
 | 
						|
 | 
						|
    if (padvf)
 | 
						|
	{
 | 
						|
        *padvf = 0;
 | 
						|
        if (pThis->m_fViewAdviseOnlyOnce) *padvf |= ADVF_ONLYONCE;
 | 
						|
        if (pThis->m_fViewAdvisePrimeFirst) *padvf |= ADVF_PRIMEFIRST;
 | 
						|
    }
 | 
						|
 | 
						|
    if (ppAdviseSink)
 | 
						|
	    { SAFE_SET_INTERFACE(*ppAdviseSink, pThis->m_pViewAdviseSink); }
 | 
						|
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetExtent(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL psizel)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx);
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::GetExtent\n");
 | 
						|
	return pThis->m_xOleObject.GetExtent(dwDrawAspect, psizel);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetRect(DWORD dwAspect, LPRECTL pRect)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ViewObjectEx);
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::GetRect\n");
 | 
						|
 | 
						|
    if (dwAspect != DVASPECT_CONTENT)
 | 
						|
        return DV_E_DVASPECT;
 | 
						|
 | 
						|
	if (pRect)
 | 
						|
	{
 | 
						|
		CopyRect((LPRECT)pRect, &(pThis->m_rcLocation));
 | 
						|
	 // Convert to himetric (according to docs, this is required)
 | 
						|
		DsoPixelsToHimetric(&(pRect->left), &(pRect->top));
 | 
						|
		DsoPixelsToHimetric(&(pRect->right), &(pRect->bottom));
 | 
						|
	}
 | 
						|
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetViewStatus(DWORD* pdwStatus)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::GetViewStatus\n");
 | 
						|
	if (pdwStatus) *pdwStatus = VIEWSTATUS_OPAQUE;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::QueryHitPoint(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG lCloseHint, DWORD *pHitResult)
 | 
						|
{
 | 
						|
 // ODS("CDsoFramerControl::XViewObjectEx::QueryHitPoint\n");
 | 
						|
    if (dwAspect != DVASPECT_CONTENT) return DV_E_DVASPECT;
 | 
						|
    CHECK_NULL_RETURN(pHitResult, E_POINTER);
 | 
						|
    *pHitResult = PtInRect(pRectBounds, ptlLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::QueryHitRect(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT pRectLoc, LONG lCloseHint, DWORD *pHitResult)
 | 
						|
{
 | 
						|
    RECT rc;
 | 
						|
	//ODS("CDsoFramerControl::XViewObjectEx::QueryHitRect\n");
 | 
						|
    if (dwAspect != DVASPECT_CONTENT) return DV_E_DVASPECT;
 | 
						|
    *pHitResult = IntersectRect(&rc, pRectBounds, pRectLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XViewObjectEx::GetNaturalExtent(DWORD dwAspect, LONG lindex, DVTARGETDEVICE *ptd, HDC hicTargetDev, DVEXTENTINFO *pExtentInfo, LPSIZEL pSizel)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XViewObjectEx::GetNaturalExtent\n");
 | 
						|
	return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XDataObject -- IDataObject Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP Draw(DWORD dwAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE * ptd, HDC hicTargetDev, HDC hdcDraw, const LPRECTL lprcBounds, const LPRECTL lprcWBounds, BOOL(*)(DWORD)pfnContinue, DWORD dwContinue); 
 | 
						|
//   STDMETHODIMP GetData(FORMATETC *pfmtc,  STGMEDIUM *pstgm);
 | 
						|
//   STDMETHODIMP GetDataHere(FORMATETC *pfmtc, STGMEDIUM *pstgm);
 | 
						|
//   STDMETHODIMP QueryGetData(FORMATETC *pfmtc);
 | 
						|
//   STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *pfmtcIn, FORMATETC *pfmtcOut);
 | 
						|
//   STDMETHODIMP SetData(FORMATETC *pfmtc, STGMEDIUM *pstgm, BOOL fRelease);
 | 
						|
//   STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenum);
 | 
						|
//   STDMETHODIMP DAdvise(FORMATETC *pfmtc, DWORD advf, IAdviseSink *psink, DWORD *pdwConnection);
 | 
						|
//   STDMETHODIMP DUnadvise(DWORD dwConnection);
 | 
						|
//   STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenum);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, DataObject)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::GetData(FORMATETC *pfmtc,  STGMEDIUM *pstgm)
 | 
						|
{
 | 
						|
    HRESULT hr;
 | 
						|
    HMETAFILE hwmf;
 | 
						|
    LPMETAFILEPICT pwmf;
 | 
						|
    HGLOBAL hmem;
 | 
						|
    SIZE sizeMetric;
 | 
						|
    RECT rc;
 | 
						|
    HDC hdc;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, DataObject);
 | 
						|
    TRACE2("CDsoFramerControl::XDataObject::GetData(%d,%d)\n", pfmtc->cfFormat, pfmtc->tymed);
 | 
						|
    CHECK_NULL_RETURN(pfmtc, E_POINTER); CHECK_NULL_RETURN(pstgm, E_POINTER);
 | 
						|
 | 
						|
 // Confirm data requested is a supportted type...
 | 
						|
    if (FAILED(hr = QueryGetData(pfmtc)))
 | 
						|
        return hr;
 | 
						|
 | 
						|
 // If caller wants a metafile of the current object, draw it...
 | 
						|
    hdc = CreateMetaFileW(NULL);
 | 
						|
 | 
						|
    sizeMetric.cx = pThis->m_Size.cx;
 | 
						|
    sizeMetric.cy = pThis->m_Size.cy;
 | 
						|
 | 
						|
    SetRect(&rc, 0, 0, sizeMetric.cx, sizeMetric.cy);
 | 
						|
    DsoPixelsToHimetric(&(sizeMetric.cx), &(sizeMetric.cy));
 | 
						|
    sizeMetric.cy = -(sizeMetric.cy);
 | 
						|
 | 
						|
    SetMapMode(hdc, MM_ANISOTROPIC);
 | 
						|
	SetWindowOrgEx(hdc, 0, 0, NULL);
 | 
						|
	SetWindowExtEx(hdc, rc.right, rc.bottom, NULL);
 | 
						|
 | 
						|
 // Delegate to same IViewObject::Draw used by most containers for metafile...
 | 
						|
    hr = pThis->m_xViewObjectEx.Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdc, (RECTL*)&rc, NULL, NULL, 0);
 | 
						|
    ASSERT(SUCCEEDED(hr));
 | 
						|
 | 
						|
	if ((hwmf = CloseMetaFile(hdc)) == NULL)
 | 
						|
		return E_UNEXPECTED;
 | 
						|
 | 
						|
 // Now allocate the transfer medium and set the metafile...
 | 
						|
    hmem = GlobalAlloc((GMEM_SHARE|GMEM_MOVEABLE), sizeof(METAFILEPICT));
 | 
						|
	if (hmem == NULL) { DeleteMetaFile(hwmf); return STG_E_MEDIUMFULL; }
 | 
						|
 | 
						|
	pwmf = (LPMETAFILEPICT)GlobalLock(hmem);
 | 
						|
    if (pwmf)
 | 
						|
    {
 | 
						|
	    pwmf->hMF  = hwmf;
 | 
						|
	    pwmf->mm   = MM_ANISOTROPIC;
 | 
						|
	    pwmf->xExt = sizeMetric.cx;
 | 
						|
	    pwmf->yExt = sizeMetric.cy;
 | 
						|
	    GlobalUnlock(hmem);
 | 
						|
    }
 | 
						|
 | 
						|
	pstgm->tymed = TYMED_MFPICT;
 | 
						|
	pstgm->hGlobal = hmem;
 | 
						|
	pstgm->pUnkForRelease = NULL;
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::GetDataHere(FORMATETC *pfmtc, STGMEDIUM *pstgm)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XDataObject::GetDataHere\n");
 | 
						|
    return DV_E_FORMATETC;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::QueryGetData(FORMATETC *pfmtc)
 | 
						|
{
 | 
						|
    TRACE2("CDsoFramerControl::XDataObject::QueryGetData(%d,%d)\n", pfmtc->cfFormat, pfmtc->tymed);
 | 
						|
    CHECK_NULL_RETURN(pfmtc, E_POINTER);
 | 
						|
 | 
						|
    if (pfmtc->cfFormat != CF_METAFILEPICT)
 | 
						|
        return DV_E_FORMATETC; // We only support WMF for IDataObj presentation.
 | 
						|
 | 
						|
    if (pfmtc->tymed != TYMED_MFPICT)
 | 
						|
        return DV_E_TYMED; // It better be in in right format...
 | 
						|
 | 
						|
    if (pfmtc->dwAspect != DVASPECT_CONTENT)
 | 
						|
        return DV_E_DVASPECT; // We only do content (not thumbnail or partial)...
 | 
						|
 | 
						|
    return S_OK; // If here, it looks fine to us...
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::GetCanonicalFormatEtc(FORMATETC *pfmtcIn, FORMATETC *pfmtcOut)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XDataObject::GetCanonicalFormatEtc\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::SetData(FORMATETC *pfmtc, STGMEDIUM *pstgm, BOOL fRelease)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XDataObject::SetData\n");
 | 
						|
    return E_NOTIMPL;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenum)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XDataObject::EnumFormatEtc\n");
 | 
						|
	return OleRegEnumFormatEtc(CLSID_FramerControl, dwDirection, ppenum);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::DAdvise(FORMATETC *pfmtc, DWORD advf, IAdviseSink *psink, DWORD *pdwConnection)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, DataObject);
 | 
						|
    ODS("CDsoFramerControl::XDataObject::DAdvise\n");
 | 
						|
 | 
						|
 // Create OLE Data advise holder to keep sink for us...
 | 
						|
	if ((NULL == pThis->m_pDataAdviseHolder) && 
 | 
						|
        FAILED(CreateDataAdviseHolder(&(pThis->m_pDataAdviseHolder))))
 | 
						|
			return E_FAIL;
 | 
						|
 | 
						|
 // Add this advise sink for the given format to the collection...
 | 
						|
	return pThis->m_pDataAdviseHolder->Advise((IDataObject*)&(pThis->m_xDataObject), pfmtc, advf, psink, pdwConnection);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::DUnadvise(DWORD dwConnection)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, DataObject);
 | 
						|
    ODS("CDsoFramerControl::XDataObject::DUnadvise\n");
 | 
						|
	CHECK_NULL_RETURN(pThis->m_pDataAdviseHolder, CONNECT_E_NOCONNECTION);
 | 
						|
    return pThis->m_pDataAdviseHolder->Unadvise(dwConnection);
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDataObject::EnumDAdvise(IEnumSTATDATA **ppenum)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, DataObject);
 | 
						|
    ODS("CDsoFramerControl::XDataObject::EnumDAdvise\n");
 | 
						|
	CHECK_NULL_RETURN(pThis->m_pDataAdviseHolder, CONNECT_E_NOCONNECTION);
 | 
						|
    return pThis->m_pDataAdviseHolder->EnumAdvise(ppenum);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XProvideClassInfo -- IProvideClassInfo Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP GetClassInfo(ITypeInfo** ppTI);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ProvideClassInfo)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XProvideClassInfo::GetClassInfo(ITypeInfo** ppTI)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XProvideClassInfo::GetClassInfo\n");
 | 
						|
	return DsoGetTypeInfoEx(LIBID_DSOFramer, 0,
 | 
						|
		DSOFRAMERCTL_VERSION_MAJOR, DSOFRAMERCTL_VERSION_MINOR, v_hModule, CLSID_FramerControl, ppTI);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XConnectionPointContainer -- IConnectionPointContainer Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP EnumConnectionPoints(IEnumConnectionPoints **ppEnum);
 | 
						|
//	 STDMETHODIMP FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ConnectionPointContainer)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XConnectionPointContainer::EnumConnectionPoints(IEnumConnectionPoints **ppEnum)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ConnectionPointContainer);
 | 
						|
    ODS("CDsoFramerControl::XConnectionPointContainer::EnumConnectionPoints\n");
 | 
						|
    if (ppEnum) { SAFE_SET_INTERFACE(*ppEnum, &(pThis->m_xEnumConnectionPoints)); };
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XConnectionPointContainer::FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ConnectionPointContainer);
 | 
						|
    ODS("CDsoFramerControl::XConnectionPointContainer::FindConnectionPoint\n");
 | 
						|
	if (riid != DIID__DFramerCtlEvents) return CONNECT_E_NOCONNECTION;
 | 
						|
	if (ppCP) { SAFE_SET_INTERFACE(*ppCP, &(pThis->m_xConnectionPoint)); };
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XEnumConnectionPoints -- IEnumConnectionPoints Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP Next(ULONG cConnections, IConnectionPoint **rgpcn, ULONG *pcFetched);
 | 
						|
//	 STDMETHODIMP Skip(ULONG cConnections);
 | 
						|
//	 STDMETHODIMP Reset(void);
 | 
						|
//	 STDMETHODIMP Clone(IEnumConnectionPoints **ppEnum);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, EnumConnectionPoints)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XEnumConnectionPoints::Next(ULONG cConnections, IConnectionPoint **rgpcn, ULONG *pcFetched)
 | 
						|
{
 | 
						|
	HRESULT hr = S_FALSE;
 | 
						|
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, EnumConnectionPoints);
 | 
						|
    ODS("CDsoFramerControl::XEnumConnectionPoints::Next\n");
 | 
						|
 | 
						|
	CHECK_NULL_RETURN(rgpcn, E_POINTER);
 | 
						|
	*rgpcn = NULL;
 | 
						|
 | 
						|
	CHECK_NULL_RETURN(pcFetched, E_POINTER);
 | 
						|
	*pcFetched = 0;
 | 
						|
 | 
						|
	if (pThis->m_fConCntDone)
 | 
						|
		pThis->m_fConCntDone = FALSE;
 | 
						|
	else
 | 
						|
	{
 | 
						|
        SAFE_SET_INTERFACE(*rgpcn, &(pThis->m_xConnectionPoint));
 | 
						|
		*pcFetched = 1;
 | 
						|
		pThis->m_fConCntDone = TRUE; hr = S_OK;
 | 
						|
	}
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XEnumConnectionPoints::Skip(ULONG cConnections)
 | 
						|
{return S_OK;}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XEnumConnectionPoints::Reset(void)
 | 
						|
{return S_OK;}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XEnumConnectionPoints::Clone(IEnumConnectionPoints **ppEnum)
 | 
						|
{if (ppEnum) *ppEnum = this; return S_OK;}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XConnectionPoint -- IConnectionPoint Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP GetConnectionInterface(IID *pIID);
 | 
						|
//	 STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer **ppCPC);
 | 
						|
//	 STDMETHODIMP Advise(IUnknown *pUnk, DWORD *pdwCookie);
 | 
						|
//	 STDMETHODIMP Unadvise(DWORD dwCookie);
 | 
						|
//	 STDMETHODIMP EnumConnections(IEnumConnections **ppEnum);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ConnectionPoint)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XConnectionPoint::GetConnectionInterface(IID *pIID)
 | 
						|
{
 | 
						|
    ODS("CDsoFramerControl::XConnectionPoint::GetConnectionInterface\n");
 | 
						|
	if (pIID) *pIID = DIID__DFramerCtlEvents;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer **ppCPC)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ConnectionPoint);
 | 
						|
    ODS("CDsoFramerControl::XConnectionPoint::GetConnectionPointContainer\n");
 | 
						|
    if (ppCPC) { SAFE_SET_INTERFACE(*ppCPC, &(pThis->m_xConnectionPointContainer)); };
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ConnectionPoint);
 | 
						|
    ODS("CDsoFramerControl::XConnectionPoint::Advise\n");
 | 
						|
 | 
						|
    CHECK_NULL_RETURN(pUnk, E_POINTER);
 | 
						|
    CHECK_NULL_RETURN(pdwCookie, E_POINTER);
 | 
						|
 | 
						|
	SAFE_RELEASE_INTERFACE(pThis->m_dispEvents);
 | 
						|
 | 
						|
 // FIX: The COM Interop layer in .NET CLR returns a different RCW for IDispatch than for a specific
 | 
						|
 // dispinterface GUID, so for events to work in .NET WinForm applications, we should explicitly use
 | 
						|
 // the RCW for that dispinterface. Other event source clients may fail QI for this GUID, so if it 
 | 
						|
 // does return an error, we will QI again for IDispatch. The event issue is change in behavior from 
 | 
						|
 // how VB6 implemented event sinks, and how VB7/C# does them...
 | 
						|
	HRESULT hr = pUnk->QueryInterface(DIID__DFramerCtlEvents, (void**)&(pThis->m_dispEvents));
 | 
						|
    if (FAILED(hr)) hr = pUnk->QueryInterface(IID_IDispatch, (void**)&(pThis->m_dispEvents));
 | 
						|
 | 
						|
    if (SUCCEEDED(hr)) *pdwCookie = (DWORD)(pThis);
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XConnectionPoint::Unadvise(DWORD dwCookie)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, ConnectionPoint);
 | 
						|
    ODS("CDsoFramerControl::XConnectionPoint::Unadvise\n");
 | 
						|
	if (dwCookie == (DWORD)(pThis))
 | 
						|
	{
 | 
						|
		SAFE_RELEASE_INTERFACE(pThis->m_dispEvents);
 | 
						|
	}
 | 
						|
	return (pThis->m_dispEvents == NULL) ? S_OK : CONNECT_E_NOCONNECTION;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XConnectionPoint::EnumConnections(IEnumConnections **ppEnum)
 | 
						|
{if (ppEnum) *ppEnum = NULL; return E_NOTIMPL;}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XOleCommandTarget -- IOleCommandTarget Implementation
 | 
						|
//
 | 
						|
//   STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText);
 | 
						|
//   STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut);            
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, OleCommandTarget)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleCommandTarget::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleCommandTarget);
 | 
						|
    //ODS("CDsoFramerControl::XOleCommandTarget::QueryStatus\n");
 | 
						|
	if (pguidCmdGroup != NULL)
 | 
						|
		return OLECMDERR_E_UNKNOWNGROUP;
 | 
						|
			
 | 
						|
	if (prgCmds == NULL)
 | 
						|
		return E_INVALIDARG;
 | 
						|
 | 
						|
    for (int i = 0; i < (int)cCmds; i++) 
 | 
						|
	{
 | 
						|
		switch (prgCmds[i].cmdID) 
 | 
						|
		{
 | 
						|
		case OLECMDID_NEW:			prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags &   1) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break;
 | 
						|
		case OLECMDID_OPEN:			prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags &   2) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break;
 | 
						|
		case OLECMDID_SAVE:			prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags &   8) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break;
 | 
						|
		case OLECMDID_SAVEAS:		prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags &  16) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break;
 | 
						|
		case OLECMDID_PRINT:		prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags &  32) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break;
 | 
						|
		case OLECMDID_PAGESETUP:	prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags &  64) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break;
 | 
						|
		case OLECMDID_PROPERTIES:	prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 128) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break;
 | 
						|
        case OLECMDID_PRINTPREVIEW: prgCmds[i].cmdf = (((pThis->m_wFileMenuFlags & 256) ? OLECMDF_ENABLED : 0) | OLECMDF_SUPPORTED); break;
 | 
						|
		default: prgCmds[i].cmdf = 0;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	if (pCmdText)
 | 
						|
    {
 | 
						|
        pCmdText->cmdtextf = MSOCMDTEXTF_NONE;
 | 
						|
        pCmdText->cwActual = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XOleCommandTarget::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, OleCommandTarget);
 | 
						|
    ODS("CDsoFramerControl::XOleCommandTarget::Exec\n");
 | 
						|
 | 
						|
    if ((pguidCmdGroup != NULL) && (*pguidCmdGroup != GUID_NULL))
 | 
						|
        return OLECMDERR_E_UNKNOWNGROUP;
 | 
						|
	    
 | 
						|
    if (nCmdexecopt == MSOCMDEXECOPT_SHOWHELP)
 | 
						|
        return OLECMDERR_E_NOHELP;
 | 
						|
 | 
						|
	switch (nCmdID)
 | 
						|
	{
 | 
						|
	case OLECMDID_NEW:
 | 
						|
	case OLECMDID_OPEN:
 | 
						|
	case OLECMDID_SAVE:
 | 
						|
	case OLECMDID_SAVEAS:
 | 
						|
	case OLECMDID_PRINT:
 | 
						|
	case OLECMDID_PAGESETUP:
 | 
						|
	case OLECMDID_PROPERTIES:
 | 
						|
    case OLECMDID_PRINTPREVIEW:
 | 
						|
		PostMessage(pThis->m_hwnd, DSO_WM_ASYNCH_OLECOMMAND, nCmdID, nCmdexecopt);
 | 
						|
		return S_OK;
 | 
						|
	}
 | 
						|
 | 
						|
	return OLECMDERR_E_NOTSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XSupportErrorInfo -- ISupportErrorInfo Implementation
 | 
						|
//
 | 
						|
//	 STDMETHODIMP InterfaceSupportsErrorInfo(REFIID riid);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, SupportErrorInfo)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XSupportErrorInfo::InterfaceSupportsErrorInfo(REFIID riid)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XSupportErrorInfo::InterfaceSupportsErrorInfo\n");
 | 
						|
	return ((riid == IID__FramerControl) ? S_OK : E_FAIL);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XObjectSafety -- IObjectSafety Implementation
 | 
						|
//
 | 
						|
//  STDMETHODIMP GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions,DWORD *pdwEnabledOptions);
 | 
						|
//  STDMETHODIMP SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, ObjectSafety)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XObjectSafety::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions,DWORD *pdwEnabledOptions)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XObjectSafety::GetInterfaceSafetyOptions\n");
 | 
						|
	CHECK_NULL_RETURN(pdwEnabledOptions, E_POINTER);
 | 
						|
 | 
						|
	if (pdwSupportedOptions)
 | 
						|
		*pdwSupportedOptions = (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACESAFE_FOR_UNTRUSTED_CALLER);
 | 
						|
 | 
						|
 // We are safe for initialization, but not necessarily for scripting. Since script
 | 
						|
 // can open documents with macros, and get access to Office OM via ActiveDocument,
 | 
						|
 // we cannot be "safe" for malicious script. But this allows the control to load
 | 
						|
 // without prompt (just not scripted without prompt)...
 | 
						|
	*pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XObjectSafety::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
 | 
						|
{
 | 
						|
	ODS("CDsoFramerControl::XObjectSafety::SetInterfaceSafetyOptions\n");
 | 
						|
	return ((((riid == IID_IPersist) || (riid == IID_IPersistPropertyBag)) &&
 | 
						|
		(dwEnabledOptions == INTERFACESAFE_FOR_UNTRUSTED_DATA)) ? S_OK : E_FAIL);
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
//
 | 
						|
// CDsoFramerControl::XDsoDocObjectSite -- IDsoDocObjectSite Implementation
 | 
						|
//
 | 
						|
//  STDMETHODIMP GetWindow(HWND* phWnd);
 | 
						|
//  STDMETHODIMP GetBorder(LPRECT prcBorder);
 | 
						|
//  STDMETHODIMP SetStatusText(LPCOLESTR pszText);
 | 
						|
//  STDMETHODIMP GetHostName(LPWSTR *ppwszHostName);
 | 
						|
//
 | 
						|
IMPLEMENT_INTERFACE_UNKNOWN(CDsoFramerControl, DsoDocObjectSite)
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::QueryService(REFGUID guidService, REFIID riid, void **ppv)
 | 
						|
{
 | 
						|
	HRESULT hr = E_NOINTERFACE;
 | 
						|
    ODS("CDsoFramerControl::XDsoDocObjectSite::QueryService\n");
 | 
						|
 | 
						|
    METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite);
 | 
						|
    CHECK_NULL_RETURN(ppv, E_POINTER);
 | 
						|
 | 
						|
 // We will return control IDispatch for cross container automation...
 | 
						|
    if (guidService == SID_SContainerDispatch)
 | 
						|
    {
 | 
						|
		ODS(" -- Container Dispatch Given --\n");
 | 
						|
        hr = pThis->QueryInterface(riid, ppv);
 | 
						|
    }
 | 
						|
 // TODO: Support IHlinkFrame services for cross hyperlinking inside control??
 | 
						|
 | 
						|
 // If we don't handle the call, and our host has a provider, pass the call along to see
 | 
						|
 // if the top-level host offers the service requested (like hyperlinking to new web page)...
 | 
						|
    if (FAILED(hr) && (pThis->m_pClientSite))
 | 
						|
    {
 | 
						|
        IServiceProvider *pprov = NULL;
 | 
						|
        if (SUCCEEDED(pThis->m_pClientSite->QueryInterface(IID_IServiceProvider, (void**)&pprov)) && (pprov))
 | 
						|
        {
 | 
						|
            if (SUCCEEDED(hr = pprov->QueryService(guidService, riid, ppv)))
 | 
						|
                { ODS(" -- Service provided by top-level host --\n"); }
 | 
						|
            pprov->Release();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::GetWindow(HWND* phWnd)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite);
 | 
						|
    ODS("CDsoFramerControl::XDsoDocObjectSite::GetWindow\n");
 | 
						|
    if (phWnd) *phWnd = pThis->m_hwnd;
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::GetBorder(LPRECT prcBorder)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite);
 | 
						|
    ODS("CDsoFramerControl::XDsoDocObjectSite::GetBorder\n");
 | 
						|
    pThis->GetSizeRectForDocument(NULL, prcBorder);
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::GetHostName(LPWSTR *ppwszHostName)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite);
 | 
						|
    ODS("CDsoFramerControl::XDsoDocObjectSite::GetHostName\n");
 | 
						|
    if (ppwszHostName) *ppwszHostName = DsoCopyString(pThis->m_pwszHostName);
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::SysMenuCommand(UINT uiCharCode)
 | 
						|
{
 | 
						|
 	METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite);
 | 
						|
    TRACE1("CDsoFramerControl::XDsoDocObjectSite::SysMenuCommand(%x)\n", uiCharCode);
 | 
						|
	
 | 
						|
 // If we are processing a sys menu command, see if it is a menu accel for our
 | 
						|
 // displayed menu, and if so we handle this with a fake click of the menu button...
 | 
						|
    if ((uiCharCode) && (pThis->m_fShowMenuBar) && !(pThis->m_fDisableMenuAccel))
 | 
						|
    {
 | 
						|
        UINT i;
 | 
						|
        CHAR *pch;
 | 
						|
 | 
						|
	 // Loop all the menu items and check against their accelerators...
 | 
						|
		for (i = 0; i < DSO_MAX_MENUITEMS; i++)
 | 
						|
		{
 | 
						|
			pch = &(pThis->m_rgchMenuAccel[0]);
 | 
						|
			if (*pch)
 | 
						|
			{
 | 
						|
				if ((*pch != 0xFF) && ((UINT)(*pch) == ASCII_LOWERCASE(uiCharCode)))
 | 
						|
				{
 | 
						|
				 // Found one that match, so fake mouse move and button down/up to run click code...
 | 
						|
					ODS("-- Trigger Menu Accelerator --\n");
 | 
						|
 | 
						|
					PostMessage(pThis->m_hwnd, WM_MOUSEMOVE, (WPARAM)0, 
 | 
						|
						MAKELPARAM(pThis->m_rgrcMenuItems[i].left + 1, pThis->m_rgrcMenuItems[i].top + 1));
 | 
						|
 | 
						|
					PostMessage(pThis->m_hwnd, WM_LBUTTONDOWN, (WPARAM)MK_LBUTTON, 
 | 
						|
						MAKELPARAM(pThis->m_rgrcMenuItems[i].left + 1, pThis->m_rgrcMenuItems[i].top + 1));
 | 
						|
 | 
						|
					PostMessage(pThis->m_hwnd, WM_LBUTTONUP, (WPARAM)0, 
 | 
						|
						MAKELPARAM(pThis->m_rgrcMenuItems[i].left + 1, pThis->m_rgrcMenuItems[i].top + 1));
 | 
						|
 | 
						|
				 // Return OK to caller to know to eat this message.
 | 
						|
					return S_OK;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else break; 
 | 
						|
        }
 | 
						|
   }
 | 
						|
 | 
						|
   return S_FALSE;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFramerControl::XDsoDocObjectSite::SetStatusText(LPCOLESTR pszText)
 | 
						|
{
 | 
						|
	METHOD_PROLOGUE(CDsoFramerControl, DsoDocObjectSite);
 | 
						|
 | 
						|
 // If m_fActivateOnStatus flag is set, see if we are not UI active. If not, try to activate...
 | 
						|
    if ((pThis->m_fActivateOnStatus) && (pThis->m_fComponentActive) && (pThis->m_fAppActive) && 
 | 
						|
		!(pThis->m_fUIActive) && !(pThis->m_fModalState))
 | 
						|
    {
 | 
						|
        ODS(" -- ForceUIActiveFromSetStatusText --\n");
 | 
						|
		pThis->m_fActivateOnStatus = FALSE;
 | 
						|
        pThis->Activate();
 | 
						|
    }
 | 
						|
 | 
						|
    return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFrameHookManager
 | 
						|
//
 | 
						|
CDsoFrameHookManager* vgGlobalManager = NULL;
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFrameHookManager::RegisterFramerControl
 | 
						|
//
 | 
						|
//  Creates a frame hook and registers it with the active manager. If 
 | 
						|
//  this is the first time called, the global manager will be created
 | 
						|
//  now.  The manager can handle up to DSOF_MAX_CONTROLS controls (10).
 | 
						|
//
 | 
						|
STDMETHODIMP_(CDsoFrameHookManager*) CDsoFrameHookManager::RegisterFramerControl(HWND hwndParent, HWND hwndControl)
 | 
						|
{
 | 
						|
	CDsoFrameHookManager* pManager = NULL;
 | 
						|
	ODS("CDsoFrameHookManager::RegisterFramerControl\n");
 | 
						|
    CHECK_NULL_RETURN(hwndControl, NULL);
 | 
						|
 | 
						|
	EnterCriticalSection(&v_csecThreadSynch);
 | 
						|
	pManager = vgGlobalManager;
 | 
						|
	if (pManager == NULL)
 | 
						|
		pManager = (vgGlobalManager = new CDsoFrameHookManager());
 | 
						|
	LeaveCriticalSection(&v_csecThreadSynch);
 | 
						|
 | 
						|
	if (pManager)
 | 
						|
	{
 | 
						|
        if (hwndParent == NULL)
 | 
						|
            hwndParent = hwndControl;
 | 
						|
 | 
						|
		if (FAILED(pManager->AddComponent(hwndParent, hwndControl)))
 | 
						|
			return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	return pManager;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFrameHookManager::AddComponent
 | 
						|
//
 | 
						|
//  Register the component and create the actual frame hook (if needed).
 | 
						|
//
 | 
						|
STDMETHODIMP CDsoFrameHookManager::AddComponent(HWND hwndParent, HWND hwndControl)
 | 
						|
{
 | 
						|
	DWORD dwHostProcessID;
 | 
						|
	CDsoFrameWindowHook* phook;
 | 
						|
	HRESULT hr = E_OUTOFMEMORY;
 | 
						|
	HWND hwndNext, hwndHost = hwndParent;
 | 
						|
	ODS("CDsoFrameHookManager::AddComponent\n");
 | 
						|
 | 
						|
 // Find the top-level window this control is sited on...
 | 
						|
	while (hwndNext = GetParent(hwndHost))
 | 
						|
		hwndHost = hwndNext;
 | 
						|
 | 
						|
 // We have to get valid window that is in-thread for a subclass to work...
 | 
						|
	if (!IsWindow(hwndHost) || 
 | 
						|
		(GetWindowThreadProcessId(hwndHost, &dwHostProcessID), 
 | 
						|
			dwHostProcessID != GetCurrentProcessId()))
 | 
						|
		return E_ACCESSDENIED;
 | 
						|
 | 
						|
 // Next if we have room in the array, add the component to the list and
 | 
						|
 // hook its parent window so we get messages for it.
 | 
						|
	EnterCriticalSection(&v_csecThreadSynch);
 | 
						|
	if ((vgGlobalManager) && (m_cComponents < DSOF_MAX_CONTROLS))
 | 
						|
	{
 | 
						|
	 // Hook the host window for this control...
 | 
						|
		phook = CDsoFrameWindowHook::AttachToFrameWindow(hwndHost);
 | 
						|
		if (phook) 
 | 
						|
		{// Add the component to the list if hooked...
 | 
						|
			m_pComponents[m_cComponents].hwndControl = hwndControl;
 | 
						|
			m_pComponents[m_cComponents].phookFrame  = phook;
 | 
						|
			m_cComponents++; hr = S_OK; 
 | 
						|
		}
 | 
						|
	}
 | 
						|
	LeaveCriticalSection(&v_csecThreadSynch);
 | 
						|
 | 
						|
	if (SUCCEEDED(hr)) // Make sure item is the new active component
 | 
						|
		hr = SetActiveComponent(hwndControl);
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFrameHookManager::DetachComponent(HWND hwndControl)
 | 
						|
{
 | 
						|
	DWORD dwIndex;
 | 
						|
	CHECK_NULL_RETURN(m_cComponents, E_FAIL);
 | 
						|
 | 
						|
 // Find this control in the list...
 | 
						|
	for (dwIndex = 0; dwIndex < m_cComponents; dwIndex++)
 | 
						|
		if (m_pComponents[dwIndex].hwndControl == hwndControl) break;
 | 
						|
 | 
						|
	if (dwIndex > m_cComponents)
 | 
						|
		return E_INVALIDARG;
 | 
						|
 | 
						|
 // If we found the index, remove the item and shift remaining
 | 
						|
 // items down the list. Change active index as needed...
 | 
						|
	EnterCriticalSection(&v_csecThreadSynch);
 | 
						|
 | 
						|
	m_pComponents[dwIndex].hwndControl = NULL;
 | 
						|
	m_pComponents[dwIndex].phookFrame->Detach();
 | 
						|
 | 
						|
 // Compact the list...
 | 
						|
	while (++dwIndex < m_cComponents)
 | 
						|
	{
 | 
						|
		m_pComponents[dwIndex-1].hwndControl = m_pComponents[dwIndex].hwndControl;
 | 
						|
		m_pComponents[dwIndex-1].phookFrame = m_pComponents[dwIndex].phookFrame;
 | 
						|
		m_pComponents[dwIndex].hwndControl = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
 // Decrement the count. If count still exists, forward activation
 | 
						|
 // to next component in the list...
 | 
						|
	if (--m_cComponents)
 | 
						|
	{
 | 
						|
		while (m_idxActive >= m_cComponents)
 | 
						|
			--m_idxActive;
 | 
						|
 | 
						|
		HWND hwndActive = GetActiveComponentWindow();
 | 
						|
		if (hwndActive) 
 | 
						|
			SendNotifyMessage(hwndActive, DSO_WM_HOOK_NOTIFY_COMPACTIVE, (WPARAM)TRUE, (LPARAM)(m_fAppActive));
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		vgGlobalManager = NULL;
 | 
						|
	 // If this is the last control, we can remove the manger!
 | 
						|
		delete this;
 | 
						|
	}
 | 
						|
 | 
						|
	LeaveCriticalSection(&v_csecThreadSynch);
 | 
						|
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFrameHookManager::SetActiveComponent(HWND hwndControl)
 | 
						|
{
 | 
						|
	ODS(" -- CDsoFrameHookManager::SetActiveComponent -- \n");
 | 
						|
	CHECK_NULL_RETURN(m_cComponents, E_FAIL);
 | 
						|
	DWORD dwIndex;
 | 
						|
 | 
						|
 // Find the index of the control...
 | 
						|
	for (dwIndex = 0; dwIndex < m_cComponents; dwIndex++)
 | 
						|
		if (m_pComponents[dwIndex].hwndControl == hwndControl) break;
 | 
						|
 | 
						|
	if (dwIndex > m_cComponents)
 | 
						|
		return E_INVALIDARG;
 | 
						|
 | 
						|
 // If it is not already the active item, notify old component it is
 | 
						|
 // losing activation, and notify new component that it is gaining...
 | 
						|
	EnterCriticalSection(&v_csecThreadSynch);
 | 
						|
	if (dwIndex != m_idxActive)
 | 
						|
	{
 | 
						|
		HWND hwndActive = GetActiveComponentWindow();
 | 
						|
		if (hwndActive) 
 | 
						|
			SendNotifyMessage(hwndActive, DSO_WM_HOOK_NOTIFY_COMPACTIVE, (WPARAM)FALSE, (LPARAM)0);
 | 
						|
 | 
						|
		m_idxActive = dwIndex;
 | 
						|
 | 
						|
		hwndActive = GetActiveComponentWindow();
 | 
						|
		if (hwndActive)
 | 
						|
			SendNotifyMessage(hwndActive, DSO_WM_HOOK_NOTIFY_COMPACTIVE, (WPARAM)TRUE, (LPARAM)(m_fAppActive));
 | 
						|
	}
 | 
						|
	LeaveCriticalSection(&v_csecThreadSynch);
 | 
						|
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP CDsoFrameHookManager::OnComponentNotify(DWORD msg, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	TRACE3("CDsoFrameHookManager::OnComponentNotify(%d, %d, %d)\n", msg, wParam, lParam);
 | 
						|
	HWND hwndActiveComp = GetActiveComponentWindow();
 | 
						|
	
 | 
						|
 // The manager needs to keep track of AppActive state...
 | 
						|
	if (msg == DSO_WM_HOOK_NOTIFY_APPACTIVATE)
 | 
						|
	{
 | 
						|
		EnterCriticalSection(&v_csecThreadSynch);
 | 
						|
		m_fAppActive = (BOOL)wParam;
 | 
						|
		LeaveCriticalSection(&v_csecThreadSynch);
 | 
						|
	}
 | 
						|
 | 
						|
 // Send the message to the active component
 | 
						|
    SendNotifyMessage(hwndActiveComp, msg, wParam, lParam);
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
STDMETHODIMP_(BOOL) CDsoFrameHookManager::SendNotifyMessage(HWND hwnd, DWORD msg, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
    BOOL fResult;
 | 
						|
 | 
						|
 // Check if the caller is on the same thread as the active component. If so we can
 | 
						|
 // forward the message directly for processing. If not, we have to post and wait for
 | 
						|
 // that thread to process message at a later time...
 | 
						|
	if (GetWindowThreadProcessId(hwnd, NULL) == GetCurrentThreadId())
 | 
						|
	{ // Notify now...
 | 
						|
		fResult = (BOOL)SendMessage(hwnd, msg, wParam, lParam);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{ // Notify later...
 | 
						|
		fResult = PostMessage(hwnd, msg, wParam, lParam);
 | 
						|
	}
 | 
						|
 | 
						|
    return fResult;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFrameWindowHook
 | 
						|
//
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFrameWindowHook::AttachToFrameWindow
 | 
						|
//
 | 
						|
//  Creates the frame hook for the host window.
 | 
						|
//
 | 
						|
STDMETHODIMP_(CDsoFrameWindowHook*) CDsoFrameWindowHook::AttachToFrameWindow(HWND hwndParent)
 | 
						|
{
 | 
						|
	CDsoFrameWindowHook* phook = NULL;
 | 
						|
	BOOL fHookSuccess = FALSE;
 | 
						|
 | 
						|
 // We have to get valid window ...
 | 
						|
	if (!IsWindow(hwndParent))
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	EnterCriticalSection(&v_csecThreadSynch);
 | 
						|
	phook = CDsoFrameWindowHook::GetHookFromWindow(hwndParent);
 | 
						|
	if (phook)
 | 
						|
	{ // Already have this window hooked, so just addref the count.
 | 
						|
		phook->AddRef();
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{ // Need to create a new hook object for this window...
 | 
						|
		if ((phook = new CDsoFrameWindowHook()))
 | 
						|
		{
 | 
						|
			phook->m_hwndTopLevelHost = hwndParent;
 | 
						|
			phook->m_fHostUnicodeWindow = (v_fUnicodeAPI && IsWindowUnicode(hwndParent));
 | 
						|
 | 
						|
		 // Setup the subclass using Unicode or Ansi methods depending on window 
 | 
						|
		 // create state. Note if either property assoc or window subclass fail...
 | 
						|
			if (phook->m_fHostUnicodeWindow)
 | 
						|
			{
 | 
						|
				fHookSuccess = SetPropW(hwndParent, L"DSOFramerWndHook", (HANDLE)phook);
 | 
						|
				if (fHookSuccess)
 | 
						|
				{
 | 
						|
					phook->m_pfnOrigWndProc = (WNDPROC)SetWindowLongW(hwndParent, GWL_WNDPROC, (LONG)(WNDPROC)HostWindowProcHook);
 | 
						|
					fHookSuccess = (phook->m_pfnOrigWndProc != NULL);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				fHookSuccess = SetPropA(hwndParent, "DSOFramerWndHook", (HANDLE)phook);
 | 
						|
				if (fHookSuccess)
 | 
						|
				{
 | 
						|
					phook->m_pfnOrigWndProc = (WNDPROC)SetWindowLongA(hwndParent, GWL_WNDPROC, (LONG)(WNDPROC)HostWindowProcHook);
 | 
						|
					fHookSuccess = (phook->m_pfnOrigWndProc != NULL);
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
		 // If we failed the subclass, kill this object and return error...
 | 
						|
			if (!fHookSuccess)
 | 
						|
			{
 | 
						|
				delete phook;
 | 
						|
				phook = NULL;
 | 
						|
			}
 | 
						|
			else phook->m_cHookCount++;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	LeaveCriticalSection(&v_csecThreadSynch);
 | 
						|
 | 
						|
	return phook;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFrameWindowHook::Detach
 | 
						|
//
 | 
						|
//  Removes the hook from the frame window if this is the last control
 | 
						|
//  to reference the hook.
 | 
						|
//
 | 
						|
STDMETHODIMP CDsoFrameWindowHook::Detach()
 | 
						|
{
 | 
						|
 // Only need to call this if item is attached.
 | 
						|
	EnterCriticalSection(&v_csecThreadSynch);
 | 
						|
	if (m_cHookCount)
 | 
						|
	{
 | 
						|
		if (--m_cHookCount == 0)
 | 
						|
		{ // We can remove the hook!
 | 
						|
			if (m_fHostUnicodeWindow)
 | 
						|
			{
 | 
						|
				SetWindowLongW(m_hwndTopLevelHost, GWL_WNDPROC, (LONG)(m_pfnOrigWndProc));
 | 
						|
				RemovePropW(m_hwndTopLevelHost, L"DSOFramerWndHook");
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				SetWindowLongA(m_hwndTopLevelHost, GWL_WNDPROC, (LONG)(m_pfnOrigWndProc));
 | 
						|
				RemovePropA(m_hwndTopLevelHost, "DSOFramerWndHook");
 | 
						|
			}
 | 
						|
			m_hwndTopLevelHost = NULL;
 | 
						|
 | 
						|
		// we can kill this object now...
 | 
						|
			delete this;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	LeaveCriticalSection(&v_csecThreadSynch);
 | 
						|
	return S_OK;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFrameWindowHook::GetHookFromWindow
 | 
						|
//
 | 
						|
//  Returns the hook control associated with this object.
 | 
						|
//
 | 
						|
STDMETHODIMP_(CDsoFrameWindowHook*) CDsoFrameWindowHook::GetHookFromWindow(HWND hwnd)
 | 
						|
{
 | 
						|
	CDsoFrameWindowHook* phook = (CDsoFrameWindowHook*)GetPropW(hwnd, L"DSOFramerWndHook");
 | 
						|
	if (phook == NULL) phook = (CDsoFrameWindowHook*)GetPropA(hwnd, "DSOFramerWndHook");
 | 
						|
	return phook;
 | 
						|
}
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////
 | 
						|
// CDsoFrameWindowHook::HostWindowProcHook
 | 
						|
//
 | 
						|
//  The window proc for the subclassed host window.
 | 
						|
//
 | 
						|
STDMETHODIMP_(LRESULT) CDsoFrameWindowHook::HostWindowProcHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | 
						|
{
 | 
						|
	CDsoFrameWindowHook* phook = CDsoFrameWindowHook::GetHookFromWindow(hwnd);
 | 
						|
	if (phook) // We better get our prop for this window!
 | 
						|
	{
 | 
						|
	 // We handle the important ActiveDocument frame-level events like task 
 | 
						|
	 // window activation/deactivation, palette change notfication, and key/mouse
 | 
						|
	 // focus notification on host app focus...
 | 
						|
		switch (msg)
 | 
						|
		{
 | 
						|
		case WM_ACTIVATEAPP:
 | 
						|
			if (vgGlobalManager)
 | 
						|
				vgGlobalManager->OnComponentNotify(DSO_WM_HOOK_NOTIFY_APPACTIVATE, wParam, lParam);
 | 
						|
			break;
 | 
						|
 | 
						|
		case WM_PALETTECHANGED:
 | 
						|
			if (vgGlobalManager)
 | 
						|
				vgGlobalManager->OnComponentNotify(DSO_WM_HOOK_NOTIFY_PALETTECHANGE, wParam, lParam);
 | 
						|
			break;
 | 
						|
 | 
						|
        case WM_SYNCPAINT:
 | 
						|
			if (vgGlobalManager)
 | 
						|
				vgGlobalManager->OnComponentNotify(DSO_WM_HOOK_NOTIFY_SYNCPAINT, wParam, lParam);
 | 
						|
			break;
 | 
						|
 | 
						|
		}
 | 
						|
 | 
						|
	 // After processing, allow calls to fall through to host app. We need to call
 | 
						|
	 // the appropriate handler for Unicode or non-Unicode windows...
 | 
						|
		if (phook->m_fHostUnicodeWindow)
 | 
						|
			return CallWindowProcW(phook->m_pfnOrigWndProc, hwnd, msg, wParam, lParam);
 | 
						|
		else
 | 
						|
			return CallWindowProcA(phook->m_pfnOrigWndProc, hwnd, msg, wParam, lParam);
 | 
						|
	}
 | 
						|
 | 
						|
 // Should not be reached, but just in case call default proc...
 | 
						|
	return (IsWindowUnicode(hwnd) ? 
 | 
						|
			DefWindowProcW(hwnd, msg, wParam, lParam) : 
 | 
						|
			DefWindowProcA(hwnd, msg, wParam, lParam));
 | 
						|
} |