Windowless RichEdit 功能补充

1:拖拽文字的具体实现方法:

(1)首先在初始化函数中加入注册拖拽处理:

    if( m_pTwh ) {
        m_pTwh->SetTransparent(TRUE);
		if (IsReadOnly())
		{
			SetAutoURLDetect(true);
			DWORD dwMask = GetEventMask();
			dwMask |= ENM_LINK;
			SetEventMask(dwMask);
		}
		else if ( IsEnabled() )
		{

			LPDROPTARGET lpDropTarget = NULL;
			m_pTwh->GetTextServices()->TxGetDropTarget(&lpDropTarget);
			if ( S_OK != ::RegisterDragDrop(GetManager()->GetPaintWindow(),lpDropTarget)) //注册拖拽响应
			{
				DWORD dwError = GetLastError();
				CStdString strTemp;
				strTemp.Format(TEXT("注册失败!:错误代码:%d"), dwError);
				//  			MessageBox(NULL,strTemp, NULL, MB_OK);
				OutputDebugString(strTemp);
			}
			lpDropTarget->Release();
			DWORD dwMask = GetEventMask();
			dwMask |= ENM_DROPFILES;
			SetEventMask(dwMask);
		}
        LRESULT lResult;
        m_pTwh->GetTextServices()->TxSendMessage(EM_SETLANGOPTIONS, 0, 0, &lResult);
        m_pTwh->OnTxInPlaceActivate(NULL);
        m_pManager->AddMessageFilter(this);
    }


(2) 然后在:

GetDragDropEffect方法中加入以下代码:

	*pdwEffect = TRUE;
	if (!g_bDrop)
	{
		if (!m_pOwner->IsReadOnly())
		{
			m_pOwner->GetSel(m_pOwner->m_dropBegin,m_pOwner->m_dropEnd);
			g_pDropWindow = m_pOwner;
			g_bDrop  = true;
		}
	}
	return E_NOTIMPL;


(3)最后在:

QueryAcceptData 方法中 加入以下代码处理拖拽和粘贴文本信息

if (!fReally)
	{
		return S_OK;
	}
	switch(reco)  
	{  
	case RECO_DRAG:
		{
			break;
		}
	case RECO_PASTE: 
		{
			HDROP       hdrop;
			STGMEDIUM stgmed; 
			ZeroMemory(&stgmed, sizeof(STGMEDIUM));
			FORMATETC tFormat={ 0xC007/*FileNameW*/, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };  


			HRESULT hr = lpdataobj->GetData(&tFormat, &stgmed);
			if (SUCCEEDED(hr))
 			{
 				tFormat.cfFormat = CF_HDROP;
 
 				hr = lpdataobj->GetData(&tFormat, &stgmed);
 				if (SUCCEEDED(hr))
 				{
 					hdrop = reinterpret_cast(GlobalLock(stgmed.hGlobal));
 					::PostMessage(m_pOwner->GetManager()->GetPaintWindow(),TM_DROPFILE_MSG,(WPARAM)hdrop,(LPARAM)bIsCopyFile);
 					GlobalUnlock(stgmed.hGlobal);
 					return E_ABORT;
 				}
 			}
			bIsCopyFile = true;


		}
	case RECO_DROP: 
		{

			//拖拽文件操作
			HDROP       hdrop;
			TCHAR       szNextFile [MAX_PATH];
			LVFINDINFO  rlvFind = { LVFI_STRING, szNextFile };


			STGMEDIUM stgmed; 
			ZeroMemory(&stgmed, sizeof(STGMEDIUM));
		
			//处理取消缩进
			::PostMessage(m_pOwner->GetManager()->GetPaintWindow(), MSG_PASTE, 0, 0);  //这个是自定义消息 处理粘贴过来的所有格式

			bool bIsDrop = false;
			if (g_pDropWindow != NULL)
			{		//模拟拖拽行为清除上次拖拽 的文字信息
				tryDebug0(TEXT("开始拖拽行为"));
				if ( g_pDropWindow->m_dropBegin != -1 && g_pDropWindow->m_dropEnd != -1 )
				{
					CRichEditUI::IRichEditOleExCallback::g_bDrop = false;
					bIsDrop = true;
					long  dropPos;
					POINT point;
					GetCursorPos(&point);
					ScreenToClient(m_pOwner->GetManager()->GetPaintWindow(), &point);
					dropPos = g_pDropWindow->CharFromPos(point);
					g_pDropWindow->SetSel(g_pDropWindow->m_dropBegin , g_pDropWindow->m_dropEnd);
					if (g_pDropWindow->m_dropBegin < dropPos)
					{
						dropPos  = dropPos - (g_pDropWindow->m_dropEnd - g_pDropWindow->m_dropBegin);
					}
					if ( !g_pDropWindow->IsReadOnly())
					{
						tryDebug0("开始清除拖拽信息");
						g_pDropWindow->ReplaceSel(TEXT(""), false);
					}
					g_pDropWindow->m_dropEnd = -1;
					g_pDropWindow->m_dropBegin = -1;
					g_pDropWindow->SetSel(dropPos, dropPos);
					g_pDropWindow = NULL;
					
				}
				tryDebug0( "拖拽行为结束" );
			}
			g_bDrop = false;
			bool bFlag  = false;
			if (bIsDrop)
			{
				POINT pt;
				RECT rect;
				GetCursorPos(&pt);
				ScreenToClient(m_pOwner->GetManager()->GetPaintWindow(), &pt);
				rect = m_pOwner->GetPos();
				if( ::PtInRect(&rect, pt) )
				{
					bFlag = m_pOwner->DoClipboard(); //处理粘贴板函数
				}
				else
					return E_NOINTERFACE;
			}
			else
			{
				bFlag = m_pOwner->DoClipboard();
			}
			if (bFlag)
			{
				return E_NOINTERFACE;
			}
			else
			{
				return S_OK;
			}
		} 

	default:  
		break;  
	}  
	return E_NOTIMPL;


