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<HDROP>(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<PIMG_CLIP_MSG> 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:未完待续