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

📄 dsofdocobj.cpp

📁 用于在线office文档编辑的控件。可以在线新建文档、修改文档
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			if (SUCCEEDED(hr = pipf->Load(pwszFile, dwBindFlgs)) && 
				SUCCEEDED(hr = pipf->QueryInterface(IID_IPersistStorage, (void**)&pipstg)))
			{
				if (SUCCEEDED(hr = pipstg->Save(m_pstgfile, FALSE)))
					hr = pipstg->SaveCompleted(NULL);
			
				pipstg->Release();
			}
			pipf->Release();
		}
	
	}
	else
	{
	 // Other non-BIFF files that are associated with Office (like *.rtf/*.csv)
	 // we can open based on a moniker. This is a more traditional (i.e., OLE
	 // "Insert From File") way of binding, which uses an inproc handler...
		if (SUCCEEDED(hr = CreateFileMoniker(pwszFile, &pmkfile)))
		{
			if (SUCCEEDED(hr = CreateBindCtx(0, &pbctx)))
			{
			 // We ask for IPersistStorage and do a formal Save to our IStorage...
				if (SUCCEEDED(hr = pmkfile->BindToObject(pbctx, NULL, IID_IPersistStorage, (void**)&pipstg))) 
				{
					if (SUCCEEDED(hr = pipstg->Save(m_pstgfile, FALSE)))
						hr = pipstg->SaveCompleted(NULL);
				
					pipstg->Release();
				}
				else if (hr == E_NOINTERFACE) // Somehow we got a server that doesn't handle OLE embedding...
					hr = STG_E_NOTFILEBASEDSTORAGE;

				if (SUCCEEDED(hr) && (!fReadOnly))
				{
				 // If we have our copy and user wants to keep a lock on original source,
				 // we'll try to get the lock by asking for the file's IStorage...
					BIND_OPTS bopts = {sizeof(BIND_OPTS), 1, dwBindFlgs, 0};
					pbctx->SetBindOptions(&bopts);
					pmkfile->BindToStorage(pbctx, NULL, IID_IStorage, (void**)&pstg);
				}
				pbctx->Release();
			}
			pmkfile->Release();
		}
	}

 // Assuming everything above worked...
	if (SUCCEEDED(hr))
	{ 
     // We are read-only until told otherwise...
	    m_fOpenReadOnly = TRUE;
		m_pwszSourceFile = DsoCopyString(pwszFile);
        m_idxSourceName = CalcDocNameIndex(m_pwszSourceFile);

	  // Let's go ahead and create the object, and keep the lock pointers...
		if (SUCCEEDED(hr = CreateDocObject(clsid)) && (fReadOnly == FALSE))
		{
			m_fOpenReadOnly = FALSE;
            SAFE_SET_INTERFACE(m_pstgSourceFile, pstg);
		}
	}

 // If we aren't locking, this will free the file...
	if (pstg) pstg->Release();

	return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::LoadStorageFromURL
