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

📄 oledlgs1.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"

#ifdef AFX_OLE2_SEG
#pragma code_seg(AFX_OLE2_SEG)
#endif

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW

UINT CALLBACK
AfxOleHookProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

////////////////////////////////////////////////////////////////////////////
// implementation helpers

BOOL AFXAPI _AfxOlePropertiesEnabled()
{
	// edit properties is enabled if there is a handler
	//  for ID_OLE_EDIT_PROPERTIES
	AFX_CMDHANDLERINFO info;

	// check main window first
	CWnd* pWnd = AfxGetMainWnd();
	if (pWnd != NULL && pWnd->OnCmdMsg(ID_OLE_EDIT_PROPERTIES, CN_COMMAND, NULL, &info))
		return TRUE;

	// check app last
	return AfxGetApp()->OnCmdMsg(ID_OLE_EDIT_PROPERTIES, CN_COMMAND, NULL, &info);
}

SCODE _AfxParseDisplayName(LPMONIKER lpmk, LPBC lpbc, LPTSTR lpszRemainder,
	ULONG* cchEaten, LPMONIKER* plpmkOut)
{
	USES_CONVERSION;

	ASSERT(lpmk != NULL);
	ASSERT(AfxIsValidString(lpszRemainder));
	ASSERT(cchEaten != NULL);
	ASSERT(plpmkOut != NULL);

	SCODE sc;
	if (lpbc != NULL)
	{
		// ask moniker to parse the display name itself
		sc = lpmk->ParseDisplayName(lpbc, NULL, T2OLE(lpszRemainder), cchEaten,
			plpmkOut);
	}
	else
	{
		// skip leading delimiters
		int cEaten = 0;
		LPTSTR lpszSrc = lpszRemainder;
		while (*lpszSrc != '\0' && (*lpszSrc == '\\' || *lpszSrc == '/' ||
			*lpszSrc == ':' || *lpszSrc == '!' || *lpszSrc == '['))
		{
			if (_istlead(*lpszSrc))
				++lpszSrc, ++cEaten;
			++lpszSrc;
			++cEaten;
		}

		// parse next token in lpszRemainder
		TCHAR szItemName[_MAX_PATH];
		LPTSTR lpszDest = szItemName;
		while (*lpszSrc != '\0' && *lpszSrc != '\\' && *lpszSrc != '/' &&
			*lpszSrc != ':' && *lpszSrc != '!' && *lpszSrc != '[' &&
			cEaten < _MAX_PATH-1)
		{
			if (_istlead(*lpszSrc))
				*lpszDest++ = *lpszSrc++, ++cEaten;
			*lpszDest++ = *lpszSrc++;
			++cEaten;
		}
		*cchEaten = cEaten;
		sc = CreateItemMoniker(OLESTDDELIMOLE, T2COLE(szItemName), plpmkOut);
	}

	return sc;
}

////////////////////////////////////////////////////////////////////////////
// COleUILinkInfo

COleUILinkInfo::COleUILinkInfo(COleDocument* pDocument)
{
	ASSERT(pDocument == NULL ||
		pDocument->IsKindOf(RUNTIME_CLASS(COleDocument)));
	m_pDocument = pDocument;
	m_pSelectedItem = NULL;
	m_pos = NULL;
	m_bUpdateLinks = FALSE;
	m_bUpdateEmbeddings = FALSE;
}

STDMETHODIMP_(ULONG) COleUILinkInfo::AddRef()
{
	return 0;
}

STDMETHODIMP_(ULONG) COleUILinkInfo::Release()
{
	return 0;
}

STDMETHODIMP COleUILinkInfo::QueryInterface(
	REFIID, LPVOID*)
{
	return E_NOTIMPL;
}

STDMETHODIMP_(DWORD) COleUILinkInfo::GetNextLink(
	DWORD dwLink)
{
	ASSERT(m_pDocument != NULL);
	if (dwLink == 0)
	{
		// start enumerating from the beginning
		m_pos = m_pDocument->GetStartPosition();
	}
	COleClientItem* pItem;
	while ((pItem = m_pDocument->GetNextClientItem(m_pos)) != NULL)
	{
		// check for links
		OLE_OBJTYPE objType = pItem->GetType();
		if (m_bUpdateLinks && objType == OT_LINK)
		{
			// link found -- return it
			return (DWORD)(void*)pItem;
		}
		// check for embeddings
		if (m_bUpdateEmbeddings && objType == OT_EMBEDDED)
		{
			// embedding w/mismatched target device
			return (DWORD)(void*)pItem;
		}
	}
	return 0;   // link not found
}

