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

  • Microsoft® Office 365 is a top choice for enterprises that want a cloud-based suite of productivity/ collaboration applications. With Office 365, you get access to Microsoft™ Office solutions practically anytime, anywhere, on virtually any device. It's a great option for current Microsoft users who can now build on their experience with Microsoft™ solutions while enjoying the flexibility of a cloud-based delivery. But even organizations with no previous investment in Microsoft will find that …

  • Live Event Date: July 28, 2016 @ 1:00 p.m. ET / 10:00 a.m. PT Jepsen tests are third-party tests for distributed databases that validate vendors' guarantees about how they perform under various failure scenarios, especially network partitions. These have proven their value as tools in any distributed system tester's arsenal. When the creator of Jepsen, Kyle Kingsbury, started his Jepsen-for-Hire business last fall, VoltDB immediately got in line, and over the past two months, our solution was given the most …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date