//
//  Loads the internal IStorage from a URL (http: or https:).
//
//  The idea here is we do a download from the URL and open the result
//  as any other file using LoadStorageFromFile. This requires MSDAIPP
//  which ships with MDAC 2.5, Office 2000/XP, or Windows 2000/XP.
//
STDMETHODIMP CDsoDocObject::LoadStorageFromURL(LPWSTR pwszURL, REFCLSID rclsid, BOOL fReadOnly, LPWSTR pwszUserName, LPWSTR pwszPassword)
{
	HRESULT	   hr;
	IStream   *pstmWebResource = NULL;
	LPWSTR     pwszTempFile;

 // We will need access to MSDAIPP unless it is read-only request...
	if (!(m_punkRosebud) && !(m_punkRosebud = CreateRosebudIPP()) && (!fReadOnly))
		return DSO_E_REQUIRESMSDAIPP;

 // Get the temp path for download...
	if (!GetTempPathForURLDownload(pwszURL, &pwszTempFile))
		return E_INVALIDARG;

 // Now get the resource from URLMON or MSDAIPP...
	if (SUCCEEDED(hr = DownloadWebResource(pwszURL, pwszTempFile,
        pwszUserName, pwszPassword, ((fReadOnly) ? NULL : &pstmWebResource))))
	{
     // If that worked, open from the downloaded resource...
		if (SUCCEEDED(hr = LoadStorageFromFile(pwszTempFile, rclsid, fReadOnly)) && 
			((pstmWebResource) && (!fReadOnly)))
		{
			m_fOpenReadOnly = FALSE;
			m_pwszWebResource = DsoCopyString(pwszURL);
			SAFE_SET_INTERFACE(m_pstmWebResource, pstmWebResource);
		}

		if (pstmWebResource)
			pstmWebResource->Release();
	}

	DsoMemFree(pwszTempFile);
	return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::LoadFromAutomationObject
//
//  Copies the storage of the current automation object and loads a new
//  embedded object from the persisted state. This allows you to load 
//  a visible instance of a document previously open and edited by automation.
//
STDMETHODIMP CDsoDocObject::LoadFromAutomationObject(LPUNKNOWN punkObj, REFCLSID rclsid, BOOL fReadOnly)
{
	HRESULT hr;
	IPersistStorage *prststg;
	IOleObject *pole;
	CLSID clsid;

	ODS("CDsoDocObject::LoadFromAutomationObject()\n");
    CHECK_NULL_RETURN(punkObj, E_POINTER);

 // First, ensure the object passed supports embedding (i.e., we expect
 // something like a Word.Document or Excel.Sheet object, not a Word.Application
 // object or something else that is not a document type)...
	hr = punkObj->QueryInterface(IID_IOleObject, (void**)&pole);
	if (FAILED(hr)) return hr;

 // Ask the object to save its persistent state. We also collect its CLSID and
 // validate that the object type supports DocObject embedding...
	hr = pole->QueryInterface(IID_IPersistStorage, (void**)&prststg);
	if (SUCCEEDED(hr))
	{
		hr = prststg->GetClassID(&clsid); // Validate the object type...
		if (FAILED(hr) || ((clsid == GUID_NULL) && ((clsid = rclsid) == GUID_NULL)) || 
            FAILED(ValidateDocObjectServer(clsid)))
		{
			hr = DSO_E_INVALIDSERVER;
		}
		else
		{
         // Create a matching storage for the object and save the current
         // state of the file in our storage (this is our private copy)...
			if (SUCCEEDED(hr = CreateObjectStorage(clsid)) &&
				SUCCEEDED(hr = prststg->Save(m_pstgfile, FALSE)) &&
				SUCCEEDED(hr = prststg->SaveCompleted(NULL)))
			{
             // At this point we have a read-only copy...
                // prststg->HandsOffStorage();
                m_fOpenReadOnly = TRUE;

             // Create the embedding...
                hr = CreateDocObject(clsid);

             // If caller wants us to keep track of file for save (write access)
             // we can do so with moniker. Keep in mind this is does not keep a
             // lock on the resource and may fail the save if auto object is still
             // open and has exclusive access at time of the save, but it is the
             // best option we have when DocObject is loaded from an object already
             // open and locked by another application or component.
                if (SUCCEEDED(hr) && (!fReadOnly))
                {
                    IPersistMoniker *prstmk = NULL;
                    IMoniker *pmk = NULL;

                    if (SUCCEEDED(pole->GetMoniker(OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_OBJFULL, &pmk)) ||
                        (SUCCEEDED(pole->QueryInterface(IID_IPersistMoniker, (void**)&prstmk)) && 
                         SUCCEEDED(prstmk->GetCurMoniker(&pmk))))
                    {
                    // Keep hold of the source moniker...
                        m_fOpenReadOnly = FALSE;
                        m_pmkSourceObject = pmk;

#ifdef _DEBUG        // For debug trace, we output moniker name we will keep for write...
                        LPOLESTR postr = NULL; IBindCtx *pbc = NULL;
                        if (SUCCEEDED(CreateBindCtx(0, &pbc)))
                        {
                            if (SUCCEEDED(pmk->GetDisplayName(pbc, NULL, &postr)))
                            {
                                TRACE1(" >> Write Moniker = %S \n", postr);
                                CoTaskMemFree(postr);
                            }
                            pbc->Release();
                        }
#endif //_DEBUG
                    }

                    SAFE_RELEASE_INTERFACE(prstmk);
                }
			}
		}

		prststg->Release();
	}

	pole->Release();
	return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::EnsureOleServerRunning
//
//  Verifies the DocObject server is running and is optionally locked
//  while the embedding is taking place.
//
STDMETHODIMP CDsoDocObject::EnsureOleServerRunning(BOOL fLockRunning)
{
	HRESULT hr = S_FALSE;
	IBindCtx *pbc;
	IRunnableObject *pro;
	IOleContainer *pocnt;
	BIND_OPTS bind;

    TRACE1("CDsoDocObject::EnsureOleServerRunning(%d)\n", (DWORD)fLockRunning);
	ASSERT(m_pole);

	if (FAILED(CreateBindCtx(0, &pbc)))
		return E_UNEXPECTED;

 // Setup the bind options for the run operation...
	bind.cbStruct = sizeof(BIND_OPTS);
	bind.grfFlags = BIND_MAYBOTHERUSER;
	bind.grfMode = STGM_READWRITE|STGM_SHARE_EXCLUSIVE;
	bind.dwTickCountDeadline = 20000;
	pbc->SetBindOptions(&bind);

 // Assume we aren't locked running...
	m_fLockedServerRunning = FALSE;

 // Get IRunnableObject and set server to run as OLE object. We check the
 // running state first since this is proper OLE, but note that this is not
 // returned from out-of-proc server, but the in-proc handler. Also note, we
 // specify a timeout in case the object never starts, and "check" the object
 // runs without IMessageFilter errors...
	if (SUCCEEDED(m_pole->QueryInterface(IID_IRunnableObject, (void**)&pro)))
	{
	 
	  // If the object is not currently running, let's run it...
		if (!(pro->IsRunning()))
			hr = pro->Run(pbc);

	  // Set the object server as a contained object (i.e., OLE object)...
		pro->SetContainedObject(TRUE);

	  // Lock running if desired...
		if (fLockRunning)
			m_fLockedServerRunning = SUCCEEDED(pro->LockRunning(TRUE, TRUE));

		pro->Release();
	}
	else if ((fLockRunning) &&
		SUCCEEDED(m_pole->QueryInterface(IID_IOleContainer, (void**)&pocnt)))
	{
		m_fLockedServerRunning = SUCCEEDED(pocnt->LockContainer(TRUE));
		pocnt->Release();
	}

	pbc->Release();
	return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::FreeRunningLock
//
//  Free any previous lock made by EnsureOleServerRunning.
//
STDMETHODIMP_(void) CDsoDocObject::FreeRunningLock()
{
	IRunnableObject *pro;
	IOleContainer *pocnt;

    ODS("CDsoDocObject::FreeRunningLock(%d)\n");
	ASSERT(m_pole);

 // Don't do anything if we didn't lock the server...
	if (m_fLockedServerRunning == FALSE)
		return;

 // Get IRunnableObject and free lock...
	if (SUCCEEDED(m_pole->QueryInterface(IID_IRunnableObject, (void**)&pro)))
	{
		pro->LockRunning(FALSE, TRUE);
		pro->Release();
	}
	else if (SUCCEEDED(m_pole->QueryInterface(IID_IOleContainer, (void**)&pocnt)))
	{
		pocnt->LockContainer(FALSE);
		pocnt->Release();
	}

	m_fLockedServerRunning = FALSE;
	return;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::IPActivateView
//
//  Activates the object for viewing. If we already have an IOleDocumentView
//  we do this by calling Show, otherwise we'll do an IOleObject::DoVerb.
//
STDMETHODIMP CDsoDocObject::IPActivateView()
{
    HRESULT hr = E_UNEXPECTED;
    ODS("CDsoDocObject::IPActivateView()\n");
    ASSERT(m_pole);

 // Normal activation uses IOleObject::DoVerb with OLEIVERB_INPLACEACTIVATE
 // (or OLEIVERB_SHOW), a view rect, and an IOleClientSite pointer...
    if ((m_pole) && (!m_pdocv))
    {
		RECT rcView; GetClientRect(m_hwnd, &rcView);

		hr = m_pole->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, 
				(IOleClientSite*)&m_xOleClientSite, (UINT)-1, m_hwnd, &rcView);

	 // If the DoVerb fails on the InPlaceActivate verb, do a Show...
		if (FAILED(hr))
		{
			DWORD dwLoopCnt = 0;
			do
			{
				Sleep((200 * dwLoopCnt++));

				hr = m_pole->DoVerb(OLEIVERB_SHOW, NULL, 
						(IOleClientSite*)&m_xOleClientSite, (UINT)-1, m_hwnd, &rcView);

			  // There are issues with Visio 2002 rejecting DoVerb calls outright
			  // if it is still loading (instead of returning retry later as it should).
			  // So we might pop out of the message filter early and fail the call
			  // unexpectedly, so this little hack checks for the error and sleeps,
			  // then calls again in a recursive "loop"...
			}
			while ((hr == 0x80010001) && (dwLoopCnt < 10));

		}
    }
	else if (m_pdocv)
	{
	 // If we have an IOleDocument pointer, we can use the "new" method
	 // for inplace activation via Show/UIActivate...
		if (SUCCEEDED(hr = m_pdocv->Show(TRUE)))
			m_pdocv->UIActivate(TRUE);
	}

 // Forward focus as needed...
	if (SUCCEEDED(hr) && (m_hwndIPObject))
		SetFocus(m_hwndIPObject);

    return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::IPDeactivateView
//
//  Deactivates the object.
//
STDMETHODIMP CDsoDocObject::IPDeactivateView()
{
    HRESULT hr = S_OK;
    ODS("CDsoDocObject::IPDeactivateView()\n");

 // If we still have a UI active object, tell it to UI deactivate...
	if (m_pipactive)
		UIActivateView(FALSE);

 // Next hide the active object...
	if (m_pdocv)
        m_pdocv->Show(FALSE);

 // Notify object our intention to IP deactivate...
    if (m_pipobj)
        m_pipobj->InPlaceDeactivate();

 // Close the object down and release pointers...
	if (m_pdocv)
	{
        hr = m_pdocv->CloseView(0);
        m_pdocv->SetInPlaceSite(NULL);
	}

    SAFE_RELEASE_INTERFACE(m_pcmdt);

⌨️ 快捷键说明

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