2:设置输入法显示框位置:

   在KeyDown 消息中加入以下代码即可

if( uMsg == WM_KEYDOWN )
 	{
		if (!IsReadOnly())
		{
			long nSelStart = 0, nSelEnd = 0;  
			this->GetSel( nSelStart, nSelEnd );
			CPoint pntCursor = this->PosFromChar( nSelEnd );


			if ( pntCursor.x == -1)
			{
				nSelEnd -=1;  
				if ( nSelEnd < 0 )
				{
					nSelEnd = 0;
				}
				pntCursor = this->PosFromChar( nSelEnd );
			}
			RECT rect = GetPos();
			HIMC hImc = ImmGetContext(GetManager()->GetPaintWindow());
			COMPOSITIONFORM form;
			form.dwStyle = CFS_RECT;
			form.ptCurrentPos = CPoint(pntCursor.x,rect.top);
			form.rcArea = CRect(pntCursor.x,rect.top,pntCursor.x+300,rect.top + 100 );
			ImmSetCompositionWindow(hImc,&form);
		}
 	}


3.复制,粘贴图片,表情:

 (1) 在GetClipboardData中加入以下代码:

if (reco == RECO_CUT || reco == RECO_DRAG || reco == RECO_DROP)
 	{
 		m_pOwner->DoWriteClipData(true);
		OutputDebugString(TEXT("响应拖拽!\n"));
 	}
 	else
 	{
 		m_pOwner->DoWriteClipData();
 	}


	m_pOwner->Invalidate();
	return S_OK;


(2)粘贴板操作:

bool CRichEditUI::DoWriteClipData(bool bIsCut)
{
	if( OpenClipboard(GetManager()->GetPaintWindow()) )
	{
		EmptyClipboard();
		CStdString data,strSelText;
		std::list listOfImg;  //图片信息格式
		long lBegin, lEnd;
		GetSel(lBegin, lEnd);

		GetSelClipData(strSelText, listOfImg);
		
		CStdString strText = GetSelText();
		strSelText = strText;
		tryDebug("选中的 文字信息为:%s",strText.GetData());
		GetClipWord(strSelText,listOfImg, data);
		if (bIsCut)
		{
			ReplaceSel(_T(""), false);
		}
		HGLOBAL clipbuffer;
		clipbuffer = GlobalAlloc(GHND | GMEM_SHARE, (data.GetLength()+1)*sizeof(TCHAR));
		char * buffer = (char*)GlobalLock(clipbuffer);
		strcpy(buffer, data.GetData());
		GlobalUnlock(clipbuffer);
		SetClipboardData(m_uOwnOleClipboardFormat,clipbuffer);		//自定义的粘贴板格式

		
		if ( ( strText.GetLength() == 1 ) && ( listOfImg.size() == 1 ) )
		{
			WriteHBitmapClip(listOfImg);		//粘贴HBITMAP的格式
			ClearClipList(listOfImg);

			CloseClipboard();
			return TRUE; 
		}
		if( listOfImg.size() > 0)
		{
			WriteHTMLClip(strSelText,listOfImg);	//粘贴HTML格式 从而支持 粘贴到 word QQ (图文混编格式)
		}
		

		CString str = strSelText;
		char* szBuff = new char[strSelText.GetLength() + 1];
		ZeroMemory(szBuff, strSelText.GetLength()  + 1);
		strcpy( szBuff, strSelText);
		if (strSelText.IsEmpty())
		{
			OutputDebugString("The Text IS NULL\n");
		}
		OutputDebugString("Select Text :");
		OutputDebugString(strSelText);
		OutputDebugString("\n");
		//ConvertUtf8ToGBK( str);
		HGLOBAL hClip;
		TCHAR * TextBuffer = NULL;
		hClip = GlobalAlloc( GMEM_MOVEABLE, str.GetLength() + 1 );
		TextBuffer = (TCHAR*)GlobalLock(hClip);
		_tcscpy( TextBuffer, szBuff );
		GlobalUnlock(hClip);
		//SetClipboardData(CF_UNICODETEXT,hClip);

		SetClipboardData(CF_TEXT, hClip);    //纯text文字

		ClearClipList(listOfImg);

		CloseClipboard();
		delete[] szBuff;

	}
	return TRUE;
}
4:未完待续

你可能感兴趣的:(Windowless RichEdit 功能补充)