📄 dxfrobj.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
* @doc INTERNAL
*
* @module - DXFROBJ.C |
*
* implementation of a generic IDataObject data transfer object.
* This object is suitable for use in OLE clipboard and drag drop
* operations
*
* Author: <nl>
* alexgo (4/25/95)
*
* Revisions: <nl>
* murrays (7/13/95) auto-doc'd and added cf_RTF
*
*/
#include "_common.h"
#include "_edit.h"
#include "_dxfrobj.h"
#include "_range.h"
#include "hash.h"
#define NUMOBJCOPIEDFORWAITCURSOR 1
#ifdef PEGASUS
#define NUMCHARCOPIEDFORWAITCURSOR 4096
#else
#define NUMCHARCOPIEDFORWAITCURSOR 16384
#endif
//
// Common Data types
//
// If you change g_rgFETC[], change g_rgDOI[] and enum FETCINDEX and CFETC in
// _dxfrobj.h accordingly, and register nonstandard clipboard formats in
// RegisterFETCs(). Order entries in order of most desirable to least, e.g.,
// RTF in front of plain text.
FORMATETC g_rgFETC[] =
{
{0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, // CF_RTFUTF8
{0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, // cf_RTF
{0, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE},// EmbObject
{0, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE},// EmbSource
{0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, // ObjDesc
{0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, // LnkSource
{CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT},
{CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
{CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI},
{0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, // RTF with no objs
{CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
{CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
{0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, // Filename
{0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}, // CF_RTFASTEXT
{0, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE},// Text with objs
{0, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE} // Richedit
};
// Keep in sync with above and with FETCINDEX and CFETC
const DWORD g_rgDOI[] =
{
DOI_CANPASTERICH, // RTF in UTF8 encoding
DOI_CANPASTERICH, // RTF
DOI_CANPASTEOLE, // Embedded Object
DOI_CANPASTEOLE, // Embed Source
DOI_NONE, // Object Descriptor
DOI_CANPASTEOLE, // Link Source
DOI_CANPASTEOLE, // Metafile
DOI_CANPASTEOLE, // DIB
DOI_CANPASTEOLE, // Bitmap
DOI_CANPASTERICH, // RTF with no objects
DOI_CANPASTEPLAIN, // Unicode plain text
DOI_CANPASTEPLAIN, // ANSI plain text
DOI_CANPASTEOLE, // Filename
DOI_CANPASTEPLAIN, // Pastes RTF as text
DOI_CANPASTERICH, // Richedit Text
DOI_CANPASTERICH // RichEdit Text w/formatting
};
/*
* RegisterFETCs()
*
* @func
* Register nonstandard format ETCs. Called when DLL is loaded
*
*/
void RegisterFETCs()
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "RegisterFETCs");
#ifdef RTF_HASHCACHE
HashKeyword_Init(); // init the rtf control keyword hash table.
#endif
#ifndef MACPORT
g_rgFETC[iRtfFETC].cfFormat
= RegisterClipboardFormatA("Rich Text Format");
g_rgFETC[iRtfUtf8].cfFormat
= RegisterClipboardFormatA("RTF in UTF8");
g_rgFETC[iRtfAsTextFETC].cfFormat
= RegisterClipboardFormatA("RTF As Text");
g_rgFETC[iRichEdit].cfFormat
= RegisterClipboardFormatA("RICHEDIT");
g_rgFETC[iObtDesc].cfFormat
= RegisterClipboardFormatA(CF_OBJECTDESCRIPTOR);
g_rgFETC[iEmbObj].cfFormat
= RegisterClipboardFormatA(CF_EMBEDDEDOBJECT);
g_rgFETC[iEmbSrc].cfFormat
= RegisterClipboardFormatA(CF_EMBEDSOURCE);
g_rgFETC[iLnkSrc].cfFormat
= RegisterClipboardFormatA(CF_LINKSOURCE);
g_rgFETC[iRtfNoObjs].cfFormat
= RegisterClipboardFormatA("Rich Text Format Without Objects");
g_rgFETC[iTxtObj].cfFormat
= RegisterClipboardFormatA("RichEdit Text and Objects");
g_rgFETC[iFilename].cfFormat
= RegisterClipboardFormatA(CF_FILENAME);
#else
// MacPort: Should we even bother to register the clipboard formats if we
// are not going to use WLM clipboard???
if(!g_rgFETC[iRtfFETC].cfFormat)
{
g_rgFETC[iRtfFETC].cfFormat = RegisterClipboardFormatA("RTF ");
g_rgFETC[iRtfFETC].cfFormat = 'RTF ';
}
if(!g_rgFETC[iRtfAsTextFETC].cfFormat)
{
g_rgFETC[iRtfAsTextFETC].cfFormat = RegisterClipboardFormatA("RTFT");
g_rgFETC[iRtfAsTextFETC].cfFormat = 'RTFT';
}
if(!g_rgFETC[iRichEdit].cfFormat)
{
g_rgFETC[iRichEdit].cfFormat = RegisterClipboardFormatA("RTE ");
g_rgFETC[iRichEdit].cfFormat = 'RTE ';
}
if(!g_rgFETC[iObtDesc].cfFormat)
{
g_rgFETC[iObtDesc].cfFormat = RegisterClipboardFormatA(CF_OBJECTDESCRIPTOR);
g_rgFETC[iObtDesc].cfFormat = cfObjectDescriptor;
}
if(!g_rgFETC[iEmbObj].cfFormat)
{
g_rgFETC[iEmbObj].cfFormat = RegisterClipboardFormatA(CF_EMBEDDEDOBJECT);
g_rgFETC[iEmbObj].cfFormat = cfEmbeddedObject;
}
if(!g_rgFETC[iEmbSrc].cfFormat)
{
g_rgFETC[iEmbSrc].cfFormat = RegisterClipboardFormatA(CF_EMBEDSOURCE);
g_rgFETC[iEmbSrc].cfFormat = cfEmbedSource;
}
if(!g_rgFETC[iLnkSrc].cfFormat)
{
g_rgFETC[iLnkSrc].cfFormat = RegisterClipboardFormatA(CF_LINKSOURCE);
g_rgFETC[iLnkSrc].cfFormat = cfLinkSource;
}
if(!g_rgFETC[iRtfNoObjs].cfFormat)
{
g_rgFETC[iRtfNoObjs].cfFormat = RegisterClipboardFormatA("RwoO");
g_rgFETC[iRtfNoObjs].cfFormat = 'RwoO';
}
if(!g_rgFETC[iTxtObj].cfFormat)
{
g_rgFETC[iTxtObj].cfFormat = RegisterClipboardFormatA("RTnO");
g_rgFETC[iTxtObj].cfFormat = 'RTnO';
}
if(!g_rgFETC[iFilename].cfFormat)
{
g_rgFETC[iFilename].cfFormat = RegisterClipboardFormatA(CF_FILENAME);
g_rgFETC[iFilename].cfFormat = cfFileName;
}
if(!g_rgFETC[iRtfUtf8].cfFormat)
{
g_rgFETC[iRtfUtf8].cfFormat = RegisterClipboardFormatA("UTF8 RTF");
g_rgFETC[iRtfUtf8].cfFormat = 'UTF8 RTF';
}
#endif
}
//
// CDataTransferObj PUBLIC methods
//
/*
* CDataTransferObj::QueryInterface (riid, ppv)
*
* @mfunc
* QueryInterface for CDataTransferObj
*
* @rdesc
* HRESULT
*/
STDMETHODIMP CDataTransferObj::QueryInterface (
REFIID riid, // @parm Reference to requested interface ID
void ** ppv) // @parm out parm for interface ptr
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::QueryInterface");
if(!ppv)
return E_INVALIDARG;
*ppv = NULL;
if(IsZombie()) // Check for range zombie
return CO_E_RELEASED;
HRESULT hresult = E_NOINTERFACE;
if( IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IDataObject) ||
IsEqualIID(riid, IID_IRichEditDO) )
{
*ppv = this;
AddRef();
hresult = NOERROR;
}
return hresult;
}
/*
* CDataTransferObj::AddRef()
*
* @mfunc
* IUnknown method
*
* @rdesc
* ULONG - incremented reference count
*/
STDMETHODIMP_(ULONG) CDataTransferObj::AddRef()
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::AddRef");
return ++_crefs;
}
/*
* CDataTransferObj::Release()
*
* @mfunc
* IUnknown method
*
* @rdesc
* ULONG - decremented reference count
*/
STDMETHODIMP_(ULONG) CDataTransferObj::Release()
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::Release");
_crefs--;
if( _crefs == 0 )
{
GlobalFree(_hPlainText);
GlobalFree(_hRtfText);
GlobalFree(_hRtfUtf8);
delete this;
return 0;
}
return _crefs;
}
/*
* CDataTransferObj::DAdvise (pFormatetc, advf, pAdvSink, pdwConnection)
*
* @mfunc
* establish an advisory connection
*
* @rdesc
* HRESULT = OLE_E_ADVISENOTSUPPORTED
*
* @devnote
* this is a data transfer object, thus the data is a "snapshot" and
* cannot change -- no advises are supported.
*/
STDMETHODIMP CDataTransferObj::DAdvise(
FORMATETC * pFormatetc,
DWORD advf,
IAdviseSink *pAdvSink,
DWORD *pdwConnection)
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::DAdvise");
return OLE_E_ADVISENOTSUPPORTED;
}
/*
* CDataTransferObj::DUnadvise (dwConnection)
*
* @mfunc
* destroy an advisory connection
*
* @rdesc
* HRESULT = OLE_E_ADVISENOTSUPPORTED
*
* @devnote
* this is a data transfer object, thus the data is a "snapshot" and
* cannot change -- no advises are supported.
*/
STDMETHODIMP CDataTransferObj::DUnadvise(
DWORD dwConnection)
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::DUnadvise");
return OLE_E_ADVISENOTSUPPORTED;
}
/*
* CDataTransferObj::EnumDAdvise (ppenumAdvise)
*
* @mfunc
* enumerate advisory connections
*
* @rdesc
* HRESULT = OLE_E_ADVISENOTSUPPORTED
*
* @devnote
* this is a data transfer object, thus the data is a "snapshot" and
* cannot change -- no advises are supported.
*/
STDMETHODIMP CDataTransferObj::EnumDAdvise(
IEnumSTATDATA ** ppenumAdvise)
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::EnumDAdvise");
return OLE_E_ADVISENOTSUPPORTED;
}
/*
* CDataTransferObj::EnumFormatEtc (dwDirection, ppenumFormatEtc)
*
* @mfunc
* returns an enumerator which lists all of the available formats in
* this data transfer object
*
* @rdesc
* HRESULT
*
* @devnote
* we have no 'set' formats for this object
*/
STDMETHODIMP CDataTransferObj::EnumFormatEtc(
DWORD dwDirection, // @parm DATADIR_GET/SET
IEnumFORMATETC **ppenumFormatEtc) // @parm out parm for enum FETC interface
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::EnumFormatEtc");
if(!ppenumFormatEtc)
return E_INVALIDARG;
*ppenumFormatEtc = NULL;
if(IsZombie()) // Check for range zombie
return CO_E_RELEASED;
HRESULT hr = NOERROR;
#ifdef DEBUG
if (dwDirection == DATADIR_SET && !_ped->Get10Mode())
{
Tracef(TRCSEVNONE, "RichEdit 2.0 EnumFormatEtc called with DATADIR_SET");
}
#endif
//Need riched10 compatibility hack to ignore dwDirection
if( (dwDirection == DATADIR_GET) || _ped->Get10Mode())
{
hr = CEnumFormatEtc::Create(_prgFormats, _cTotal, ppenumFormatEtc);
}
return hr;
}
/*
* CDataTransferObj::GetCanonicalFormatEtc( pformatetc, pformatetcOut)
*
* @mfunc
* from the given formatetc, return a more standard (or canonical)
* format.
*
* @rdesc
* HRESULT = E_NOTIMPL
*
* @devnote
* (alexgo): we may need to write this routine if we ever do anything
* snazzy with printers
*/
STDMETHODIMP CDataTransferObj::GetCanonicalFormatEtc(
FORMATETC *pformatetc,
FORMATETC *pformatetcOut)
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::GetCanonicalFormatEtc");
return E_NOTIMPL;
}
/*
* CDataTransferObj::GetData (pformatetcIn, pmedium)
*
* @mfunc
* retrieves data of the specified format
*
* @rdesc
* HRESULT
*/
STDMETHODIMP CDataTransferObj::GetData(
FORMATETC *pformatetcIn,
STGMEDIUM *pmedium )
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CDataTransferObj::GetData");
memset(pmedium, '\0', sizeof(STGMEDIUM));
pmedium->tymed = TYMED_NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -