Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: MFC Drag drop
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 22-Jan-13 18:30pm
Comments
Sergey Alexandrovich Kryukov at 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 at 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 at 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 at 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 at 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
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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);
    }
}
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

@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
  Permalink  

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

  Print Answers RSS
0 OriginalGriff 5,130
1 DamithSL 4,237
2 Maciej Los 3,700
3 Kornfeld Eliyahu Peter 3,470
4 Sergey Alexandrovich Kryukov 2,846


Advertise | Privacy | Mobile
Web01 | 2.8.141216.1 | Last Updated 24 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100