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

📄 dsofdocobj.cpp

📁 用于在线office文档编辑的控件。可以在线新建文档、修改文档
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	DBPROP            rdbp[4];
	BSTR              bstrLock;
	DWORD             dw = 256;
	CHAR              szUserName[256];

	if (FAILED(CoCreateInstance(CLSID_MSDAIPP_BINDER, NULL,
			CLSCTX_INPROC, IID_IDBProperties, (void**)&pdbprops)))
		return NULL;

	bstrLock = (GetUserName(szUserName, &dw) ? DsoConvertToBSTR(szUserName) : NULL);

	memset(rdbp, 0, sizeof(4 * sizeof(DBPROP)));

	rdbpset.cProperties = 4; 
	rdbpset.guidPropertySet = DBPROPSET_DBINIT;
	rdbpset.rgProperties = rdbp;

	rdbp[0].dwPropertyID = DBPROP_INIT_BINDFLAGS;
	rdbp[0].vValue.vt = VT_I4;
	rdbp[0].vValue.lVal = DBBINDURLFLAG_OUTPUT;

	rdbp[1].dwPropertyID = DBPROP_INIT_LOCKOWNER;
	rdbp[1].vValue.vt = VT_BSTR;
	rdbp[1].vValue.bstrVal = bstrLock;

	rdbp[2].dwPropertyID = DBPROP_INIT_LCID;
	rdbp[2].vValue.vt = VT_I4;
	rdbp[2].vValue.lVal = GetThreadLocale();

	rdbp[3].dwPropertyID = DBPROP_INIT_PROMPT;
	rdbp[3].vValue.vt = VT_I2;
	rdbp[3].vValue.iVal = DBPROMPT_COMPLETE;

	if (pdbprops->SetProperties(1, &rdbpset) == S_OK)
	{
		hr = pdbprops->QueryInterface(IIDX_IBindResource, (void**)&pres);
	}

    SAFE_FREEBSTR(bstrLock);
	pdbprops->Release();

	return (IUnknown*)pres;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::DownloadWebResource (protected)
