Solved

DRAGGING ICONS

Posted on 1998-12-15
4
308 Views
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.
0
Comment
Question by:rangers99
  • 2
  • 2
4 Comments
 

Author Comment

by:rangers99
ID: 1180251
Adjusted points to 400
0
 
LVL 1

Accepted Solution

by:
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_dropTarget.Register(this);
   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);
     src.DoDragDrop();
     ::GlobalFree(stgText.hGlobal);
     ::GlobalFree(stgRptItem.hGlobal);

     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;
             rect.top = point.y;
             CString text = pRec->text;
             rect.right = rect.left + text.GetLength()*m_textDims.cx + 2;
             rect.bottom = rect.top + m_textDims.cy + 2;
             if (dropEffect == DROPEFFECT_MOVE)
               pRec->Move(point, this);
             else
               {
                 item  = new CMyItem(point, pRec->item, this);
                 // add item to document list
                 GetDocument()->m_list.AddTail(item);
                 GetDocument()->SetModifiedFlag();
               }
             bResult = TRUE;
             ::GlobalUnlock(stg.hGlobal);
          }
     }
   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
             GetDocument()->m_list.AddTail(item);
             GetDocument()->SetModifiedFlag();
             bResult = TRUE;
             ::GlobalUnlock(stg.hGlobal);
          }
     }
   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!
0
 
LVL 1

Expert Comment

by:jim_pettinato
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).
0
 

Author Comment

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

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
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 clear a vector as well as how to detect empty vectors in C++.

746 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

9 Experts available now in Live!

Get 1:1 Help Now