DefListDragHandler

>>-aMessageExtensions~DefListDragHandler-----------------------><


A list view control cannot handle a drag-and-drop operation within the list view. Therefore, you can connect the DefListDragHandler method with the BEGINDRAG or BEGINRDRAG notification message (see ConnectListNotify) to allow the dragging of an item from one location to another within an icon view and a smallicon view. The cursor shape is changed to a crosshair during the drag operation. You can cancel the drag operation by clicking the other mouse button while holding the button that started the drag operation. Note that the item position is not flexible when the list view control has the AUTOARRANGE style.

The DefListDragHandler is implemented as follows:

::method DefListDragHandler
   use arg id, item, pt
   lc = self~GetListControl(id)
   hc = lc~Cursor_Cross   /* change cursor and store current */
   parse value lc~GetRect with left top right bottom
   parse var pt oldx oldy
   origin = lc~ItemPos(item)
   lmb = self~IsMouseButtonDown("LEFT")
   rmb = self~IsMouseButtonDown("RIGHT")
   do while (lmb \= 0 | rmb \= 0) & \(lmb \= 0 & rmb \= 0)
     pos = self~CursorPos
     parse var pos x y
     parse value lc~ScreenToClient(x, y) with newx newy
     hs = lc~HScrollPos; vs = lc~VScrollPos
     sx = x-right
     sy = y-bottom
      in_rx = (sx <= 30) & (newx >= -30)
      in_ry = (sy <= 30) & (newy >= -30)
      if (in_rx & in_ry) then do    /* is the mouse cursor inside the drag
                                                      rectangle */
          if xright then sx = sx + 30; else sx = 0
          if ybottom then sy = sy + 30; else sy = 0
          newx = newx+hs;  newy = newy +vs;
          if newx < 0 then newx = 0
          if newy < 0 then newy = 0
          if (in_rx & oldx \= newx) | (in_ry & oldy \= newy) then do
           lc~SetItemPos(item, newx, newy)
             oldx = newx
             oldy = newy
             if sx \= 0 | sy \= 0 then do
                lc~Scroll(sx, sy)
                call msSleep 30
             end
        end
      end
      else do    /* no, so force the mouse cursor back inside the rectangle */
         if newx < -30 then newx = -30
         if sx > 30 then newx = (right-left) + 28
         if newy < -30 then newy = -30
         if sy > 30 then newy = (bottom-top) + 28
         parse value lc~ClientToSCreen(newx, newy) with x y
         self~SetCursorPos(x, y)
      end
      lmb = self~IsMouseButtonDown("LEFT")
      rmb = self~IsMouseButtonDown("RIGHT")
   end
   if (lmb \= 0 & rmb \= 0) then do  /* if both buttons pressed restore
                                         original pos */
      parse var origin x y
      lc~SetItemPos(item, x, y)
   end
   lc~RestoreCursorShape(hc)  /* restore old cursor */
   pos = self~CursorPos
   parse var pos x y
   self~SetCursorPos(x+1, y+1)  /* move cursor to force redraw */