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

📄 dsofauto.cpp

📁 用于在线office文档编辑的控件。可以在线新建文档、修改文档
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************
 * 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()
{
	HWND hwnd;
    ODS("CDsoFramerControl::Activate\n");

 // Activate this control in multi-control list (if applicable)...
    if ((!m_fComponentActive) && (m_pFrameHook))
	    m_pFrameHook->SetActiveComponent(this);

  // All we need to do is grab focus. This will tell the host to
  // UI activate our OCX (if not done already)...
	SetFocus(m_hwnd);

  // Then if we have an activedocument, ensure it is activated
  // and forward focus...
	if ((m_pDocObjFrame) && (hwnd = m_pDocObjFrame->GetActiveWindow()))
		SetFocus(hwnd);

    m_fComponentActive = TRUE;

	return S_OK;
}

////////////////////////////////////////////////////////////////////////
// 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_FAIL;
    DWORD dwOptions = (DWORD)LONG_FROM_VARIANT(Options, 0);

	TRACE1("CDsoFramerControl::DoOleCommand(%d)\n", OLECMDID);
    CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN));

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

    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;

    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;
	RECT rcPlace;
	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;

    if (m_fModalState) // Cannot access object if in modal condition...
        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::CreateNewDocObject();
	if (!(m_pDocObjFrame)) return E_OUTOFMEMORY;
	m_pDocObjFrame->m_pParentCtrl = this;
 // Start a wait operation to notify user...
	hCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
    GetSizeRectForDocument(NULL, &rcPlace);
    m_fInDocumentLoad = TRUE;

 // Init the doc site for a new instance...
	if (SUCCEEDED(hr = m_pDocObjFrame->InitializeNewInstance(m_hwnd, 
			&rcPlace, m_pwszHostName, (IOleCommandTarget*)&(m_xOleCommandTarget))))
	{
     // 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);

		SEH_TRY

     // If we are loading a template, init the storage before the create...
        if (pstgTemplate)
        {
            hr = m_pDocObjFrame->InitObjectStorage(clsid, pstgTemplate);
            GOTO_ON_FAILURE(hr, error_out);
        }

	  // Create a new doc object and IP activate...
		hr = m_pDocObjFrame->CreateDocObject(clsid);
		if (SUCCEEDED(hr))
		{
				BSTR  dddd;
				StringFromCLSID(clsid,&dddd);
				
				char * pstrNameTemp1 = NULL;
				LPWSTR  pstrNameTemp2;
				if ((dddd) && (SysStringLen(dddd) > 0)){
					pstrNameTemp2 = SysAllocString(dddd);
					pstrNameTemp1 = DsoConvertToMBCS(pstrNameTemp2);
				}
				
				if(0 == strcmp(pstrNameTemp1,"{00020906-0000-0000-C000-000000000046}"))
					m_nOriginalFileType =  FILE_TYPE_WORD;
				else if(0 == strcmp(pstrNameTemp1,"{00020820-0000-0000-C000-000000000046}"))
					m_nOriginalFileType =  FILE_TYPE_EXCEL;
				else if(0 == strcmp(pstrNameTemp1,"{64818D10-4F9B-11CF-86EA-00AA00B929E8}"))
					m_nOriginalFileType = FILE_TYPE_PPT;
				else
					m_nOriginalFileType = FILE_TYPE_UNK;
				
				DsoMemFree((void*)(pstrNameTemp1));
				
				if (!m_fShowToolbars)
					m_pDocObjFrame->OnNotifyChangeToolState(FALSE);
				
				hr = m_pDocObjFrame->IPActivateView();
			}else{
				m_nOriginalFileType = FILE_TYPE_NULL;
			}

        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 if ((m_dispEvents) && !(m_fFreezeEvents))
	{
	 // 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;

		DsoDispatchInvoke(m_dispEvents, NULL, DSOF_DISPID_DOCOPEN, 0, 2, rgargs, NULL);
		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).
//
#include "dsoframer.h" 
#include "msoffice.h"
#include <atlbase.h>
#include <atlconv.h>
#include <afxdisp.h>
extern char* BSTR2char(const BSTR bstr) ;
STDMETHODIMP CDsoFramerControl::Open(VARIANT Document, VARIANT ReadOnly, VARIANT ProgId, VARIANT WebUsername, VARIANT WebPassword)
{
	memset(m_cPassWord,0,128);//Excel的只读密码
	memset(m_cPWWrite,0,128);//Excel的可写密码
	HRESULT   hr;
	LPWSTR    pwszDocument  = LPWSTR_FROM_VARIANT(Document);
	LPWSTR    pwszAltProgId = LPWSTR_FROM_VARIANT(ProgId);
	LPWSTR    pwszUserName  = LPWSTR_FROM_VARIANT(WebUsername);
	LPWSTR    pwszPassword  = LPWSTR_FROM_VARIANT(WebPassword);
    BOOL      fOpenReadOnly = BOOL_FROM_VARIANT(ReadOnly, FALSE);
	CLSID     clsidAlt      = GUID_NULL;
	RECT      rcPlace;
	HCURSOR	  hCur;
    IUnknown* punk = NULL;
	if(ProgId.vt == VT_EMPTY || !pwszAltProgId){
  		pwszAltProgId =  L"Word.Document";
	}else{
		
		if(_wcsicmp(pwszAltProgId,L"doc") == 0 ){
  			pwszAltProgId =  L"Word.Document";
		}else if(_wcsicmp(pwszAltProgId,L"wps") == 0 ){
  			pwszAltProgId =  L"Wps.Document";
		}else if(_wcsicmp(pwszAltProgId,L"xls") == 0 ){
  			pwszAltProgId = L"Excel.Sheet";
		}else if(_wcsicmp(pwszAltProgId,L"ppt") == 0 ){
  			pwszAltProgId =  L"PowerPoint.Slide";
		}
	}

    TRACE1("CDsoFramerControl::Open(%S)\n", pwszDocument);
	USES_CONVERSION;

 // We must have either a string (file path or URL) or an object to open from...
	if (!(pwszDocument) || (*pwszDocument == L'\0'))
    {
        if (!(pwszDocument) && ((punk = PUNK_FROM_VARIANT(Document)) == NULL))
		    return E_INVALIDARG;
    }
	char cHttpURL[1024];
	cHttpURL[0] = 0;
	if(Document.vt = VT_BSTR && m_cUrl && strlen(m_cUrl)<900){
		char *pTemp = NULL;
		pTemp = BSTR2char(Document.bstrVal);
		if(pTemp){
			if(_strnicmp(pTemp, "/", 1) == 0){	
			     strcpy(cHttpURL,m_cUrl);
				 char * p = strrchr(cHttpURL,'/');
				 if(p) *p = 0;
				 strcat(cHttpURL,pTemp); 
				 pwszDocument = A2W(cHttpURL);
			}else if(_strnicmp(pTemp, "./", 2) == 0){  
				strcpy(cHttpURL,m_cUrl);
				 char * p = strrchr(cHttpURL,'/');
				 if(p) *p = 0;
				 strcat(cHttpURL,&pTemp[1]);
				 pwszDocument = A2W(cHttpURL);
			}else if(_strnicmp(pTemp, "../", 3) == 0){ //
				 strcpy(cHttpURL,m_cUrl);
				 char * p = strrchr(cHttpURL,'/');
				 if(++p) *p = 0;
				 strcat(cHttpURL,pTemp);
				 pwszDocument = A2W(cHttpURL);
			}
			free(pTemp);
			pTemp = NULL;
		}
	}

 // If the user passed the ProgId, find the alternative CLSID for server...
	if ((pwszAltProgId) && FAILED(CLSIDFromProgID(pwszAltProgId, &clsidAlt)))
		return E_INVALIDARG;

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

 // OK. If here, all the parameters look good and it is time to try and open
 // the document object. Start by closing any existing document 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...
	if (!(m_pDocObjFrame = CDsoDocObject::CreateNewDocObject()))
		return E_OUTOFMEMORY;

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

	if (SUCCEEDED(hr = m_pDocObjFrame->InitializeNewInstance(m_hwnd, 
			&rcPlace, m_pwszHostName, (IOleCommandTarget*)&(m_xOleCommandTarget))))
	{
//		SEH_TRY
		try{

⌨️ 快捷键说明

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