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

📄 olecli1.cpp

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// 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_OLE_SEG
#pragma code_seg(AFX_OLE_SEG)
#endif

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

#define new DEBUG_NEW

/////////////////////////////////////////////////////////////////////////////
// COleClientItem - Container view of IOleObject and related interfaces

COleClientItem::COleClientItem(COleDocument* pContainerDoc)
{
	if (pContainerDoc != NULL)
		ASSERT_VALID(pContainerDoc);

	// initialize OLE client side view of IOleObject
	m_lpObject = NULL;
	m_lpViewObject = NULL;
	m_dwConnection = 0;
	m_lpStorage = NULL;
	m_lpLockBytes = NULL;
	m_scLast = S_OK;
	m_pView = NULL;
	m_pInPlaceFrame = NULL;
	m_pInPlaceDoc = NULL;
	m_nItemState = emptyState;  // initially empty until OleLoad, OleCreate
	m_bMoniker = FALSE;
	m_nDrawAspect = DVASPECT_CONTENT;   // default draw aspect
	m_dwItemNumber = 0;
	m_bLinkUnavail = FALSE; // set to TRUE on failed DoVerb, or in links dialog
	m_nItemType = OT_UNKNOWN;       // type unknown so far
	m_hWndServer = NULL;
	m_bClosing = FALSE; // COleClientItem::Close in process
	m_bLocked = FALSE;  // need CoLockObjectExternal(..., FALSE, ...)

	// initialize compound file support
	m_lpNewStorage = NULL;
	m_bNeedCommit = FALSE;

	if (pContainerDoc != NULL)
		pContainerDoc->AddItem(this);

	ASSERT(m_pDocument == pContainerDoc);
	ASSERT_VALID(this);

	AfxOleLockApp();
}

COleClientItem::~COleClientItem()
{
	ASSERT_VALID(this);

	// release any references we may have to other objects
	Release();

	// only remove it from the associated document if it hasn't been detached
	//  from the document already!
	if (m_pDocument != NULL)
		m_pDocument->RemoveItem(this);

	// make sure all outside connections are disconnected
	ExternalDisconnect();
	AfxOleUnlockApp();
}

void COleClientItem::Delete(BOOL bAutoDelete)
{
	USES_CONVERSION;
	ASSERT_VALID(this);

	Release();      // first close it

	COleDocument* pDoc = GetDocument();
	if (pDoc != NULL && pDoc->m_bCompoundFile)
	{
		// cleanup docfile storage first
		COleDocument* pDoc = GetDocument();
		ASSERT_VALID(pDoc);

		if (pDoc->m_lpRootStg != NULL)
		{
			// get item name
			TCHAR szItemName[OLE_MAXITEMNAME];
			GetItemName(szItemName);

			// attempt to remove it from the storage, ignore errors
			pDoc->m_lpRootStg->DestroyElement(T2COLE(szItemName));
		}
	}

	if (bAutoDelete)
	{
		// remove item from document
		if (pDoc != NULL)
			pDoc->RemoveItem(this);

		InternalRelease();  // remove the item from memory
	}
}

void COleClientItem::Release(OLECLOSE dwCloseOption)
{
	ASSERT_VALID(this);

	m_scLast = S_OK;

	// cleanup view advise
	if (m_lpViewObject != NULL)
	{
		DWORD dwAspect;
	  IAdviseSink* pAdviseSink;

	  pAdviseSink = NULL;
		VERIFY(m_lpViewObject->GetAdvise(&dwAspect, NULL, &pAdviseSink) == S_OK);
	  if( pAdviseSink != NULL )
	  {
		 RELEASE( pAdviseSink );
	  }
		VERIFY(m_lpViewObject->SetAdvise(dwAspect, 0, NULL) == S_OK);
		RELEASE(m_lpViewObject);
	}

	// cleanup the OLE object itself
	if (m_lpObject != NULL)
	{
		// cleanup object advise
		if (m_dwConnection != 0)
		{
			VERIFY(m_lpObject->Unadvise(m_dwConnection) == S_OK);
			m_dwConnection = 0;
		}

		// close object and save (except now when called from destructor)
		//  (NOTE: errors are _not_ reported as an exception)
		m_scLast = m_lpObject->Close(dwCloseOption);
		RELEASE(m_lpObject);
	}

	// cleanup storage related data
	RELEASE(m_lpStorage);
	RELEASE(m_lpLockBytes);

	// cleanup in-place editing data
	if (m_pInPlaceFrame != NULL)
	{
		m_pInPlaceFrame->InternalRelease();
		m_pInPlaceFrame = NULL;
		if (m_pInPlaceDoc != NULL)
		{
			m_pInPlaceDoc->InternalRelease();
			m_pInPlaceDoc = NULL;
		}
	}
	ASSERT(m_pInPlaceFrame == NULL);
	ASSERT(m_pInPlaceDoc == NULL);
}

