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

📄 ldte.cpp

📁 Windows CE 6.0 Word Application 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
							hGlobal = DuplicateHGlobal(hGlobal);
							if (hGlobal) {
								hresult =  DIBToRange(hGlobal, prg, publdr);
							} else {
								hresult = E_OUTOFMEMORY;
							}
						}
					}
					_ped->_pdp->Thaw();
					::CloseClipboard();
				}
				if (FAILED(hresult)) {
					_ped->Sound();
				}
				return hresult;
			}
		}
	}

	// Paste an object uses the limit text calculation
	_fUseLimit = TRUE;

	if(cf == CF_TEXT)
	{
		FORMATETC fetc = {CF_UNICODETEXT, NULL, 0, -1, TYMED_NULL};
		  
		if(pdo->QueryGetData(&fetc) == S_OK)
			cf = CF_UNICODETEXT;
	}

	//Call QueryAcceptData unless caller has specified otherwise
	if (!(dwFlags & PDOR_NOQUERY) && precall)
	{
		CLIPFORMAT cfReq = cf;
		HGLOBAL hmeta = NULL;

		if (rps)
		{
			hmeta = (HGLOBAL)((rps->dwAspect == DVASPECT_ICON) ? rps->dwParam : NULL);
		}

		// Ask the callback if it likes the data object, and cfReq.

		hresult = precall->QueryAcceptData(
			pdo,
			&cfReq,
			(dwFlags & PDOR_DROP) ? RECO_DROP : RECO_PASTE,
			TRUE,
			hmeta);

		if(hresult == DATA_S_SAMEFORMATETC)
		{
			// Allow callback to return DATA_S_SAMEFORMATETC if it only
			// wants cf as passed in - we don't really care because
			// any non-zero CLIPFORMAT causes us to only accept that format.
			hresult = S_OK;
		}

		if(hresult == S_OK || hresult == E_NOTIMPL)
		{
			// Callback either liked it or didn't implement the method.
			// It may have changed the format while it was at it.
			// Treat a change of cf to zero as acceptance of the original.
			// In any event, we will try to handle it.

			// If a specific CLIPFORMAT was originally requested and the
			// callback changed it, don't accept it.
			if(cfReq && cf && (cf != cfReq))
			{
				hresult = DV_E_FORMATETC;
				goto Exit;
			}

			// If a specific CLIPFORMAT was originally requested and the
			// callback either left it alone or changed it to zero,
			// make sure we use the original.  If no CLIPFORMAT was
			// originally requested, make sure we use what came back
			// from the callback.
			if(!cf)
			{
				cf = cfReq;
			}
		}
		else
		{
			// Some success other than S_OK && DATA_S_SAMEFORMATETC.
			// The callback has handled the paste.  OR some error
			// was returned.
			goto Exit;
		}
	}

	if (_ped->TxGetReadOnly())			// Should check for range protection
	{
		hresult = E_ACCESSDENIED;
		goto Exit;
	}

	// At this point we freeze the display
	fThawDisplay = TRUE;
	_ped->_pdp->Freeze();

	if( publdr )
	{
		publdr->StopGroupTyping();
		publdr->SetNameID(UID_PASTE);
	}

	for( i = 0; i < CFETC; i++, pfetc++ )
	{
		// make sure the format is either 1.) a plain text format 
		// if we are in plain text mode or 2.) a rich text format
		// or 3.) matches the requested format.

		if( cf && cf != pfetc->cfFormat )
		{
			continue;
		}

		if( _ped->IsRich() || (g_rgDOI[i] & DOI_CANPASTEPLAIN) )
		{
			// make sure the format is available
			if( pdo->QueryGetData(pfetc) != NOERROR )
			{
				continue;
			}

			//If we have a format that uses an hGlobal get and lock it
			if(i == iRtfFETC || i == iRtfAsTextFETC || i == iAnsiFETC ||
			   i == iUnicodeFETC || i == iRtfNoObjs || i == iRtfUtf8)
			{
				if( pdo->GetData(pfetc, &medium) != NOERROR )
					continue;

                hGlobal = medium.hGlobal;
				ptext = (LPTSTR)GlobalLock(hGlobal);
				if( !ptext )
				{
					pReleaseStgMedium(&medium);

					hresult = E_OUTOFMEMORY;
					goto Exit;
				}

				// 1.0 COMPATBILITY HACK ALERT!  RichEdit 1.0 has a bit of
				// "error recovery" for parsing rtf files; if they aren't
				// valid rtf, it treats them as just plain text.
				// Unfortunately, apps like Exchange depend on this behavior,
				// i.e., they give RichEdit plain text data, but call it rich
				// text anyway.  Accordingly, we emulate 1.0 behavior here by
				// checking for an rtf signature.
				if( (i == iRtfFETC || i == iRtfNoObjs || i == iRtfUtf8) &&
					(GlobalSize(hGlobal) < cbRTFSig	||
					 memcmp(ptext, szRTFSig, cbRTFSig) != 0 ))
				{
					// uh-oh, data is not RTF, make it ANSI text
					i = iAnsiFETC;
				}
			}

			// Don't delete trail EOP in some cases
			prg->AdjustEndEOP(NONEWCHARS);

			switch(i)									
			{											
			case iRtfNoObjs:							
			case iRtfFETC:								
			case iRtfUtf8:						
                
				hresult = HGlobalToRange(i, hGlobal, ptext, prg, publdr, bDBCString);
				break;
	
			case iRtfAsTextFETC:
			case iAnsiFETC:								// ANSI plain text		

				hUnicode = TextHGlobalAtoW(hGlobal, &bDBCString);
				ptext	 = (LPTSTR)GlobalLock(hUnicode);
				if(!ptext)
				{
					hresult = E_OUTOFMEMORY;			// Unless out of RAM,
					break;								//  fall thru to
				}										//  Unicode case
														
			case iUnicodeFETC:							// Unicode plain text

				// Ok to pass in NULL for hglobal since argument won't be used
				hresult = HGlobalToRange(i, NULL, ptext, prg, publdr, bDBCString);
				if(hUnicode)							// For iAnsiFETC case
				{
					GlobalUnlock(hUnicode);
					GlobalFree(hUnicode);
				}			
				break;

			case iObtDesc:	 // Object Descriptor
				*(volatile DWORD*)&dwTemp = 0; // Work around compiler bug (#14740)
				continue;    // to search for a good format.
							 // the object descriptor hints will be used
				             // when the format is found.

			case iEmbObj:	 // Embedded Object
			case iEmbSrc:	 // Embed Source
			case iLnkSrc:	 // Link Source
			case iMfPict:	 // Metafile
			case iDIB:		 // DIB
			case iBitmap:	 // Bitmap
			case iFilename:	 // Filename
				hresult = CreateOleObjFromDataObj(pdo, prg, rps, i, publdr);
				break;

			//COMPATIBILITY ISSUE (v-richa) iTxtObj is needed by Exchange and 
			//as a flag for Wordpad.  iRichEdit doesn't seem to be needed by 
			//anyone but might consider implementing as a flag.
			case iRichEdit:	 // RichEdit
			case iTxtObj:	 // Text with Objects
				break;
			}

			//If we used the hGlobal unlock it and free it.
			if(hGlobal)
			{
				GlobalUnlock(hGlobal);
				pReleaseStgMedium(&medium);
			}
			
			//Break out of the for loop
			break;
		}
	}