//
//  Downloads the file specified by the URL to the given temp file. Locks
//  the web resource for editing if ppstmKeepForSave is requested.
//
STDMETHODIMP CDsoDocObject::DownloadWebResource(LPWSTR pwszURL, LPWSTR pwszFile, LPWSTR pwszUsername, LPWSTR pwszPassword, IStream** ppstmKeepForSave)
{
	HRESULT        hr    = E_UNEXPECTED;
	IStream       *pstm  = NULL;
	IBindResource *pres  = NULL;
	BYTE          *rgbBuf;
	DWORD   dwStatus, dwBindFlags;
	ULONG   cbRead, cbWritten;
	HANDLE  hFile;

 // First thing, we save out the user name and password (if provided)
 // for IAuthenticate which can be caled by either URLMON or MSDAIPP...
	if (pwszUsername)
	{
		SAFE_FREESTRING(m_pwszUsername);
		m_pwszUsername = DsoCopyString(pwszUsername);

		SAFE_FREESTRING(m_pwszPassword);
		m_pwszPassword = DsoCopyString(pwszPassword);
	}

 // If we don't need to write access, we can just use IE for "read-only" download...
    if (ppstmKeepForSave == NULL)
	{
        hr = URLDownloadFile((IUnknown*)&m_xAuthenticate, pwszURL, pwszFile);
		if (SUCCEEDED(hr) || (hr == E_ABORT)) return hr;
	  // If it fails for whatever reason, try MSDAIPP (which can use
	  // FPSE authentication as well as HTTP/DAV web access)...
	}

 // Otherwise, we want to use MSDAIPP for full access...
	if (!m_punkRosebud) return DSO_E_REQUIRESMSDAIPP;

	rgbBuf = new BYTE[10240]; //a 10-k buffer for reading
	if (!rgbBuf) return E_OUTOFMEMORY;

 // Use IBindResource::Bind to open an IStream and copy out the date to
 // the file given. This will then be used to load the object from the file...
	if (SUCCEEDED(m_punkRosebud->QueryInterface(IIDX_IBindResource, (void**)&pres)))
	{
		dwBindFlags = (DBBINDURLFLAG_READ | DBBINDURLFLAG_OUTPUT);
		if (ppstmKeepForSave)
			dwBindFlags |= (DBBINDURLFLAG_WRITE | DBBINDURLFLAG_SHARE_DENY_WRITE); //DBBINDURLFLAG_SHARE_EXCLUSIVE);
callagain:
		if (SUCCEEDED(hr = pres->Bind(NULL, pwszURL, dwBindFlags, DBGUIDX_STREAM, 
				IID_IStream, (IAuthenticate*)&m_xAuthenticate, NULL, &dwStatus, (IUnknown**)&pstm)))
		{
			LARGE_INTEGER lintStart; lintStart.QuadPart = 0;
			hr = pstm->Seek(lintStart, STREAM_SEEK_SET, NULL);

			if (FOpenLocalFile(pwszFile, GENERIC_WRITE, 0, CREATE_ALWAYS, &hFile))
			{
				while (SUCCEEDED(hr))
				{
					if (FAILED(hr = pstm->Read((void*)rgbBuf, 10240, &cbRead)) ||
						(cbRead == 0))
						break;

					if (FALSE == WriteFile(hFile, rgbBuf, cbRead, &cbWritten, NULL))
					{
						hr = E_WIN32_LASTERROR;
						break;
					}
				}

				CloseHandle(hFile);
			}
            else hr = E_WIN32_LASTERROR;

			if (ppstmKeepForSave)
                { SAFE_SET_INTERFACE(*ppstmKeepForSave, pstm); }

			pstm->Release();
		}
		else if ((hr == DB_E_NOTSUPPORTED) && ((dwBindFlags & DBBINDURLFLAG_OUTPUT) == DBBINDURLFLAG_OUTPUT))
		{
		 // WEC4 does not support DBBINDURLFLAG_OUTPUT flag, but if we are using WEC
		 // we don't really need the flag since this is not an HTTP GET call. Flip the
		 // flag off and call the method again to connect to server...
			dwBindFlags &= ~DBBINDURLFLAG_OUTPUT; 
			goto callagain;
		}

  		pres->Release();
	}

 // Map an OLEDB error to a common "file" error so a user
 // (and VB/VBScript) would better understand... 
	if (FAILED(hr))
	{
		switch (hr)
		{
		case DB_E_NOTFOUND:             hr = STG_E_FILENOTFOUND; break;
		case DB_E_READONLY:
		case DB_E_RESOURCELOCKED:       hr = STG_E_LOCKVIOLATION; break;
		case DB_SEC_E_PERMISSIONDENIED:
		case DB_SEC_E_SAFEMODE_DENIED:  hr = E_ACCESSDENIED; break;
		case DB_E_CANNOTCONNECT:
		case DB_E_TIMEOUT:              hr = E_VBA_NOREMOTESERVER; break;
		case E_NOINTERFACE:             hr = E_UNEXPECTED; break;
		}
	}

	delete [] rgbBuf;
	return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::UploadWebResource (protected)
//
//  Uploads the file to a URL. The code can be used two ways:
//
//  1.) If ppstmSave contains a pointer to an existing IStream*, then we 
//      just upload to the existing stream. This allows for normal "Save"
//      on an open web resource.
//
//  2.) If ppstmSave is NULL (or contains a NULL IStream*), we create a new
//      web resource at the location given by pwszURLSaveTo and save to its
//      stream. If ppstmSave is passed, we return the new IStream* to the
//      caller who can then use it to do the other type of save next time.
//
STDMETHODIMP CDsoDocObject::UploadWebResource(LPWSTR pwszFile, IStream** ppstmSave, LPWSTR pwszURLSaveTo, BOOL fOverwriteFile, LPWSTR pwszUsername, LPWSTR pwszPassword)
{
	HRESULT     hr     = E_UNEXPECTED;
	ICreateRow *pcrow  = NULL;
	IStream    *pstm   = NULL;
	BYTE       *rgbBuf;
	HANDLE      hFile;
	BOOL        fstmIn = FALSE;
	ULONG       cbRead, cbWritten;
	DWORD       dwStatus, dwBindFlags;

	ASSERT(m_punkRosebud); // MSDAIPP is required for save...
	if (!m_punkRosebud) return DSO_E_REQUIRESMSDAIPP;

 // Check if this a "Save" on existing IStream* and jump to loop...
	if ((ppstmSave) && (fstmIn = (BOOL)(pstm = *ppstmSave)))
		goto uploadfrominstm;

 // Save the user name and password (if provided) for IAuthenticate...
	if (pwszUsername)
	{
		SAFE_FREESTRING(m_pwszUsername);
		m_pwszUsername = DsoCopyString(pwszUsername);

		SAFE_FREESTRING(m_pwszPassword);
		m_pwszPassword = DsoCopyString(pwszPassword);
	}

 // Check the URL string and ask for ICreateRow (to make new web resource)... 
	if (!(pwszURLSaveTo) || !LooksLikeHTTP(pwszURLSaveTo) ||
		FAILED(m_punkRosebud->QueryInterface(IIDX_ICreateRow, (void**)&pcrow)))
		return hr;

	dwBindFlags = ( DBBINDURLFLAG_READ | 
					DBBINDURLFLAG_WRITE | 
					DBBINDURLFLAG_SHARE_DENY_WRITE | 
                    (fOverwriteFile ? DBBINDURLFLAG_OVERWRITE : 0));

	if (SUCCEEDED(hr = pcrow->CreateRow(NULL, pwszURLSaveTo, dwBindFlags, DBGUIDX_STREAM,
			IID_IStream, (IAuthenticate*)&m_xAuthenticate, NULL, &dwStatus, NULL, (IUnknown**)&pstm)))
	{

	 // Once we are here, we have a stream (either handed in or opened from above).
	 // We just loop through and read from the file to the stream...
uploadfrominstm:
		if (rgbBuf = new BYTE[10240]) //a 10-k buffer for reading
		{
			if (FOpenLocalFile(pwszFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &hFile))
			{
				LARGE_INTEGER lintStart; lintStart.QuadPart = 0;
				hr = pstm->Seek(lintStart, STREAM_SEEK_SET, NULL);

				while (SUCCEEDED(hr))
				{
					if (FALSE == ReadFile(hFile, rgbBuf, 10240, &cbRead, NULL))
					{
						hr = E_WIN32_LASTERROR;
						break;
					}

					if (0 == cbRead) break;

					if (FAILED(hr = pstm->Write((void*)rgbBuf, cbRead, &cbWritten)))
						break;
				}

			 // Need to commit the changes to make it official...
				if (SUCCEEDED(hr))
					hr = pstm->Commit(STGC_DEFAULT);

				CloseHandle(hFile);
			}
            else hr = E_WIN32_LASTERROR;

			delete [] rgbBuf;
		}
        else hr = E_OUTOFMEMORY;

	 // If we are not using a passed in IStream (and therefore created one), we
	 // should AddRef and pass back (if caller asked us to)...
		if (!fstmIn)
		{
			if (SUCCEEDED(hr) && (ppstmSave) && (!(*ppstmSave)))
			{
                SAFE_SET_INTERFACE(*ppstmSave, pstm);
			}
			pstm->Release();
		}

	}

 // Map an OLEDB error to a common "file" error so a user
 // (and VB/VBScript) would better understand... 
    if (FAILED(hr))
	{
		switch (hr)
		{
		case DB_E_RESOURCEEXISTS:       hr = STG_E_FILEALREADYEXISTS; break;
		case DB_E_NOTFOUND:             hr = STG_E_PATHNOTFOUND; break;
		case DB_E_READONLY:
		case DB_E_RESOURCELOCKED:       hr = STG_E_LOCKVIOLATION; break;
		case DB_SEC_E_PERMISSIONDENIED:
		case DB_SEC_E_SAFEMODE_DENIED:  hr = E_ACCESSDENIED; break;
		case DB_E_CANNOTCONNECT:
		case DB_E_TIMEOUT:              hr = E_VBA_NOREMOTESERVER; break;
		case DB_E_OUTOFSPACE:           hr = STG_E_MEDIUMFULL; break;
		case E_NOINTERFACE:             hr = E_UNEXPECTED; break;
		}
	}

	if (pcrow)
		pcrow->Release();

	return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::TurnOffWebToolbar (protected)
//
//  This function "turns off" the Web toolbar used by Office apps to 
//  do in-site navigation. The problem is when toggling tools off the
//  bar may still be visible, so we have to explicitly turn it off if
//  we want a true "no tool" state.
//
STDMETHODIMP_(void) CDsoDocObject::TurnOffWebToolbar()
{
	IDispatch *pdisp;
	VARIANT    vtT[5];

 // Can't change toolbar state in print preview...
    if (InPrintPreview()) return;

	if ((m_pipactive) && 
		(SUCCEEDED(m_pipactive->QueryInterface(IID_IDispatch, (void**)&pdisp))))
	{
		if (SUCCEEDED(DsoDispatchInvoke(pdisp, 
				L"CommandBars", 0, DISPATCH_PROPERTYGET, 0, NULL, &vtT[0])))
		{
			ASSERT(vtT[0].vt == VT_DISPATCH);
			vtT[1].vt = VT_BSTR; vtT[1].bstrVal = SysAllocString(L"Web");

			if (SUCCEEDED(DsoDispatchInvoke(vtT[0].pdispVal, 
				L"Item", 0, DISPATCH_PROPERTYGET, 1, &vtT[1], &vtT[2])))
			{
				ASSERT(vtT[2].vt == VT_DISPATCH);
				vtT[3].vt = VT_BOOL; vtT[3].boolVal = 0;
				DsoDispatchInvoke(vtT[2].pdispVal, 
					L"Visible", 0, DISPATCH_PROPERTYPUT, 1, &vtT[3], &vtT[2]);
				VariantClear(&vtT[2]);
			}

			VariantClear(&vtT[1]);
			VariantClear(&vtT[0]);
		}

		pdisp->Release();
	}

}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::ClearMergedMenu (protected)
//
//  Frees the merged menu set by host.
//
STDMETHODIMP_(void) CDsoDocObject::ClearMergedMenu()
{	
	if (m_hMenuMerged)
	{
        int cbMenuCnt = GetMenuItemCount(m_hMenuMerged);
		for (int i = cbMenuCnt; i >= 0; --i)
		    RemoveMenu(m_hMenuMerged, i, MF_BYPOSITION);

		DestroyMenu(m_hMenuMerged);
		m_hMenuMerged = NULL;
	}
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::CalcDocNameIndex (protected)
//
//  Calculates position of the name portion of the full path string.
//
STDMETHODIMP_(DWORD) CDsoDocObject::CalcDocNameIndex(LPCWSTR pwszPath)
{
    DWORD cblen, idx = 0;
    if ((pwszPath) && ((cblen = lstrlenW(pwszPath)) > 1))
    {
        for (idx = cblen; idx > 0; --idx)
        {
            if (pwszPath[idx] == L'\\')
                break;
        }

        if ((idx) && !(++idx < cblen))
            idx = 0;
    }
    return idx;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::IsStorageDirty
//
//  Ask the object if it is dirty and return result.
//
STDMETHODIMP_(BOOL) CDsoDocObject::IsStorageDirty()
{
	BOOL fDirty = TRUE; // Assume we are dirty unless object says we are not
	IPersistStorage *pprststg;
	IPersistFile *pprst;

	// Can't be dirty without object
	CHECK_NULL_RETURN(m_pole, FALSE);

	// Ask object its dirty state. Use IPersistStorage (it is more ac

⌨️ 快捷键说明

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