📄 oledlgs1.cpp
字号:
// 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 + -