Exit:

	if (fThawDisplay)
	{
		_ped->_pdp->Thaw();
	}

	if(!pdoSave)										// Release data object
		pdo->Release();									//  used for clipboard

	return hresult;						
}	

/*
 *	CLightDTEngine::GetDropTarget (ppDropTarget)
 *
 *	@mfunc
 *		creates an OLE drop target
 *
 *	@rdesc
 *		HRESULT
 *
 *	@devnote	The caller is responsible for AddRef'ing this object
 *				if appropriate.
 */
HRESULT CLightDTEngine::GetDropTarget(
	IDropTarget **ppDropTarget)		// @parm outparm for drop target
{
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CLightDTEngine::GetDropTarget");

	if( !_pdt )
	{
		_pdt = new CDropTarget(_ped);
		// the AddRef done by the constructor will be
		// undone by the destructor of this object
	}

	if( ppDropTarget )
	{
		*ppDropTarget = _pdt;
	}

	return _pdt ? NOERROR : E_OUTOFMEMORY;
}

/*
 *	CLightDTEngine::StartDrag (prg, publdr)
 *
 *	@mfunc
 *		starts the main drag drop loop
 *
 */	
HRESULT CLightDTEngine::StartDrag(
	CTxtSelection *psel,		// @parm Selection to drag from
	IUndoBuilder *publdr)		// @parm undo builder to receive antievents
{
#ifndef PEGASUS
	TRACEBEGIN(TRCSUBSYSDTE, TRCSCOPEINTERN, "CLightDTEngine::StartDrag");

	LONG			cch, cch1;
	LONG			cp1, cpMin, cpMost;
	DWORD			dwEffect = 0;
	HRESULT			hr;
	IDataObject *	pdo = NULL;
	IDropSource *	pds;
	IRichEditOleCallback * precall = _ped->GetRECallback();

	// If we're doing drag drop's, we should have our own drop target
	// It's possible that _pdt will be NULL at this point--some clients
	// will delay instantiation of our drop target until a drop target
	// in the parent window decides that ours is needed.  However, since
	// we need it just to initiate drag drop, go ahead and create one
	// here.

	if( _pdt == NULL )
	{
		if( (hr = GetDropTarget(NULL)) != NOERROR )
		{
			return hr;
		}
	}

	psel->CheckTableSelection();

	if(precall)
	{
		CHARRANGE chrg;

		// give the callback a chance to give us its own IDataObject
		psel->GetRange(chrg.cpMin, chrg.cpMost);
		hr = precall->GetClipboardData(&chrg, RECO_COPY, &pdo);
	}
	else
	{
		// we need to build our own data object.
		hr = S_FALSE;
	}

	// If we didn't get an IDataObject from the callback, build our own
	if(hr != NOERROR || pdo == NULL)
	{										// Don't include trailing EOP
		psel->AdjustEndEOP(NONEWCHARS);		//  in some selection cases
		hr = RangeToDataObject(psel, SF_TEXT | SF_RTF, &pdo);
		if(hr != NOERROR)
			return hr;
	}

	cch = psel->GetRange(cpMin, cpMost);	// NB: prg is the selection
	cp1 = psel->GetCp();					// Save active end and signed
	cch1 = psel->GetCch();					//  length for Undo antievent
	CTxtRange rg(_ped, cpMost, cch);		// Use range copy to float over
											// mods made to backing store
	// The floating range that we just created on the stack needs to
	// think that it's protected, so it won't change size.
	rg.SetDragProtection(TRUE);

	pds = new CDropSource();
	if( pds == NULL )
	{
		pdo->Release();
		return E_OUTOFMEMORY;
	}

	// cache some info with our own drop target
	_pdt->SetDragInfo(publdr, cpMin, cpMost);


	// Set allowable effects
	dwEffect = DROPEFFECT_COPY;
	if (!_ped->TxGetReadOnly())
		dwEffect |= DROPEFFECT_MOVE;
	
	// Let the client decide what it wants.
	if (precall)
	{
		hr = precall->GetDragDropEffect(TRUE, 0, &dwEffect);
	}

	if (!FAILED(hr) || hr == E_NOTIMPL)
	{
		// start drag-drop operation
		hr = pDoDragDrop(pdo, pds, dwEffect, &dwEffect);
	}

	// clear drop target
	_pdt->SetDragInfo(NULL, -1, -1);

	// handle 'move' operations	
	if( hr == DRAGDROP_S_DROP && (dwEffect & DROPEFFECT_MOVE) )
	{
		// we're going to delete the dragged range, so turn off protection.

		rg.SetDragProtection(FALSE);

		if( publdr )
		{
			LONG cpNext, cchNext;

			if(_ped->GetCallMgr()->GetChangeEvent() )
			{
				cpNext = cchNext = -1;
			}
			else
			{
				cpNext = rg.GetCpMin();
				cchNext = 0;
			}

			HandleSelectionAEInfo(_ped, publdr, cp1, cch1, cpNext, cchNext,
								  SELAE_FORCEREPLACE);
		}
		
		// delete the data that was moved.  The selection will float
		// to the new correct location.
		rg.ReplaceRange(0, NULL, publdr, SELRR_IGNORE);

		// The update that happens implicitly by the update of the range may
		// have the effect of scrolling the window. This in turn may have the
		// effect in the drag drop case of scrolling non-inverted text into
		// the place where the selection was. The logic in the selection 
		// assumes that the selection is inverted and so reinverts it to turn
		// off the selection. Of course, it is obvious what happens in the
		// case where non-inverted text is scrolled into the selection area.
		// To simplify the processing here, we just say the whole window is
		// invalid so we are guaranteed to get the right painting for the
		// selection.
		// FUTURE: (ricksa) This solution does have the disadvantage of causing
		// a flash during drag and drop. We probably want to come back and
		// investigate a better way to update the screen.
		_ped->TxInvalidateRect(NULL, FALSE);

		// Display is updated via notification from the range

		// Update the caret
		psel->Update(TRUE);
	}
	else if( hr == DRAGDROP_S_DROP && _ped->GetCallMgr()->GetChangeEvent() &&
		(dwEffect & DROPEFFECT_COPY) && publdr)
	{
		// if we copied to ourselves, we want to restore the selection to
		// the original drag origin on undo
		HandleSelectionAEInfo(_ped, publdr, cp1, cch1, -1, -1, 
				SELAE_FORCEREPLACE);
	}


	if( SUCCEEDED(hr) )
	{	
		hr = NOERROR;
	}

	pdo->Release();
	pds->Release();

	// we do this last since we may have re-used some 'paste' code which
	// will stomp the undo name to be UID_PASTE.
	if( publdr )
	{
		publdr->SetNameID(UID_DRAGDROP);
	}

	if( (_ped->GetEventMask() & ENM_DRAGDROPDONE) )
	{
		NMHDR	hdr;

		ZeroMemory(&hdr, sizeof(NMHDR));
		_ped->TxNotify(EN_DRAGDROPDONE, &hdr);
	}

	return hr;
#else
	return 0;
#endif
}

/*
 *	CLightDTEngine::LoadFromEs (prg, lStreamFormat, pes, fTestLimit, publdr)
 *
 *	@mfunc
 *		Load data from the stream pes into the range prg according to the
 *		format lStreamFormat
 *
 *	@rdesc
 *		LONG -- count of characters read
 */
LONG CLightDTEngine::LoadFromEs(
	CTxtRange *	prg,			// @parm range to load into

⌨️ 快捷键说明

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