Solved

DRAGGING ICONS

Posted on 1998-12-15
4
332 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

691 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