void COleClientItem::Close(OLECLOSE dwCloseOption)
{
	ASSERT_VALID(this);
	ASSERT(m_lpObject != NULL);

	// gaurd against re-entry
	if (m_bClosing)
		return;

	m_bClosing = TRUE;

	// attempt to close the object
	m_scLast = m_lpObject->Close(dwCloseOption);

	// remove external lock placed on item during in-place activation
	if (m_bLocked)
	{
		OleLockRunning(m_lpObject, FALSE, TRUE);
		m_bLocked = FALSE;
	}

	// handle failure cases -- COleClientItem::Close can be used to
	//  robustly handle a server crashing (ie. something unexpected happens,
	//  we'll call COleClientItem::Close to attempt safe shutdown)
	if (GetItemState() != loadedState)
	{
		// We'll call COleClientItem::Close anywhere a catastrophe
		//  happens inside of other portions of COleClientItem.  We must
		//  completely exit from any in-place/open state.

		// force transition from activeUIState to activeState
		if (GetItemState() == activeUIState)
			OnDeactivateUI(FALSE);

		// force transition from activeState to loadedState
		if (GetItemState() == activeState)
			OnDeactivate();

		if (m_nItemState != loadedState)
		{
			// in case of extreme failure, force loadedState
			OnChange(OLE_CHANGED_STATE, (DWORD)loadedState);
			m_nItemState = loadedState; // force it to loaded state
		}
	}

	m_bClosing = FALSE; // now safe for further close calls
}

/////////////////////////////////////////////////////////////////////////////
// COleClientItem name management

DWORD COleClientItem::GetNewItemNumber()
{
	ASSERT_VALID(this);

	COleDocument* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	DWORD dwNextItemNumber = pDoc->m_dwNextItemNumber;

	for (;;)
	{
		// make sure that m_dwNextItemNumber is not used in another item first
		POSITION pos = pDoc->GetStartPosition();
		COleClientItem* pItem;
		while ((pItem = pDoc->GetNextClientItem(pos)) != NULL)
		{
			if (pItem->m_dwItemNumber == dwNextItemNumber)
				break;
		}
		if (pItem == NULL)
			break;  // no item using m_dwNextItemNumber

		// m_dwNextItemNumber is in use, bump to next one!
		++dwNextItemNumber;
	}

	pDoc->m_dwNextItemNumber = dwNextItemNumber + 1;
	return dwNextItemNumber;
}

void COleClientItem::GetItemName(LPTSTR lpszItemName) const
{
	ASSERT_VALID(this);
	ASSERT(lpszItemName != NULL);

	wsprintf(lpszItemName, _T("Embedding %lu"), m_dwItemNumber);
	ASSERT(lstrlen(lpszItemName) < OLE_MAXITEMNAME);
}

// extracts icon resource ID and path name from registry "file.exe,35" format
static void AfxGetIconInfo(LPCTSTR lpszRegInfo, LPTSTR lpszImagePath,
	UINT& nIndex)
{
	LPTSTR pstrTarget = lpszImagePath;
	LPCTSTR pstrSource = lpszRegInfo;
	while (*pstrSource != ',' && *pstrSource != '\0')
	{
		*pstrTarget = *pstrSource;
		pstrTarget = _tcsinc(pstrTarget);
		pstrSource = _tcsinc(pstrSource);
	}
	*pstrTarget = '\0';

	// extract the index
	if (*pstrSource != '\0')
	{
		LPTSTR pstrIndex = _tcsinc(pstrSource);
		nIndex = (UINT) _ttol(pstrIndex);
	}
	else
		nIndex = 0;
}

HICON COleClientItem::GetIconFromRegistry() const
{
	CLSID clsid;
	GetClassID(&clsid);
	if (clsid == CLSID_NULL)
		return NULL;

	return GetIconFromRegistry(clsid);
}

