Posted on 1998-12-15
Last Modified: 2010-04-02
My application involves dragging icons from a property page in a modeless property sheet dialogue onto a view window. I am having trouble implementing this - currently I can only drag the icon around the original property page (use begindrag, mousemove and lbuttonup functions) and have problems when I try to drag it out this window.
Can anyone outline a procedure for this - ie dragging an icon between different windows.
Question by:rangers99
  • 2
  • 2

Author Comment

ID: 1180251
Adjusted points to 400

Accepted Solution

jim_pettinato earned 400 total points
ID: 1180252
My CView derived code has been drag/drop enabled for either text or a custom object derived from CButton. It should not be to difficult to modify the custom object handling to handle a bitmap or icon. All I am really doing is passing a pointer to the original object, which I use to make a new copy and duplicate at the drop location.

The trick is twofold... define a new clipboard format type and
handle objects of that type dragged into your view.

Add the following members to your CView derived class:

   COleDropTarget m_dropTarget;
   UINT m_nClipFormat;

In your target view's OnCreate member, define a new clipboard format like this: (my view is derived from CScrollView)

int CMyView::OnCreate(LPCREATESTRUCT *lpCreateStruct)
   if (CScrollView::OnCreate(lpCreateStruct) == -1)
      return -1;

   m_nClipFormat = RegisterClipboardFormat("MyItemEntry");
   ASSERT((m_nClipFormat >= 0xC000) && (m_nClipFormat <= 0xFFFF));
   return 0;

Now in the dragged object's OnLButtonDown method, do the following:

void CMyItem::OnLButtonDown(UINT nFlags, CPoint point)
     STGMEDIUM stgMyItem;
     CMyItem *rec = this;
     stgRptItem.tymed = TYMED_HGLOBAL;
     stgRptItem.hGlobal = ::GlobalAlloc(GMEM_SHARE, sizeof(rec));
     memcpy(stgRptItem.hGlobal, &rec, sizeof(rec));

     COleDataSource src;
     src.CacheData((BYTE)m_nClipFormat, &stgRptItem);

     CButton::OnLButtonDown(nFlags, point);

Then, in the target view, override the following 3 functions:

DROPEFFECT CMyView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
  // don't need any special initial handling for my object types
   return OnDragOver(pDataObject, dwKeyState, point);

DROPEFFECT CMyView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
       if (ChildWindowFromPoint(point) != this)  // is mouse  over another child item?
          return DROPEFFECT_NONE;  

       if ((pDataObject->IsDataAvailable(CF_TEXT))
       ||  (pDataObject->IsDataAvailable((BYTE)m_nClipFormat)) )
          // we allow copying or moving of text or custom format, depending on the state
          if (dwKeyState & MK_CONTROL) {
             return DROPEFFECT_COPY;
          else {
             return DROPEFFECT_MOVE;

       // unknown format: reject
       return DROPEFFECT_NONE;

BOOL CReportView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
   ReportItem *item;
   BOOL bResult = FALSE;

   if (pDataObject->IsDataAvailable((BYTE)m_nClipFormat))
        STGMEDIUM stg;
        if (pDataObject->GetData((BYTE)m_nClipFormat, &stg))
             CMyItem* pRec=(CMyItem*)::GlobalLock(stg.hGlobal);
             RECT rect;
             rect.left = point.x;
    = point.y;
             CString text = pRec->text;
             rect.right = rect.left + text.GetLength()* + 2;
             rect.bottom = + + 2;
             if (dropEffect == DROPEFFECT_MOVE)
               pRec->Move(point, this);
                 item  = new CMyItem(point, pRec->item, this);
                 // add item to document list
             bResult = TRUE;
   else if (pDataObject->IsDataAvailable(CF_TEXT))
        STGMEDIUM stg;
        if (pDataObject->GetData(CF_TEXT, &stg))
             char* pszText = (char*) ::GlobalLock(stg.hGlobal);
             item = new MyObject(point,
                                    pszText, this);
             item->type = ReportItem::USERTEXT;
             // Add the Object to the document
             bResult = TRUE;
   return bResult;

You will notice that I added constructors and a Move method to
my CButton derived CMyItem class that simplified moving/ copying objects to a drop location. This makes the view's code quite a bit more straightforward.

Good Luck!

Expert Comment

ID: 1180253
I left out one thing: the m_nClipFormat variable in the drop targed CView must be available to the source item (in my case, the CButton-derived CMyItem). I did this by creating a public static m_nClipFormat member in the CMyItem class and assigning it once the CView-derived class has the format registered. This variable appears in the CMyItem::OnLButtonDown, but I forgot to show you that I added this member to the CMyItem class and assigned it (I think I assigned it in the view's OnInitialUpdate() method, I don't know why, I could have done it in the OnCreate as soon as I had the format registered).

Author Comment

ID: 1180254
Cheers. I should be able to modify this to work with icons.

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Better understanding on C++ Class serialization and formats 9 65
Header of docx file 17 102
trigs fail! I thought I knew how to do trignometry 3 65
max float value 3 39
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

815 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now