I'm trying to draw a line to show where the listview row will drop. But I can't get it to work properly (I just focused on the draw part).
Could you help me please ? Here is the code :
EDIT : Here is a working code from Shardik (thank you !)
Code: Select all
Structure LVINSERTMARK
  cbSize.L
  dwFlags.L
  iItem.L
  dwReserved.L
EndStructure
Define DraggingIsActive.I
Define HeaderHeight.I
Define Rectangle.RECT
Define RowIndex.I
Define RowHeight.I
Define RowInsertionIndex.I
Procedure WindowCallback(WindowHandle.I, Msg.I, WParam.I, LParam.I)
  Shared DraggingIsActive.I
  Protected *NMHdr.NMHDR
  Select Msg
    Case #WM_NOTIFY
      *NMHdr = LParam
      If *NMHdr\hwndFrom = GadgetID(0)       
        If *NMHdr\code = #LVN_ITEMCHANGING
          If DraggingIsActive And GetGadgetState(0) = -1
            ; ----- Disable highlighting of item under cursor
            ProcedureReturn #True
          EndIf
        EndIf
      EndIf
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
Procedure DragCallback(Action.I)
  Shared HeaderHeight.I
  Shared RowHeight.I
  Shared RowInsertionIndex.I
  Protected CursorPositon.POINT
  Protected CursorRow.I
  Protected InsertMark.LVINSERTMARK
  Protected Rectangle.RECT
  Protected RowCount.I
  InsertMark\cbSize = SizeOf(LVINSERTMARK)
  GetCursorPos_(CursorPositon)
  GetWindowRect_(GadgetID(0), Rectangle)
  If PtInRect_(Rectangle, CursorPositon\x + (CursorPositon\y) << 32)
    ; ----- Convert x and y from coordinate space to window-relative space
    MapWindowPoints_(0, GadgetID(0), CursorPositon, 1)
    ; ----- Get row index of current cursor position
    CursorRow = (CursorPositon\y - HeaderHeight) / RowHeight
    RowCount = CountGadgetItems(0)
    If CursorRow >= RowCount
      ; ----- Cursor is in empty row below last item
      RowInsertionIndex = RowCount
    ElseIf CursorRow = -1
      CursorRow = 0
    Else
      ; ----- Get row insertion index
      SendMessage_(GadgetID(0), #LVM_INSERTMARKHITTEST, @CursorPositon,
        @InsertMark)
      ; ----- Display insertion line
      SendMessage_(GadgetID(0), #LVM_SETINSERTMARK, 0, @InsertMark)
      RowInsertionIndex = InsertMark\iItem
      ; ----- Increase index if cursor is in lower part of row
      If (CursorPositon\y - HeaderHeight) % RowHeight > RowHeight * 0.5
        RowInsertionIndex + 1
      EndIf
    EndIf
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure DropCallback(TargetHandle.I, Status.I, Format.I, Action.I, x.I, y.I)
  Shared DraggingIsActive.I
  Protected InsertMark.LVINSERTMARK
  Protected Result.I = #False
  InsertMark\cbSize = SizeOf(LVINSERTMARK)
  Select Status
    Case #PB_Drag_Move, #PB_Drag_Enter
      DraggingIsActive = #True
    Case #PB_Drag_Leave, #PB_Drag_Finish
      DraggingIsActive = #False
      ; ----- Remove insertion line
      InsertMark\iItem = -1
      SendMessage_(GadgetID(0), #LVM_SETINSERTMARK, 0, @InsertMark)
  EndSelect
  If Status <> #PB_Drag_Leave
    Result = #True
  EndIf
  ProcedureReturn Result
EndProcedure
OpenWindow(0, 100, 100, 370, 150, "Drag 'n drop row inside gadget")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
  "Name", 100,
  #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0,
  0, #PB_ListIcon_ColumnWidth) - 4)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ +
  "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ +
  "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ +
  "321 Logo Drive, Mouse House, Downtown")
EnableGadgetDrop(0, #PB_Drop_Text, #PB_Drag_Copy)
SetDragCallback(@DragCallback())
SetDropCallback(@DropCallback())
; ----- Get height of header row
GetClientRect_(SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0), @Rectangle)
HeaderHeight = Rectangle\bottom - Rectangle\top
; ----- Get height of single row
RowHeight = SendMessage_(GadgetID(0), #LVM_GETITEMSPACING, #True, 0) >> 16
; ----- Initialize WindowCallback to suppress highlighting
SetWindowCallback(@WindowCallback(), 0)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0 And EventType() = #PB_EventType_DragStart
        DraggingIsActive = #True
        RowIndex = GetGadgetState(0)
        ; ----- Deselect any selected entry
        SetGadgetState(0, -1)
     
        If RowIndex >= 0
          DragText(GetGadgetItemText(0, RowIndex, 0) + #LF$ +
            GetGadgetItemText(0, RowIndex, 1), #PB_Drag_Copy)
        EndIf
      EndIf
    Case #PB_Event_GadgetDrop
      AddGadgetItem(0, RowInsertionIndex, EventDropText())
      ; ----- Deselect any selected entry
      SetGadgetState(0, -1)
  EndSelect
ForEver





 And thank you to RASHAD too !
 And thank you to RASHAD too !