MFC:在文本框之间拖放时丢失了一部分文本 [英] MFC: Lost a part of text in Dragging and Drop between Text boxes
问题描述
我想在VS2010上用MFC做一个Drag_n_Drop的演示。
但我在演示中找不到丢失文字的原因。
请在这里查看名为''COleDragnDrop'的项目,帮助我: http://www.mediafire.com/?nx3op4s6ofe1znp [ ^ ]
此处发布指向源的链接并不常见。最好只发布相关部分。在您的情况下,这将是准备拖动文本并在删除时获取它的代码。但是,我查看了你的文件:
- [更新] :你忘了从
InitInstance()
中调用AfxOleInit()
。- 你正在路过文本字符串没有终止
NULL
字符。- 您正在使用
GlobalSize()
来确定下降侧的字符串长度。这可能会导致意外结果,因为分配的全局内存大小可能会大于请求的大小。- 您正在使用
CSharedFile
对象来创建全局内存对象和CMemFile
对象访问drop对象。虽然这没有错,但没有必要。- 可选:执行拖动时,不要在
CDragEdit :: OnLButtonDown()
中调用默认处理程序(以下所有鼠标事件都由OLE处理,因此控件不会收到按钮消息)- 可选:
CDragEdit :: OnLButtonDown()
需要更多检查:仅当控件具有焦点并单击选定文本时才开始拖动。
这是一个简短的代码片段,显示了如何完成拖放操作:
DROPEFFECT DragText(LPCTSTR lpszText,DROPEFFECT dwEffect)
{
// 分配全局内存和复制文本
size_t nSize =(_ tcslen(lpszText)+ 1 )* sizeof (TCHAR);
HGLOBAL hGlobal = :: GlobalAlloc(GMEM_MOVEABLE,static_cast< SIZE_T>(nSize));
LPTSTR lpDst = static_cast< LPTSTR>(:: GlobalLock(hGlobal));
:: CopyMemory(lpDst,lpszText,nSize);
:: GlobalUnlock(hGlobal);
// 使用DragDrop,我们可以在堆栈上分配COleDataSource。
< span class =code-comment> // 使用SetClipboard()时,必须在堆上分配它。
COleDataSource Data;
#ifdef _UNICODE
Data.CacheGlobalData(CF_UNICODETEXT,hGlobal);
#else
Data.CacheGlobalData(CF_TEXT,hGlobal);
#endif
return Data.DoDragDrop(dwEffect);
}
// 将LPCSTR分配到CStringW或LPCWSTR时CStringA,
// 执行ANSI / Unicode转换。
void GetDropText(CString& str,COleDataObject * pDataObject)
{
str = _T( );
if (pDataObject-> IsDataAvailable(CF_UNICODETEXT))
{
HGLOBAL hGlobal = pDataObject-> GetGlobalData(CF_UNICODETEXT);
LPCWSTR lpSrc = static_cast< LPCWSTR>(:: GlobalLock(hGlobal));
str = lpSrc;
:: GlobalUnlock(hGlobal);
}
else if (pDataObject-> IsDataAvailable(CF_TEXT))
{
HGLOBAL hGlobal = pDataObject-> GetGlobalData(CF_TEXT);
LPCSTR lpSrc = static_cast< LPCSTR>(:: GlobalLock(hGlobal));
str = lpSrc;
:: GlobalUnlock(hGlobal);
}
}
@Jochen Arndt:因为我使用了Dialog类型,所以我把AfxOleInit()in
OnInitDialog()
我根据这一点调试并解决了我的问题: ''Quote:您正在传递文本字符串而不终止NULL字符。
我刚从CString对象使用了char * buffer而不是GetBuffer。
Ex:COleDataSource pSource;
CSharedFile sf(GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT);
char pBuf [] =测试1 ...... 2 ......;
sf.Write(pBuf,strlen(pBuf));
感谢您的帮助,Jochen和S.Alexandrovich
Hi,
I am trying to make a demo of Drag_n_Drop with MFC on VS2010.
But I could not find out the reason for losing text in my demo.
Please help me by taking a look on my project named ''COleDragnDrop'' here: http://www.mediafire.com/?nx3op4s6ofe1znp[^]
It is uncommon here to post links to sources. It is better to post only relevant parts. In your case this would be the code to prepare the drag text and get it upon dropping. However, I had a look on your files:
- [UPDATE]: You forgot to call
AfxOleInit()
from withinInitInstance()
.- You are passing the text strings without terminating
NULL
character.- You are using
GlobalSize()
to determine the string length on the drop side. That may lead to unexpected results because the allocated global memory size may be larger than the requested size.- You are using
CSharedFile
objects to create global memory objects andCMemFile
objects to acccess drop objects. While this is not wrong it is not necessary.- Optional: Don''t call the default handler in
CDragEdit::OnLButtonDown()
when performing drag (all following mouse events are handled by OLE so that the control will not receive a button up message)- Optional:
CDragEdit::OnLButtonDown()
needs some more checks: Start drag only when control has focus and clicked on selected text.
Here is a short code snippet showing how drag and drop can be done:
DROPEFFECT DragText(LPCTSTR lpszText, DROPEFFECT dwEffect) { // Allocate global memory and copy text size_t nSize = (_tcslen(lpszText) + 1) * sizeof(TCHAR); HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, static_cast<SIZE_T>(nSize)); LPTSTR lpDst = static_cast<LPTSTR>(::GlobalLock(hGlobal)); ::CopyMemory(lpDst, lpszText, nSize); ::GlobalUnlock(hGlobal); // With DragDrop, we may allocate COleDataSource on the stack. // When using SetClipboard(), it must be allocated on the heap. COleDataSource Data; #ifdef _UNICODE Data.CacheGlobalData(CF_UNICODETEXT, hGlobal); #else Data.CacheGlobalData(CF_TEXT, hGlobal); #endif return Data.DoDragDrop(dwEffect); } // When assingning a LPCSTR to a CStringW or a LPCWSTR to a CStringA, // ANSI / Unicode conversion is performed. void GetDropText(CString& str, COleDataObject* pDataObject) { str = _T(""); if (pDataObject->IsDataAvailable(CF_UNICODETEXT)) { HGLOBAL hGlobal = pDataObject->GetGlobalData(CF_UNICODETEXT); LPCWSTR lpSrc = static_cast<LPCWSTR>(::GlobalLock(hGlobal)); str = lpSrc; ::GlobalUnlock(hGlobal); } else if (pDataObject->IsDataAvailable(CF_TEXT)) { HGLOBAL hGlobal = pDataObject->GetGlobalData(CF_TEXT); LPCSTR lpSrc = static_cast<LPCSTR>(::GlobalLock(hGlobal)); str = lpSrc; ::GlobalUnlock(hGlobal); } }
@Jochen Arndt: Because I used Dialog type, I putAfxOleInit()in
OnInitDialog()
I debugged and solved my problem based on this point: ''Quote:You are passing the text strings without terminating NULL character.
I have just used char *buffer instead of GetBuffer from a CString object.
Ex:COleDataSource pSource; CSharedFile sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT); char pBuf[] = "Testing 1... 2... "; sf.Write(pBuf, strlen(pBuf));
Thanks for your helps, Jochen and S.Alexandrovich
这篇关于MFC:在文本框之间拖放时丢失了一部分文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!