⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsofauto.cpp

📁 主要用于打开office文档而使用. ole开发,
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************
 * DSOFAUTO.CPP
 *
 * CDsoFramerControl: Automation interface for Binder Control
 *
 *  Copyright ?999-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 - _FramerControl Implementation
//

////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::Activate
//
//  Activate the current embedded document (i.e, forward focus).
//
STDMETHODIMP CDsoFramerControl::Activate()
{
    HRESULT hr;
    ODS("CDsoFramerControl::Activate\n");

	if (m_fInControlActivate)
		return S_FALSE;

 // Don't allow recursion of this function or we could get stuck in
 // loop trying to constantly grab focus.
	m_fInControlActivate = TRUE;

 // All we need to do is grab focus. This will tell the host to
 // UI activate our OCX, set focus to our window, and set this control
 // as the active component with the hook manager. 
    hr = UIActivate(TRUE);

 // Invalidate windows to update painting...
    if (SUCCEEDED(hr))
        InvalidateAllChildWindows(m_hwnd);

	m_fInControlActivate = FALSE;

	return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::get_ActiveDocument
//
//  Returns the automation object currently embedded.
//
//  Since we only support a single instance at a time, it might have been
//  better to call this property Object or simply Document, but VB reserves
//  the first name for use by the control extender, and IE reserves the second
//  in its extender, so we decided on the "Office sounding" name. ;-)
//
STDMETHODIMP CDsoFramerControl::get_ActiveDocument(IDispatch** ppdisp)
{
    HRESULT hr = DSO_E_DOCUMENTNOTOPEN;
	IUnknown* punk;

	ODS("CDsoFramerControl::get_ActiveDocument\n");
    CHECK_NULL_RETURN(ppdisp, E_POINTER); *ppdisp = NULL;

 // Get IDispatch from open document object.
	if ((m_pDocObjFrame) && (punk = (IUnknown*)(m_pDocObjFrame->GetActiveObject())))
	{ 
     // Cannot access object if in print preview..
        if (m_pDocObjFrame->InPrintPreview())
            return ProvideErrorInfo(DSO_E_INMODALSTATE);

	  // Ask ip active object for IDispatch interface. If it is not supported on
      // active object interface, try to get it from OLE object iface...
        if (FAILED(hr = punk->QueryInterface(IID_IDispatch, (void**)ppdisp)) && 
            (punk = (IUnknown*)(m_pDocObjFrame->GetOleObject())))
        {
            hr = punk->QueryInterface(IID_IDispatch, (void**)ppdisp);
        }
        ASSERT(SUCCEEDED(hr));
	}

	return ProvideErrorInfo(hr);
}

////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::ExecOleCommand
//
//  Allows caller to pass commands to embedded object via IOleCommandTarget and
//  gives access to a few extra commands to extend functionality for certain object
//  types (not all objects may support all commands).
//
STDMETHODIMP CDsoFramerControl::ExecOleCommand(LONG OLECMDID, VARIANT Options, VARIANT* vInParam, VARIANT* vInOutParam)
{
	HRESULT hr = E_INVALIDARG;
    DWORD dwOptions = (DWORD)LONG_FROM_VARIANT(Options, 0);

	TRACE1("CDsoFramerControl::DoOleCommand(%d)\n", OLECMDID);

 // Cannot access object if in modal condition...
    if ((m_fModalState) || (m_fNoInteractive))
        return ProvideErrorInfo(DSO_E_INMODALSTATE);

 // Handle some custom commands that don't need doc open to call...
	switch (OLECMDID)
	{
	case OLECMDID_RESETFRAMEHOOK:
		{
			LONG lhwnd = (DWORD)LONG_FROM_VARIANT(*vInParam, 0);
			return ResetFrameHook((HWND)lhwnd);
		}
	case OLECMDID_LOCKSERVER:
		if (BOOL_FROM_VARIANT(Options, TRUE) == FALSE)
			return put_LockServer(VARIANT_FALSE);
	}

 // The rest require a doc object loaded first...
    CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN));

    switch (OLECMDID)
    {
    case OLECMDID_GETDATAFORMAT:
     // If requesting special data get...
        hr = m_pDocObjFrame->HrGetDataFromObject(vInParam, vInOutParam);
        break;

    case OLECMDID_SETDATAFORMAT:
     // If requesting special data set...
        hr = m_pDocObjFrame->HrSetDataInObject(vInParam, vInOutParam, BOOL_FROM_VARIANT(Options, TRUE));
        break;

    case OLECMDID_LOCKSERVER: // optional lock on server...
        if (BOOL_FROM_VARIANT(Options, FALSE))
            hr = put_LockServer(VARIANT_TRUE);
        break;

	case OLECMDID_NOTIFYACTIVE:
		if (vInParam) // Force notify server that it should be active...
		{
			m_pDocObjFrame->OnNotifyAppActivate(BOOL_FROM_VARIANT(*vInParam, FALSE), 0);
			hr = S_OK;
		}
		break;

    default:
     // Do normal IOleCommandTarget call on object...

     // If options was not passed as long, but as bool, we expect the caller meant to
     // specify if user should be prompted or not, so update the options to allow the
     // assuption to still work as expected (this is for compatibility)...
        if ((dwOptions == 0) && ((DsoPVarFromPVarRef(&Options)->vt & 0xFF) == VT_BOOL))
            dwOptions = (BOOL_FROM_VARIANT(Options, FALSE) ? OLECMDEXECOPT_PROMPTUSER : OLECMDEXECOPT_DODEFAULT);

     // Ask object server to do the command...
	    hr = m_pDocObjFrame->DoOleCommand(OLECMDID, dwOptions, vInParam, vInOutParam);
    }
	return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::CreateNew