STDMETHODIMP COleUILinkInfo::SetLinkUpdateOptions(
	DWORD dwLink, DWORD dwUpdateOpt)
{
	COleClientItem* pItem = (COleClientItem*)dwLink;
	ASSERT_VALID(pItem);
	ASSERT_KINDOF(COleClientItem, pItem);
	ASSERT(pItem->GetType() == OT_LINK);

	SCODE sc;
	TRY
	{
		// item is a link -- get its link options
		pItem->SetLinkUpdateOptions((OLEUPDATE)dwUpdateOpt);
		sc = S_OK;
	}
	CATCH_ALL(e)
	{
		sc = COleException::Process(e);
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	return sc;
}

STDMETHODIMP COleUILinkInfo::GetLinkUpdateOptions(
	DWORD dwLink, DWORD* lpdwUpdateOpt)
{
	COleClientItem* pItem = (COleClientItem*)dwLink;
	ASSERT_VALID(pItem);
	ASSERT_KINDOF(COleClientItem, pItem);

	SCODE sc;
	TRY
	{
		if (pItem->GetType() == OT_LINK)
			*lpdwUpdateOpt = pItem->GetLinkUpdateOptions();
		else
			*lpdwUpdateOpt = OLEUPDATE_ALWAYS;  // make believe it is auto-link
		sc = S_OK;
	}
	CATCH_ALL(e)
	{
		sc = COleException::Process(e);
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	return sc;
}

STDMETHODIMP COleUILinkInfo::SetLinkSource(
	DWORD dwLink, LPTSTR lpszDisplayName, ULONG lenFileName,
	ULONG* pchEaten, BOOL  fValidateSource)
{
	USES_CONVERSION;

	COleClientItem* pItem = (COleClientItem*)dwLink;
	ASSERT_VALID(pItem);
	ASSERT_KINDOF(COleClientItem, pItem);
	ASSERT(pItem->GetType() == OT_LINK);

	LPOLEOBJECT lpObject = NULL;
	CLSID clsid;

	// parse the portion known to be a file name into a file moniker
	TCHAR szName[_MAX_PATH];
	lstrcpyn(szName, lpszDisplayName, (int)lenFileName + 1);
	LPMONIKER lpmk = NULL;
	SCODE sc = CreateFileMoniker(T2COLE(szName), &lpmk);
	if (lpmk == NULL)
		return sc;

	LPBC lpbc = NULL;
	if (fValidateSource)
	{
		sc = CreateBindCtx(0, &lpbc);
		if (sc != S_OK)
		{
			lpmk->Release();
			return sc;
		}
	}

	// nUneaten is the number of chars left to parse
	UINT nUneaten = lstrlen(lpszDisplayName) - lenFileName;

	// lpszRemainder is the left over display name
	LPTSTR lpszRemainder = lpszDisplayName + lenFileName;
	*pchEaten = lenFileName;

	// parse the rest of the display name
	while (nUneaten > 0)
	{
		// attempt to parse next moniker
		ULONG nEaten = 0;
		LPMONIKER lpmkNext = NULL;
		sc = _AfxParseDisplayName(lpmk, lpbc, lpszRemainder, &nEaten, &lpmkNext);
		if (sc != S_OK)
		{
			lpmk->Release();
			lpbc->Release();
			return sc;
		}

		// advance through the display name
		nUneaten -= nEaten;
		*pchEaten += nEaten;
		lpszRemainder += nEaten;

		if (lpmkNext != NULL)
		{
			// create composite out of current and next
			LPMONIKER lpmkTemp = NULL;
			sc = CreateGenericComposite(lpmk, lpmkNext, &lpmkTemp);
			if (FAILED(sc))
			{
				lpmk->Release();
				lpmkNext->Release();
				lpbc->Release();
				return sc;
			}

			// make current = next
			lpmkNext->Release();
			lpmk->Release();
			lpmk = lpmkTemp;
		}
	}

	if (fValidateSource)
	{
		// attempt to bind the the object
		sc = lpmk->BindToObject(lpbc, NULL, IID_IOleObject, (LPLP)&lpObject);
		if (FAILED(sc))
		{
			pItem->m_bLinkUnavail = TRUE;
			lpbc->Release();
			lpmk->Release();
			RELEASE(lpObject);
			return sc;
		}
		ASSERT(lpObject != NULL);

		// call GetUserClassID while bound so default handler updates
		lpObject->GetUserClassID(&clsid);
		pItem->m_bLinkUnavail = FALSE;
	}

	// get IOleLink interface
	LPOLELINK lpOleLink = QUERYINTERFACE(pItem->m_lpObject, IOleLink);
	ASSERT(lpOleLink != NULL);

	// set source from moniker
	sc = lpOleLink->SetSourceMoniker(lpmk, clsid);

	// update the cache if object was successfully bound
	if (lpObject != NULL)
	{
		lpObject->Update();
		lpObject->Release();
	}

	// cleanup
	lpOleLink->Release();
	RELEASE(lpmk);
	RELEASE(lpbc);

	return sc;
}

STDMETHODIMP COleUILinkInfo::GetLinkSource(
	DWORD dwLink, LPTSTR* lplpszDisplayName, ULONG* lplenFileName,
	LPTSTR* lplpszFullLinkType, LPTSTR* lplpszShortLinkType,
	BOOL* lpfSourceAvailable, BOOL* lpfIsSelected)
{
	COleClientItem* pItem = (COleClientItem*)dwLink;
	ASSERT_VALID(pItem);
	ASSERT_KINDOF(COleClientItem, pItem);
	ASSERT(pItem->GetType() == OT_LINK);

	// set OUT params to NULL
	ASSERT(lplpszDisplayName != NULL);
	*lplpszDisplayName  = NULL;
	if (lplpszFullLinkType != NULL)
		*lplpszFullLinkType = NULL;
	if (lplpszShortLinkType != NULL)
		*lplpszShortLinkType = NULL;
	if (lplenFileName != NULL)
		*lplenFileName = 0;
	if (lpfSourceAvailable != NULL)
		*lpfSourceAvailable = !pItem->m_bLinkUnavail;

	// get IOleLink interface
	LPOLELINK lpOleLink = QUERYINTERFACE(pItem->m_lpObject, IOleLink);
	ASSERT(lpOleLink != NULL);

	// get moniker & object information
	LPMONIKER lpmk;
	if (lpOleLink->GetSourceMoniker(&lpmk) == S_OK)
	{
		if (lplenFileName != NULL)
			*lplenFileName = _AfxOleGetLenFilePrefixOfMoniker(lpmk);
		lpmk->Release();
	}


	// attempt to get the type names of the link
	if (lplpszFullLinkType != NULL)
	{
		LPOLESTR lpOleStr = NULL;
		pItem->m_lpObject->GetUserType(USERCLASSTYPE_FULL, &lpOleStr);
		*lplpszFullLinkType = TASKSTRINGOLE2T(lpOleStr);
		if (*lplpszFullLinkType == NULL)
		{
			TCHAR szUnknown[256];
			VERIFY(AfxLoadString(AFX_IDS_UNKNOWNTYPE, szUnknown) != 0);
			*lplpszFullLinkType = AfxAllocTaskString(szUnknown);
		}
	}
	if (lplpszShortLinkType != NULL)
	{
		LPOLESTR lpOleStr = NULL;
		pItem->m_lpObject->GetUserType(USERCLASSTYPE_SHORT, &lpOleStr);
		*lplpszShortLinkType = TASKSTRINGOLE2T(lpOleStr);
		if (*lplpszShortLinkType == NULL)
		{
			TCHAR szUnknown[256];
			VERIFY(AfxLoadString(AFX_IDS_UNKNOWNTYPE, szUnknown) != 0);
			*lplpszShortLinkType = AfxAllocTaskString(szUnknown);
		}
	}

	// get source display name for moniker
	LPOLESTR lpOleStr = NULL;
	SCODE sc = lpOleLink->GetSourceDisplayName(&lpOleStr);
	*lplpszDisplayName = TASKSTRINGOLE2T(lpOleStr);
	lpOleLink->Release();
	if (sc != S_OK)
		return sc;

	// see if item is selected if specified
	if (lpfIsSelected)
	{
		*lpfIsSelected = (m_pSelectedItem == pItem);
	}

	return S_OK;
}

STDMETHODIMP COleUILinkInfo::OpenLinkSource(DWORD dwLink)
{
	COleClientItem* pItem = (COleClientItem*)dwLink;
	ASSERT_VALID(pItem);
	ASSERT_KINDOF(COleClientItem, pItem);
	ASSERT(pItem->GetType() == OT_LINK);

	SCODE sc;
	TRY
	{
		// Note: no need for valid CView* since links don't activate inplace
		pItem->DoVerb(OLEIVERB_SHOW, NULL);
		sc = S_OK;
	}
	CATCH_ALL(e)
	{
		sc = COleException::Process(e);
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	return sc;
}

STDMETHODIMP COleUILinkInfo::UpdateLink(
	DWORD dwLink, BOOL /*fErrorMessage*/, BOOL /*fErrorAction*/)
{
	COleClientItem* pItem = (COleClientItem*)dwLink;
	ASSERT_VALID(pItem);
	ASSERT_KINDOF(COleClientItem, pItem);

	SCODE sc;
	TRY
	{
		// link not up-to-date, attempt to update it
		if (!pItem->UpdateLink())
			AfxThrowOleException(pItem->GetLastStatus());
		pItem->m_bLinkUnavail = FALSE;
		sc = S_OK;
	}
	CATCH_ALL(e)
	{
		pItem->m_bLinkUnavail = TRUE;
		sc = COleException::Process(e);
		pItem->ReportError(sc);
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	return sc;
}

STDMETHODIMP COleUILinkInfo::CancelLink(DWORD dwLink)
{
	COleClientItem* pItem = (COleClientItem*)dwLink;
	ASSERT_VALID(pItem);
	ASSERT_KINDOF(COleClientItem, pItem);
	ASSERT(pItem->GetType() == OT_LINK);

	SCODE sc = E_FAIL;
	TRY
	{
		if (pItem->FreezeLink())
			sc = S_OK;
	}
	CATCH_ALL(e)
	{
		sc = COleException::Process(e);
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	// report error
	if (sc != S_OK)
		pItem->ReportError(sc);

	return S_OK;
}

STDMETHODIMP COleUILinkInfo::GetLastUpdate(DWORD dwLink, FILETIME*)
{
	COleClientItem* pItem = (COleClientItem*)dwLink;
	ASSERT_VALID(pItem);

	// Note: leave last update time at unknown!

	return S_OK;
}

⌨️ 快捷键说明

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