Solved

Drag and Drop Image

Posted on 2002-03-06
8
534 Views
Last Modified: 2013-11-20
I've implemented a drag and drop in my application.  I use a standard cursor to show that you are in a drag - drop mode.  

But I would like to display a image of the items being dragged,  simalar to how Explorer does it.  Can someone point me in the correct direction.

Thanks
Scott
0
Comment
Question by:sabrog
  • 4
  • 3
8 Comments
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 6846557
get the code from MSDN

http://www.microsoft.com/msj/0898/wicked0898.htm

GOOD LUCK
0
 

Author Comment

by:sabrog
ID: 6847940
that's not quite what i need.  The problem is creating the drag image.  They use the function CreateDragImage, which is a function of cTreeCtrl.  

I'm dragging from a custom grid control so i need to create dynamic Bitmap to add to the CImageList from a specified rect of the screen.

Scott
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6854316
Is it possible that the 'custom grid control' is derived from CListView?  If so, you can send it the LVM_CREATEDRAGIMAGE message.

Otherwise, you will need to create a bitmap of the text that you want to drag.  Then create a persistent  CImageList that contains just that one bitmap.  Then call
 
      m_cImgListDrag.SetDragCursorImage(0,...)

Then continue with the normal dragging operations.
      m_cImgListDrag.BeginDrag(...)
      m_cImgListDrag.DragEnter(...)
...etc.

Do you need help creating the bitmap?  Raise the points to 200 and I'll work out the details for you.  I'll provide a function that accepts a string of text and creates a bitmap that contains that text.

-- Dan
0
 

Author Comment

by:sabrog
ID: 6854391
Yes creating the bitmap is what i need help with. I understand how to use the CImageList and move the image around, getting that image is what I'm not sure on

The dragging is for moving columns around, not items in the list box.  For the bitmap i want to show the header cell and 4-5 rows of text.  Can we create a bitmap of a specified rect on the screen, to include the look of the header and not just text?

unfortunately the list box is not derived from CListView, it's totally custom.

Thanks
Scott
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 49

Expert Comment

by:DanRollins
ID: 6855187
Just so that I understand it...

The user has clicked on a header 'button' at the top of the grid and is now dragging that header around the screen.  You want to show a shadowy image that looks kind of like the image of the header button and the data in the several visible columns that are directly below that header.

So you should be satisfied with a drag image that looks like a particular rectangle on the screen.  

It will be your responsibility to identify the desired rectangle in global screen coordinates.  I will capture the contents of that rectangle and dither it so that it looks kind of shadowy.  I'll put the result into a CImageList so that it will work with the normal drag-and-drop handling.  You will implement all of the drag-and-drop code.  You will award me an A for my efforts and not throw in a bunch of unrelated post-solution questions.

Are we agreed?
0
 

Author Comment

by:sabrog
ID: 6855364
Sounds good to me!  Can the white area behind the text be transparent?

Scott
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 200 total points
ID: 6855492
Here ya go!

//---------------------------------
// pass in a window and a rect (in window coords) and a bitmap
// returns with the bitmap containing the image from that part of that window
//
void CreateBitmapFromWindowRect( CWnd* pWnd, CRect* prc, CBitmap* pcBmp )
{
     CWindowDC     dc( pWnd );
     CDC           memDC;
     CRect          rect;

     memDC.CreateCompatibleDC( &dc );
     pWnd->GetWindowRect(rect);

     pcBmp->CreateCompatibleBitmap( &dc, rect.Width(),rect.Height() );

     CBitmap* pOldBitmap = memDC.SelectObject( pcBmp );
     memDC.BitBlt( 0,0, prc->Width(),prc->Height(), &dc, prc->left, prc->top, SRCCOPY);

     memDC.SelectObject(pOldBitmap);
}

//--------------------------------------------
// example usage.  You will need to fire on a different
// event (i.e., start of drag of your custom header control)
// and do other customization for your needs

void CMyDlg::OnWhatever( ... whatever ... )
{
     CHeaderCtrl* pHC= m_ctlList.GetHeaderCtrl();

     int nClmNum= 1;   // you must set this based upon the clm that is being dragged
     int nHigh=   60;  // set this to the height of the grid control    

     //---------- here I calculate the location of the
     //---------- rectangle to use as the drag image
     CRect rcHdr;  
     pHC->GetItemRect( nClmNum, &rcHdr );

     CBitmap cBmp;
     CRect rcBmp;

     rcBmp.top= 0;
     rcBmp.left=  rcHdr.left;
     rcBmp.right= rcHdr.right + 2; // cosmetic tweak
     rcBmp.bottom= nHigh;    
     
     CreateBitmapFromWindowRect( &m_ctlList, &rcBmp, &cBmp );

     //------------------- delete the old drag image and create the new
     if( m_pImgListDrag ) {
          delete m_pImgListDrag;
     }
     m_pImgListDrag= new CImageList();

     m_pImgListDrag->Create( rcBmp.Width(), rcBmp.Height(), ILC_MASK, 1, 1);
     m_pImgListDrag->Add( &cBmp, RGB( 255,255,255) ); // make white transparent!

     //--------- you do the rest... this is what i used for testing
     
     m_pImgListDrag->BeginDrag( 0, CPoint(8, 8) );
     m_pImgListDrag->DragEnter( GetDesktopWindow(), pNMListView->ptAction );

     m_fDragging= TRUE;
     SetCapture (); // capture all mouse messages
}

//----------------- more of my testing code.
//----- yours will be different

void CD01Dlg::OnMouseMove(UINT nFlags, CPoint point)
{
     if ( m_fDragging ) {
          CPoint pt(point);
          CWnd* pwndDraggingOver= WindowFromPoint(pt);
          ClientToScreen( &pt );
          m_pImgListDrag->DragMove(pt);            // move the drag image
          m_pImgListDrag->DragShowNolock( FALSE ); // unlock window updates

          m_pImgListDrag->DragShowNolock( TRUE ); // show only the drag updates
     }
     
     CDialog::OnMouseMove(nFlags, point);
}

=-=-=-=-=-=-=-
You will need to set up the rectangle for the call into the CreateBitmapFromWindowRect() fn.  Note that it expects Window coordinates rather than screen coordinates (I think it is easier for you this way)

I did not do anything to make the drag image look 'dim' It looked great as is.  I guess the dimming is being done automatically by the DragMove or DragShowNoLock fn... I saw no need to monkey with it.

-- Dan
0
 

Author Comment

by:sabrog
ID: 6856996
Thank you, works great!

Scott
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
MFC Dialog 9 48
How to know only "File created" with EventLog 3 32
matchUp  challenge 6 53
modThree challenge 4 79
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

863 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

21 Experts available now in Live!

Get 1:1 Help Now