//
//  Creates a new document object based on the passed in ProgID or Template.
//  ProgID should map to the "document" object, such as "Word.Document",
//  "Excel.Sheet", "PowerPoint.Slide", etc. A Template name should be full
//  path to the file, whether local, UNC, or HTTP path. No relative paths.
//
STDMETHODIMP CDsoFramerControl::CreateNew(BSTR ProgIdOrTemplate)
{
	HRESULT hr;
	CLSID clsid;
	HCURSOR	hCur;
    IStorage *pstgTemplate = NULL;
    LPWSTR pwszTempFile = NULL;

    TRACE1("CDsoFramerControl::CreateNew(%S)\n", ProgIdOrTemplate);

 // Check the string to make sure a valid item is passed...
	if (!(ProgIdOrTemplate) || (SysStringLen(ProgIdOrTemplate) < 4))
		return E_INVALIDARG;

// Cannot create object if we are not activate yet, or if in modal condition...
    if (!(m_fInPlaceActive) || (m_fModalState)) 
        return ProvideErrorInfo(DSO_E_INMODALSTATE);

 // Make sure any open document is closed first...
	if ((m_pDocObjFrame) && FAILED(hr = Close()))
		return hr;

 // Make sure we are the active component for this process...
    if (FAILED(hr = Activate())) return hr;

 // Let's make a doc frame for ourselves...
	m_pDocObjFrame = CDsoDocObject::CreateInstance((IDsoDocObjectSite*)&m_xDsoDocObjectSite);
	if (!(m_pDocObjFrame)) return E_OUTOFMEMORY;

 // Start a wait operation to notify user...
	hCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
    m_fInDocumentLoad = TRUE;

 // If the string passed looks like a URL, it is a web template. We need
 // to download it to temp location and use for new object...
    if (LooksLikeHTTP(ProgIdOrTemplate) && 
        GetTempPathForURLDownload(ProgIdOrTemplate, &pwszTempFile))
    {
     // Ask URLMON to download the file...
        if (FAILED(hr = URLDownloadFile(NULL, ProgIdOrTemplate, pwszTempFile)))
        {
            DsoMemFree(pwszTempFile); pwszTempFile = NULL;
            goto error_out;
        }

     // If that worked, switch out the name of the template to local file...
        ProgIdOrTemplate = SysAllocString(pwszTempFile);
    }

 // If the string is path to file, then it must be a template. It must be
 // a storage file with CLSID associated with it, like any Office templates 
 // (.dot,.xlt,.pot,.vst,etc.), and path must be fully qualified...
    if (LooksLikeUNC(ProgIdOrTemplate) || LooksLikeLocalFile(ProgIdOrTemplate))
    {
        if ((hr = StgIsStorageFile(ProgIdOrTemplate)) != S_OK)
        {
            hr = (FAILED(hr) ? hr : STG_E_NOTFILEBASEDSTORAGE);
            goto error_out;
        }

     // Open the template for read access only...
        hr = StgOpenStorage(ProgIdOrTemplate, NULL, 
            (STGM_READ | STGM_SHARE_DENY_WRITE | STGM_TRANSACTED),
             NULL, 0, &pstgTemplate);
        GOTO_ON_FAILURE(hr, error_out);

     // We get the CLSID from the template...
        hr = ReadClassStg(pstgTemplate, &clsid);
        if (FAILED(hr) || (clsid == GUID_NULL))
        {
            hr = (FAILED(hr) ? hr : STG_E_OLDFORMAT);
            goto error_out;
        } 
 // Otherwise the string passed is assumed a ProgID...
    }
    else if (FAILED(CLSIDFromProgID(ProgIdOrTemplate, &clsid)))
    {
        hr = DSO_E_INVALIDPROGID;
        goto error_out;
    }

 // If we are here, we must have a valid CLSID for the object...
    ASSERT(clsid != GUID_NULL);

 // If we had delayed the frame hook, we should set it up now...
    if (!(m_pHookManager) && FDelayFrameHookSet())
    {
		m_pHookManager = CDsoFrameHookManager::RegisterFramerControl(m_hwndParent, m_hwnd);
		if (!m_pHookManager) {hr = DSO_E_FRAMEHOOKFAILED; goto error_out;}
    }

	SEH_TRY

 // If we are loading a template, init the storage before the create...
    if (pstgTemplate)
    {
        hr = m_pDocObjFrame->CreateDocObject(pstgTemplate);
    }
    else
    {
      // Create a new doc object and IP activate...
	    hr = m_pDocObjFrame->CreateDocObject(clsid);
    }

 // If the call worked, we can activate it...
	if (SUCCEEDED(hr))
	{
        EnableDropFile(FALSE);

		if (!m_fShowToolbars)
			m_pDocObjFrame->OnNotifyChangeToolState(FALSE);

		hr = m_pDocObjFrame->IPActivateView();
	}

    SEH_EXCEPT(hr)

 // Force a close if an error occurred...
	if (FAILED(hr))
	{
error_out:
		m_fFreezeEvents = TRUE;
		Close();
		m_fFreezeEvents = FALSE;
		hr = ProvideErrorInfo(hr);
	}
	else
	{

	 // Fire the OnDocumentOpened event...
		VARIANT rgargs[2]; 
		rgargs[0].vt = VT_DISPATCH;	get_ActiveDocument(&(rgargs[0].pdispVal));
		rgargs[1].vt = VT_BSTR; rgargs[1].bstrVal = NULL;

        RaiseAutomationEvent(DSOF_DISPID_DOCOPEN, 2, rgargs);
		VariantClear(&rgargs[0]);
    
     // Ensure we are active control...
        Activate();

     // Redraw the caption as needed...
        RedrawCaption();
    }

    m_fInDocumentLoad = FALSE;
	SetCursor(hCur);

    SAFE_RELEASE_INTERFACE(pstgTemplate);

 // Delete the temp file used in the URL download (if any)...
    if (pwszTempFile)
    {
        FPerformShellOp(FO_DELETE, pwszTempFile, NULL);
        DsoMemFree(pwszTempFile);
        SysFreeString(ProgIdOrTemplate);
    }

	return hr;
}


////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::Open
//
//  Creates a document object based on a file or URL. This simulates an
//  "open", but preserves the correct OLE embedding activation required
//  by ActiveX Documents. Opening directly from a file is not recommended.
//  We keep a lock on the original file (unless opened read-only) so the
//  user cannot tell we don't have the file "open".
//
//  The alternate ProgID allows us to open a file that is not associated 
//  with an DocObject server (like *.asp) with the server specified. Also
//  the username/password are for web access (if Document is a URL).
//
STDMETHODIMP CDsoFramerControl::Open(VARIANT Document, VARIANT ReadOnly, VARIANT ProgId, VARIANT WebUsername, VARIANT WebPassword)
{
	HRESULT   hr;
	LPWSTR    pwszDocument  = LPWSTR_FROM_VARIANT(Document);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -