Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Multiple drag images for ListView

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Multiple drag images for ListView

    Code:
       FUNCTION CreateDragImageEx(lpPoint AS POINTAPI) AS LONG
       ' Supports generation of drag images for single or multiple
       ' ListView selections.
       ' Merges the selected ListView items into a single Imagelist
       ' by creating a bitmap in a memory DC and painting the drag
       ' images from each selected item into it.
       ' Masking is used to provide a transparent background.
       ' Example usage:
       '  LOCAL nmLvPtr AS NM_LISTVIEW PTR
       '     CASE %WM_NOTIFY
       '     nmLvPtr = lParam
       '     SELECT CASE @nmLvPtr.hdr.code
       '     CASE %LVN_BEGINDRAG
       '        hImage = CreateDragImageEx(pt)
       '        ImageList_BeginDrag hImage, 0, pt.x, pt.y
       '        ImageList_DragEnter GetDesktopWindow, pt.x, pt.y
       '        SetCapture()
    
       LOCAL SingleRect AS RECT, CompleteRect AS RECT, pos AS LONG, Pt AS POINTAPI, hDC AS LONG, _
             hMemDC AS LONG, hBitMap AS LONG, hOldMemDCBitMap AS LONG, hSingleImageList AS LONG, _
             hCompleteImageList AS LONG, tRect AS RECT, Green AS DWORD
    
       ' Determine what the total size of the drag image will be
       DO
          pos = ListView_GetNextItem(hListView, pos, %LVNI_SELECTED)
          IF pos < 0 THEN EXIT LOOP
          ListView_GetItemRect hListView, pos, SingleRect, %LVIR_BOUNDS
          ' Build the drag rectangle
          UnionRect CompleteRect, CompleteRect, SingleRect
       LOOP
    
       ' Create bitmap in memory DC
       hDC = GetDC(hWndClient)
       hMemDC = CreateCompatibleDC(hDC)
       w& = CompleteRect.nRight -  CompleteRect.nLeft
       h& = CompleteRect.nBottom -  CompleteRect.nTop
       hBitMap = CreateCompatibleBitMap(hDC, w&, h&)
    
       hOldMemDCBitMap = SelectObject(hMemDC, hBitMap)
    
       ' Use green as mask color
       Green = RGB(0, 255, 0)
       hBrush& = CreateSolidBrush(Green)
       SelectObject hMemDC, hBrush&
    
       ' Scale rect offsets to zero
       tRect = CompleteRect
       tRect.nBottom = tRect.nBottom - tRect.nTop : tRect.nTop = 0
       FillRect hMemDC, tRect, hBrush&
       DeleteObject hBrush&
       pos = 0
    
       ' Paint each DragImage in the DC
       DO
          pos = ListView_GetNextItem(hListView, pos, %LVNI_SELECTED)
          IF pos < 0 THEN EXIT LOOP
          hSingleImageList = ListView_CreateDragImage(hListView, pos, Pt)
          IF hSingleImageList THEN
             ListView_GetItemRect hListView, pos, SingleRect, %LVIR_BOUNDS
             ImageList_Draw hSingleImageList, 0, hMemDC, SingleRect.nLeft - CompleteRect.nLeft, _
                                              Singlerect.nTop - CompleteRect.nTop, %ILD_MASK
             ImageList_Destroy hSingleImageList
          END IF
       LOOP
    
       SelectObject hMemDC, hOldMemDCBitMap
    
       ' Create the imagelist with the merged drag images
       hCompleteImageList = ImageList_Create(w&, h&, %ILC_COLOR OR %ILC_MASK, 0, 1)
    
       ' Again, green is used as mask color
       ImageList_AddMasked hCompleteImageList, hBitMap, Green
    
       ' Clean up...
       ReleaseDC hWndClient, hDC
       DeleteDC hMemDC
       DeleteObject hBitMap
    
       ' Helper code provides offset to mouse cursor for (BeginDrag)
       GetCursorPos Pt
       ScreenToClient hListView, Pt
       lpPoint.x = Pt.x - CompleteRect.nLeft : lpPoint.y = Pt.y - CompleteRect.nTop
       FUNCTION = hCompleteImageList
    END FUNCTION
    ------------------
    Nick
    Nick

  • #2
    I found a bug in the code. It wouldn't do row zero.
    Add: pos = -1
    before each DO... LOOP statement.


    ------------------
    Nick
    Nick

    Comment

    Working...
    X