ldte.cpp
来自「Windows CE 6.0 Word Application 源码」· C++ 代码 · 共 2,381 行 · 第 1/5 页
CPP
2,381 行
_pdo = NULL;
}
}
/*
* CLightDTEngine::CanPaste(pdo, cf, flags)
*
* @mfunc
* Determines if clipboard format cf is one we can paste.
*
* @rdesc
* BOOL - true if we can paste cf into range prg OR DF_CLIENTCONTROL
* if the client is going to handle this one.
*
* @devnote
* we check the clipboard ourselves if cf is 0. Primarily, this
* is for backwards compatibility with Richedit1.0's EM_CANPASTE
* message.
*
*/
DWORD CLightDTEngine::CanPaste(
IDataObject *pdo, // @parm Data object to check; if NULL use clipboard
CLIPFORMAT cf, // @parm clipboard format to query about; if 0, use
// best available.
DWORD flags) // @parm flags
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CLightDTEngine::CanPaste");
IRichEditOleCallback *precall = _ped->GetRECallback();
CLIPFORMAT cf0 = cf;
DWORD cFETC = CFETC;
HRESULT hr = NOERROR;
DWORD ret = FALSE;
#ifndef MACPORT
if( pdo == NULL && precall )
#else
if( pdo == NULL)
#endif
{
// don't worry about errors
pOleGetClipboard(&pdo);
}
else if( pdo )
{
// so we can make just one 'Release' call below
pdo->AddRef();
}
if( precall && pdo )
{
hr = precall->QueryAcceptData(pdo, &cf, flags, 0, NULL);
if( SUCCEEDED(hr) && (hr != S_OK && hr != DATA_S_SAMEFORMATETC ) )
{
ret = DF_CLIENTCONTROL;
goto Exit;
}
else if( FAILED(hr) && hr != E_NOTIMPL )
{
goto Exit;
}
else if(SUCCEEDED(hr))
{
// we should go on and check ourselves unless the client
// modified the format when it shouldn't have
if( cf0 && cf0 != cf )
{
goto Exit;
}
}
// otherwise, continue with our normal checks
}
if (_ped->TxGetReadOnly()) // Can't paste if read only
goto Exit;
while(cFETC--) // Does cf = format we can paste or
{ // is selection left up to us?
cf0 = g_rgFETC[cFETC].cfFormat;
if( cf == cf0 || !cf )
{
// either we hit the format requested, or no format
// was requested. Now see if the format matches what
// we could handle in principle. There are three
// basic categories:
// 1. we are rich text and have an OLE callback;
// then we can handle pretty much everything.
// 2. we are rich text but have no OLE callback.
// then we can handle anything but OLE specific
// formats.
// 3. we are plain text only. Then we can only
// handle plain text formats.
if( (_ped->_fRich || (g_rgDOI[cFETC] & DOI_CANPASTEPLAIN)) &&
(precall || !(g_rgDOI[cFETC] & DOI_CANPASTEOLE)))
{
// once we get this far, make sure the data format
// is actually available.
if( (pdo && pdo->QueryGetData(&g_rgFETC[cFETC]) == NOERROR ) ||
(!pdo && IsClipboardFormatAvailable(cf0)) )
{
ret = TRUE; // Return arbitrary non zero value.
break;
}
}
}
}
Exit:
if( pdo )
{
pdo->Release();
}
return ret;
}
/*
* CLightDTEngine::RangeToDataObject (prg, lStreamFormat, ppdo)
*
* @mfunc
* Create data object (with no OLE-formats) for the range prg
*
* @rdesc
* HRESULT = !ppdo ? E_INVALIDARG :
* pdo ? NOERROR : E_OUTOFMEMORY
*/
HRESULT CLightDTEngine::RangeToDataObject(
CTxtRange * prg, // @parm Range to get DataObject for
LONG lStreamFormat, // @parm stream format to use for loading
IDataObject ** ppdo) // @parm Out parm for DataObject
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CLightDTEngine::RangeToDataObject");
if(!ppdo)
return E_INVALIDARG;
CDataTransferObj *pdo = CDataTransferObj::Create(_ped, prg, lStreamFormat);
*ppdo = pdo;
return pdo ? NOERROR : E_OUTOFMEMORY;
}
/*
* CLightDTEngine::RenderClipboardFormat(wFmt)
*
* @mfunc
* Renders current clipboard data object in specified format. (Ole less transfer)
*
* @rdesc
* HRESULT
*/
HRESULT CLightDTEngine::RenderClipboardFormat(
WPARAM wFmt)
{
HRESULT hr = E_FAIL;
// GuyBark Jupiter: Added utf8 handling here. The first format that the
// RichEdit pasting code tries is UTF8. Given that RichEdit can copy that
// ok to the clipboard, handle it here. We used to ignore the request for
// utf8 here and then accept the next request which was RTF.
if (_fOleless && (wFmt == cf_RTFUTF8 || wFmt == cf_RTF || wFmt == CF_UNICODETEXT || wFmt == CF_DIB))
{
Assert(_pdo);
STGMEDIUM med;
DWORD iFETC = iUnicodeFETC;
if (wFmt == cf_RTF)
iFETC = iRtfFETC;
else if (wFmt == cf_RTFUTF8)
iFETC = iRtfUtf8;
else if (wFmt == CF_DIB)
iFETC = iDIB;
med.tymed = TYMED_HGLOBAL;
med.pUnkForRelease = NULL;
med.hGlobal = NULL;
hr = _pdo->GetData(&g_rgFETC[iFETC], &med);
if (SUCCEEDED(hr) && ::SetClipboardData(wFmt, med.hGlobal) != NULL)
{
hr = S_OK;
}
}
return hr;
}
/*
* CLightDTEngine::RenderAllClipboardFormats(wFmt)
*
* @mfunc
* Renders current clipboard data object (text and RTF). (Ole less transfer)
*
* @rdesc
* HRESULT
*/
HRESULT CLightDTEngine::RenderAllClipboardFormats()
{
HRESULT hr;
if (_fOleless)
{
HWND howner = ::GetClipboardOwner();
HWND hwnd;
if (howner &&
_ped->TxGetWindow(&hwnd) == NOERROR &&
howner == hwnd &&
::OpenClipboard(hwnd)
)
{
::EmptyClipboard();
hr = RenderClipboardFormat(cf_RTF);
if (SUCCEEDED(hr))
hr = RenderClipboardFormat(CF_UNICODETEXT);
//hr = hr || RenderClipboardFormat(CF_UNICODETEXT);
if (SUCCEEDED(hr))
hr = RenderClipboardFormat(CF_DIB);
//hr = hr || RenderClipboardFormat(CF_DIB);
::CloseClipboard();
return hr;
}
}
return S_OK; // Pretend we did the right thing.
}
/*
* CLightDTEngine::DestroyClipboard()
*
* @mfunc
* Destroys the clipboard data object
*
* @rdesc
* HRESULT
*
*/
HRESULT CLightDTEngine::DestroyClipboard()
{
// Nothing to do. This should work together with our Flush clipboard logic
return S_OK;
}
/*
* CLightDTEngine::HGlobalToRange(dwFormatIndex, hGlobal, ptext, prg, publdr, bDBCString)
*
* @mfunc
* Copies the contents of the given string (ptext) to the given range.
* The global memory handle may or may not point to the string depending
* on the format
*
* @rdesc
* HRESULT
*/
HRESULT CLightDTEngine::HGlobalToRange(
DWORD dwFormatIndex,
HGLOBAL hGlobal,
LPTSTR ptext,
CTxtRange * prg,
IUndoBuilder *publdr,
BOOL bDBCString)
{
READHGLOBAL rhg;
EDITSTREAM es;
BOOL fSetCur=FALSE;
HCURSOR hcur;
// If RTF, wrap EDITSTREAM around hGlobal & delegate to LoadFromEs()
if (dwFormatIndex == iRtfNoObjs || dwFormatIndex == iRtfFETC ||
dwFormatIndex == iRtfUtf8)
{
Assert(hGlobal != NULL);
rhg.ptext = (LPSTR)ptext; // Start at beginning
rhg.cbLeft = GlobalSize(hGlobal); // with full length
es.dwCookie = (DWORD)&rhg; // The read "this" ptr
es.dwError = NOERROR; // No errors yet
es.pfnCallback = ReadHGlobal; // The read method
// DBoone: Want wait cursor to display sooner
if (rhg.cbLeft > 1024) {
hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
fSetCur = TRUE;
}
LoadFromEs(prg, SFF_SELECTION | SF_RTF, &es, TRUE, publdr);
if (fSetCur)
SetCursor(hcur);
return es.dwError;
}
Assert( dwFormatIndex == iRtfAsTextFETC ||
dwFormatIndex == iAnsiFETC ||
dwFormatIndex == iUnicodeFETC );
prg->CleanseAndReplaceRange(-1, ptext, TRUE, publdr);
if(prg->_rpTX.IsAfterEOP()) // If new text ends
{ // with EOP, select
prg->SetExtend(TRUE); // and delete that
prg->BackupCRLF(); // EOP
prg->ReplaceRange(0, NULL, publdr, SELRR_REMEMBERRANGE);
}
return NOERROR;
}
/*
* CLightDTEngine::DIBToRange(hGlobal, prg, publdr)
*
* @mfunc
* Inserts dib data from the clipboard into range in the control
*
* @rdesc
* HRESULT
*
*/
HRESULT CLightDTEngine::DIBToRange(HGLOBAL hGlobal, CTxtRange *prg, IUndoBuilder * publdr)
{
HRESULT hresult = DV_E_FORMATETC;
REOBJECT reobj = { 0 };
LPBITMAPINFO pbmi = (LPBITMAPINFO) GlobalLock(hGlobal);
WCHAR ch = WCH_EMBEDDING;
reobj.clsid = CLSID_StaticDib;
reobj.sizel.cx =
(LONG) _ped->_pdp->DXtoHimetricX( pbmi->bmiHeader.biWidth );
reobj.sizel.cy =
(LONG) _ped->_pdp->DYtoHimetricY( pbmi->bmiHeader.biHeight );
_ped->GetClientSite(&reobj.polesite);
COleObject *pobj = (COleObject *)reobj.polesite;
COleObject::ImageInfo *pimageinfo = new COleObject::ImageInfo;
if(!pimageinfo)
{
hresult = E_OUTOFMEMORY;
goto leave;
}
pobj->SetHdata(hGlobal);
pimageinfo->xScale = 100;
pimageinfo->yScale = 100;
pimageinfo->xExtGoal = reobj.sizel.cx;
pimageinfo->yExtGoal = reobj.sizel.cy;
pimageinfo->cBytesPerLine = 0;
pobj->SetImageInfo(pimageinfo);
if (!reobj.polesite )
{
goto leave;
}
// Put object into the edit control
reobj.cbStruct = sizeof(REOBJECT);
//V-GUYB:
// If there is currently a selection, this will get replaced with the
// WCH_EMBEDDING character. Therefore by the time the object in inserted,
// it will get inserted at what is currently the start of any selection,
// NOT the end of it. So reobj.cp MUST be set to cpMin here. Calling
// prg->GetCp here can return what is currently end of the selection.
#ifdef NEVER
reobj.cp = prg->GetCp();
#else
reobj.cp = prg->GetCpMin();
#endif // NEVER
reobj.dvaspect = DVASPECT_CONTENT;
reobj.dwFlags = REO_RESIZABLE;
// Since we are loading an object, it shouldn't be blank
reobj.dwFlags &= ~REO_BLANK;
prg->Set_iCF(-1);
prg->ReplaceRange(1, &ch, publdr, SELRR_IGNORE);
hresult = _ped->GetObjectMgr()->InsertObject(reobj.cp, &reobj, NULL);
leave:
return hresult;
}
/*
* CLightDTEngine::PasteDataObjectToRange (pdo, prg, cf, rps, pubdlr, dwFlags)
*
* @mfunc
* Inserts data from the data object pdo into the range prg. If the
* clipboard format cf is not NULL, that format is used; else the highest
* priority clipboard format is used. In either case, any text that
* already existed in the range is replaced. If pdo is NULL, the
* clipboard is used.
*
* @rdesc
* HRESULT
*
*/
HRESULT CLightDTEngine::PasteDataObjectToRange(
IDataObject * pdo, // @parm Data object to paste
CTxtRange * prg, // @parm Range into which to paste
CLIPFORMAT cf, // @parm ClipBoard format to paste
REPASTESPECIAL *rps, // @parm Special paste info
IUndoBuilder * publdr, // @parm Undo builder to receive antievents
DWORD dwFlags) // @parm DWORD packed flags
{
TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CLightDTEngine::PasteDataObjectToRange");
HGLOBAL hGlobal = NULL;
HRESULT hresult = DV_E_FORMATETC;
HGLOBAL hUnicode = NULL;
DWORD i;
STGMEDIUM medium = {0, NULL};
IDataObject *pdoSave = pdo;
FORMATETC * pfetc = g_rgFETC;
LPTSTR ptext = NULL;
LPRICHEDITOLECALLBACK const precall = _ped->GetRECallback();
BOOL fThawDisplay = FALSE;
BOOL bDBCString = FALSE; // use in pasting plain text
DWORD dwTemp;
if(!pdo) // No data object: use clipboard
{
hresult = pOleGetClipboard(&pdo);
if(FAILED(hresult))
{
// Ooops. No Ole clipboard support
// Need to use direct clipboard access
HWND howner = ::GetClipboardOwner();
HWND hwnd;
if (howner &&
_ped->TxGetWindow(&hwnd) == NOERROR &&
howner == hwnd
)
{
// We are cut/pasting within the same richedit instance
// Use our cached clipboard data object
pdo = _pdo;
if (!pdo) { // Som failure
_ped->Sound();
return hresult;
}
pdo->AddRef();
}
else
{
// Oh Oh We need to transfer from clipboard without data object
// Data must be coming from another window instance
if (_ped->TxGetWindow(&hwnd) == NOERROR &&
::OpenClipboard(hwnd)
)
{
DWORD dwFmt = iRtfUtf8; // Try for UTF8 RTF
_ped->_pdp->Freeze();
// GuyBark Jupiter:
// Don't check for rtf here if the control is in plain text mode.
// hGlobal is initialized to NULL above.
#ifdef PWD_JUPITER
if(_ped->IsRich())
{
#endif // PWD_JUPITER
hGlobal = ::GetClipboardData(cf_RTFUTF8);
if (hGlobal == NULL) // Wasn't there, so
{ // try for RTF
hGlobal = ::GetClipboardData(cf_RTF);
dwFmt = iRtfFETC;
}
#ifdef PWD_JUPITER
}
#endif // PWD_JUPITER
if (hGlobal == NULL) // Wasn't there either
{ // so try for plain
hGlobal = ::GetClipboardData(CF_UNICODETEXT);
dwFmt = iUnicodeFETC;
}
if (hGlobal)
{
ptext = (LPTSTR)GlobalLock(hGlobal);
hresult = HGlobalToRange(dwFmt, hGlobal, ptext, prg, publdr, bDBCString);
}
else // hGlobal == NULL Try for bitmaps
{
hGlobal = ::GetClipboardData(CF_DIB);
if (hGlobal) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?