HICON COleClientItem::GetIconFromRegistry(CLSID& clsid)
{
	// This function will extract the icon registered as the DefaultIcon
	// for the server referred to by clsid.  We get the ProgID for the server
	// and then extract \\hkcr\progid\DefaultIcon.  If that doesn't exist, we
	// get a default icon from \\hkcr\DocShortcut\DefaultIcon and if that fails
	// we just return 0.

	USES_CONVERSION;

	HICON hIcon = NULL;
	HRESULT hr;
	OLECHAR *szCLSID;
	DWORD dwType = 0;
	TCHAR szName[MAX_PATH+1];
	TCHAR szPathName[MAX_PATH+1];
	HKEY hkeyObj;
	HKEY hkeyDefIcon;
	HKEY hkeyCLSID;
	UINT nIndex;

	hr = ::StringFromCLSID(clsid, &szCLSID);
	if (!SUCCEEDED(hr))
		return NULL;

	// first, try for the real icon
	if (RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("clsid"), 0, KEY_READ, &hkeyCLSID) == ERROR_SUCCESS)
	{
		if (RegOpenKeyEx(hkeyCLSID, OLE2T(szCLSID), 0, KEY_READ, &hkeyObj) == ERROR_SUCCESS)
		{
			if (RegOpenKeyEx(hkeyObj, _T("DefaultIcon"), 0, KEY_READ, &hkeyDefIcon) == ERROR_SUCCESS)
			{
				DWORD dwCount;
				dwCount = sizeof(szName);
				if (RegQueryValueEx(hkeyDefIcon, NULL, NULL, &dwType, (BYTE*) szName, &dwCount) == ERROR_SUCCESS)
				{
					AfxGetIconInfo(szName, szPathName, nIndex);

					// Load the icon
					hIcon = ::ExtractIcon(AfxGetApp()->m_hInstance, szPathName, nIndex);

					// ExtractIcon() failure case means NULL return
					if (int(hIcon) == 1)
						hIcon = NULL;
				}
				RegCloseKey(hkeyDefIcon);
			}
			RegCloseKey(hkeyObj);
		}
		RegCloseKey(hkeyCLSID);
	}

	// if we didn't get the real icon, try the default icon
	if (hIcon == NULL)
	{
		if (RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("DocShortcut"), 0, KEY_READ,&hkeyObj) == ERROR_SUCCESS)
		{
			if (RegOpenKeyEx(hkeyObj, _T("DefaultIcon"), 0, KEY_READ, &hkeyDefIcon) == ERROR_SUCCESS)
			{
				DWORD dwCount;
				dwCount = sizeof(szName);
				if (RegQueryValueEx(hkeyDefIcon, NULL, NULL, &dwType, (BYTE*) szName, &dwCount) == ERROR_SUCCESS)
				{
					AfxGetIconInfo(szName, szPathName, nIndex);

					// Load the icon
					hIcon = ::ExtractIcon(AfxGetApp()->m_hInstance, szPathName, nIndex);

					// ExtractIcon() failure case means NULL return
					if (int(hIcon) == 1)
						hIcon = NULL;
				}
				RegCloseKey(hkeyDefIcon);
			}
			RegCloseKey(hkeyObj);
		}
	}

	::CoTaskMemFree(szCLSID);
	return hIcon;
}

/////////////////////////////////////////////////////////////////////////////
// COleClientItem creation helpers

void COleClientItem::UpdateItemType()
{
	ASSERT_VALID(this);
	ASSERT(m_lpObject != NULL);

	// check for linked object
	LPOLELINK lpOleLink = QUERYINTERFACE(m_lpObject, IOleLink);
	if (lpOleLink != NULL)
	{
		lpOleLink->Release();
		m_nItemType = OT_LINK;
		return;
	}

	// check for static object
	DWORD dwStatus;
	if (m_lpObject->GetMiscStatus(DVASPECT_CONTENT, &dwStatus) == S_OK
		&& (dwStatus & OLEMISC_STATIC) == 0)
	{
		m_nItemType = OT_EMBEDDED;
		return;
	}

	// not not link, not embedding -- must be static
	m_nItemType = OT_STATIC;
}

BOOL COleClientItem::FinishCreate(SCODE sc)
{
	USES_CONVERSION;

	ASSERT_VALID(this);
	ASSERT(m_pView == NULL);

	TRY
	{
		// m_lpObject is currently an IUnknown, convert to IOleObject
		if (m_lpObject != NULL)
		{
			LPUNKNOWN lpUnk = m_lpObject;
			m_lpObject = QUERYINTERFACE(lpUnk, IOleObject);
			lpUnk->Release();
			if (m_lpObject == NULL)
				AfxThrowOleException(E_OUTOFMEMORY);
		}

		// check return code from create function
		CheckGeneral(sc);

		UpdateItemType();

		// cache the IViewObject interface
		m_lpViewObject = QUERYINTERFACE(m_lpObject, IViewObject2);
		if (m_lpViewObject == NULL)
			CheckGeneral(E_NOINTERFACE);
		ASSERT(m_lpViewObject != NULL);

		if (GetType() != OT_STATIC)
		{
			// setup for advises; we assume that OLE cleans them up properly
			LPADVISESINK lpAdviseSink =
				(LPADVISESINK)GetInterface(&IID_IAdviseSink);
			ASSERT(lpAdviseSink != NULL);
			CheckGeneral(m_lpObject->Advise(lpAdviseSink, &m_dwConnection));
			ASSERT(m_dwConnection != 0);

			// set up view advise
			VERIFY(m_lpViewObject->SetAdvise(DVASPECT_CONTENT, 0, lpAdviseSink)
				== S_OK);

			// the server shows these in its user-interface
			//  (as document title and in File Exit menu)
			m_lpObject->SetHostNames(T2COLE(AfxGetAppName()),
				T2COLE(m_pDocument->GetTitle()));

⌨️ 快捷键说明

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