Click here to Skip to main content
15,881,757 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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[^]
Posted
Comments
Sergey Alexandrovich Kryukov 22-Jan-13 23:36pm    
Please remove all executables from your RAR file and post again. Doing so is considered very dangerous. The .suo files are also do not belong to the source code.

However, many won't look at your project anyway, will prefer to wait for your explanations...
—SA
Member 9743678 23-Jan-13 0:05am    
I would like to put whole project to speed up investigations from other.

Sorry for any inconveniences,
Sergey Alexandrovich Kryukov 23-Jan-13 0:17am    
To me, it's fine, some other member may argue against it. So, not sure it can help you, let's see. Your case may need some time to investigate, that's the problem, even if the bug is really trivial...
Did you execute it all under debugger? You know better where you handle what.

Also, I would advise you to describe steps to reproduce. I found it, but on first attempt (clicked on one button), the application "crashed". Might be another problem.

—SA
Member 9743678 23-Jan-13 1:20am    
Really? There are 3 buttons, but I did not attach any events for them.

Waiting for your deep investigations,

--
TA
Sergey Alexandrovich Kryukov 22-Jan-13 23:42pm    
No, it does not behave as you described. Sometimes, it "remembers" previously entered text. Think about it. The text you drop is not the one of the source.
—SA

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:
C++
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);
    }
}
 
Share this answer
 
v2
@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
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900