MFC:在文本框之间拖放时丢失了一部分文本 [英] MFC: Lost a part of text in Dragging and Drop between Text boxes

查看:79
本文介绍了MFC:在文本框之间拖放时丢失了一部分文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我想在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 within InitInstance().
  • 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 and CMemFile 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 put

AfxOleInit()

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