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);



Comments

  • Why to count indent levels?

    Posted by Legacy on 04/25/2000 12:00am

    Originally posted by: Tomas Brotz

    Simply get the text bounding rectangle and substract one indent. You save the while cycle and the GetScrollPos() call.

    // Get the text bounding rectangle
    if (pMyTree->GetItemRect(htiHit, &itemRect, TRUE))
    {
    // Calculate the new offset
    offsetPt.y = dragPt.y - itemRect.top;
    offsetPt.x = dragPt.x - (itemRect.left - pMyTree->GetIndent());
    }

    Reply
  • Account for stateMask bitmap in x offset

    Posted by Legacy on 12/09/1999 12:00am

    Originally posted by: Joey Ting

    Add the following after the new offset calculation.
    
    

    UINT nState;
    if(nState=GetItemState( htiHit, LVIS_STATEIMAGEMASK ) ){
    (nState>>=12)--;
    IMAGEINFO ImageInfo;
    //State Image list
    m_ImageListState.GetImageInfo(nState,&ImageInfo);
    offsetPt.x -= (ImageInfo.rcImage.right-ImageInfo.rcImage.left);
    }

    Reply
  • Taking checkboxes into account

    Posted by Legacy on 05/27/1999 12:00am

    Originally posted by: P�l Kristian T�nder

    The following code also checks for state images
    
    (for instance check boxes)

    CImageList* pList = pMyTree->GetImageList(TVSIL_STATE);
    if(pList) {
    IMAGEINFO info;
    pList->GetImageInfo(1, &info);
    offsetPt.x -= info.rcImage.right-info.rcImage.left;
    }

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: April 22, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Database professionals — whether developers or DBAs — can often save valuable time by learning to get the most from their new or existing productivity tools. Whether you're responsible for managing database projects, performing database health checks and reporting, analyzing code, or measuring software engineering metrics, it's likely you're not taking advantage of some of the lesser-known features of Toad from Dell. Attend this live …

  • The rapid evolution of enterprise storage technologies, combined with external forces, like the explosion of big data, can cause Linux® and server administrators to play catch-up when it comes to storage. Running a bunch of monolithic storage devices and proprietary, disconnected technologies forces administrators to spend valuable time creating and managing complex solutions. To reduce complexity and enable rapid deployment of new technologies and applications, server administrators need a single open …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds