Dynamic Calculation of DragImage Hotspot

Have you ever noticed how, when you drag an item from the left pane in
the Explorer, the drag image is always created relative to the cursor
position? It looks like you are grabbing the drag item exactly where
the cursor is. Here is code that accomplishes this. The key is to
dynamically calculate the offset between the cursor and the selected
image, and use that as the hotspot.

This code is added to the OnBeginDrag method, immediately before the
call to CImageList::BeginDrag. Change variable names as needed to make
it work in your code.

        // Calculate the offset to the hotspot
        CPoint offsetPt(8,8);   // Initialize a default offset

        CPoint dragPt = pNMTreeView->ptDrag;    // Get the Drag point
        UINT nHitFlags = 0;
        HTREEITEM htiHit = pMyTree->HitTest(dragPt, &nHitFlags);
        if (NULL != htiHit)
        {
                // The drag point has Hit an item in the tree
                CRect itemRect;
                if (pMyTree->GetItemRect(htiHit, &itemRect, FALSE))
                {
                        // Count indent levels
                        HTREEITEM htiParent = htiHit;
                        int nIndentCnt = 0;
                        while (htiParent != NULL)
                        {
                                htiParent = pMyTree->GetParentItem(htiParent);
                                nIndentCnt++;
                        }

                        // Calculate the new offset
                        offsetPt.y = dragPt.y - itemRect.top;
                        offsetPt.x = dragPt.x - (nIndentCnt * pMyTree->GetIndent()) + GetScrollPos(SB_HORZ);
                }
        }

        // Begin the Drag operation using the Drag image and the calculated hotspot offset
        m_pDragImage->BeginDrag(0, offsetPt);

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read