[ahkv2]It is to change the Class_LV_Rows to v2 version need help
Posted: 12 Aug 2018, 04:46
Original version of address
https://github.com/Pulover/Class_LV_Rows
This is LV_Rows I am editing.
Below is the LV_Rows test script
I want to use LV_Rows drag in ahkv2
Please help me
https://github.com/Pulover/Class_LV_Rows
This is LV_Rows I am editing.
Code: Select all
;=======================================================================================
;
; Class LV_Rows
;
; Author: Pulover [Rodolfo U. Batista]
; AHK version: 1.1.23.01
;
; Additional functions for ListView controls
;=======================================================================================
;
; This class provides an easy way to add functionalities to ListViews that are not
; supported by AutoHotkey built-in functions such as Copy, Cut, Paste, Drag and more.
;
;=======================================================================================
;
; Edit Functions:
; Copy()
; Cut()
; Paste([Row, Multiline])
; Duplicate()
; Delete()
; Move([Up])
; Drag([DragButton, AutoScroll, ScrollDelay, LineThick, Color])
;
; History Functions:
; Add()
; Undo()
; Redo()
; ClearHistory()
;
; Group Functions:
; EnableGroups([Enable, FirstName, Collapsible, StartCollapsed])
; InsertGroup([Row, GroupName])
; RemoveGroup([Row])
; InsertAtGroup([Count, Rows*])
; RemoveAtGroup([Count, Rows*])
; SetGroups(Groups)
; GetGroups([AsObject])
; SetGroupCollapisable([Collapsible])
; RemoveAllGroups([FirstName])
; CollapseAll([Collapse])
; RefreshGroups([Collapsed])
;
; Management Functions:
; InsertHwnd(Hwnd)
; RemoveHwnd(Hwnd)
; SetHwnd(Hwnd [, NewData])
; GetData([Hwnd])
; SetCallback(Func)
;
;=======================================================================================
;
; Usage:
;
; You can call the function by preceding them with LV_Rows. For example:
; LV_Rows.Copy() <-- Calls function on active ListView.
;
; Or with a handle initialized via New meta-function. For example:
; MyListHandle := New LV_Rows() <-- Creates a new handle.
; MyListHandle.Add() <-- Calls function for that Handle.
;
; Like AutoHotkey built-in functions, these functions operate on the default gui,
; and active ListView control. When usingle handles, SetHwnd will attempt to set
; the selected ListView as active, but it's recommend to call Gui, Listview on
; your script too.
;
; Initializing is required for History and Group functions and in case your ListView
; has icons to be moved during Drag().
; Gui, Add, ListView, hwndhLV, Columns
; MyListHandle := New LV_Rows(hLV) <-- Creates a new handle with Hwnd.
;
; Gui, Add, ListView, hwndhLV1, Columns
; Gui, Add, ListView, hwndhLV2, Columns
; MyListHandle := New LV_Rows(hLV1, hLV2)
;
; You can also use the same handle for the Edit functions.
; You can create more handles or pass the ListView's Hwnd to operate on different
; lists with the same handle.
;
; In order to keep row's icons you need to initialize the class passing the
; ListView's Hwnd. For example:
; Gui, Add, ListView, hwndhLV, Columns
; MyListHandle := New LV_Rows(hLV)
;
;=======================================================================================
Class LV_Rows extends LV_Rows.LV_EX
{
;=======================================================================================
; Meta-Functions Pass the Hwnd of one or more Listiviews when initializing it to
; manage history, groups and keep row's icons during Drag().
; Use InsertHwnd() to add more lists and SetHwnd() to switch between them.
;
; Properties:
; ActiveSlot: Contains the current entry position in the ListView History.
; HasChanged: The HasChanged property may optionally be used to check if the
; ListView has been changed. For this you must use a handle
; for all functions.
; Every time a function (except Copy) is called it will be set
; to true. The user may consult Handle.HasChanged to show
; a save dialog and set it to False after saving.
;=======================================================================================
__New(LVname, Hwnd*)
{
this.hArray := {}
this.LVname := LVname
If (Hwnd.Length())
{
For e, h in Hwnd
{
this.hArray[h] := { Hwnd: h
, GroupsArray: []
, Slot: []
, ActiveSlot: 1}
, this.hArray[h].GroupsArray.Push({Name: "Start", Row: 1})
}
this.LVHwnd := this.hArray[Hwnd[1]].Hwnd
, this.Handle := this.hArray[Hwnd[1]]
}
Else
{
this.hArray["default"] := { Hwnd: ""
, GroupsArray: []
, Slot: []
, ActiveSlot: 1}
, this.Handle := this.hArray["default"]
, this.Handle.GroupsArray.Push({Name: "Start", Row: 1})
}
}
__Call(Func)
{
Callback := this.Callback
If (IsFunc(Callback))
{
If (!%Callback%(Func, this.LVHwnd))
return
}
If "Cut,Paste,Duplicate,Delete,Move,Drag,Undo,Redo" ~= "\b" Func "\b"
this.HasChanged := true
}
__Delete()
{
this.RemoveAt(1, this.Length())
, this.SetCapacity(0)
, this.base := ""
}
;=======================================================================================
; Management Functions: Set, Insert and Remove ListView Hwnd's.
;=======================================================================================
; Function: Handle.InsertHwnd()
; Description: Inserts one or more ListView Hwnd's to be managed.
; Parameters:
; Hwnd: One or more ListView Hwnd's.
; Return: No return value.
;=======================================================================================
InsertHwnd(Hwnd*)
{
If (Hwnd.Length())
{
For e, h in Hwnd
{
If (this.hArray.HasKey(h))
continue
this.hArray[h] := { Hwnd: h
, GroupsArray: []
, Slot: []
, ActiveSlot: 1}
, this.hArray[h].GroupsArray.Push({Name: "Start", Row: 1})
}
}
}
;=======================================================================================
; Function: Handle.RemoveHwnd()
; Description: Removes a ListView Hwnd.
; Parameters:
; Hwnd: Hwnd of the ListView to be removed.
; Return: No return value.
;=======================================================================================
RemoveHwnd(Hwnd)
{
If (this.hArray.HasKey(Hwnd))
{
this.hArray[Hwnd].RemoveAt(1, this.Length())
, this.hArray[Hwnd].SetCapacity(0)
, this.hArray[Hwnd].base := ""
}
}
;=======================================================================================
; Function: Handle.SetHwnd()
; Description: Selects a previously inserted ListView or adds it to the handle
; and selects it, optionally copying the data, history and
; groups from another Hwnd.
; Parameters:
; Hwnd: Hwnd of a ListView to be selected. If the hwnd is not found, it
; will be added to the handle and selected.
; NewData: Hwnd of a previously inserted ListView whose data, history and groups
; will be copied to the one being selected.
; Return: No return value.
;=======================================================================================
SetHwnd(Hwnd, NewData := "")
{
If (this.hArray.HasKey(Hwnd))
{
this.LVHwnd := this.hArray[Hwnd].Hwnd
, this.Handle := this.hArray[Hwnd]
;~ Gui, Listview, % this.LVHwnd ;checklv
If (NewData != "")
{
If (IsObject(NewData))
{
this.hArray[Hwnd].GroupsArray := NewData.GroupsArray
, this.hArray[Hwnd].Slot := NewData.Slot
, this.hArray[Hwnd].ActiveSlot := NewData.ActiveSlot
, this.Load()
}
Else If (this.hArray.HasKey(NewData))
{
this.hArray[Hwnd].GroupsArray := this.hArray[NewData].GroupsArray.Clone()
, this.hArray[Hwnd].Slot := this.hArray[NewData].Slot.Clone()
, this.hArray[Hwnd].ActiveSlot := this.hArray[NewData].ActiveSlot
, this.Load()
}
}
return
}
this.hArray[Hwnd] := { Hwnd: Hwnd
, GroupsArray: []
, Slot: []
, ActiveSlot: 1}
this.LVHwnd := Hwnd
, this.Handle := this.hArray[Hwnd]
, this.Handle.GroupsArray.Push({Name: "Start", Row: 1})
;~ Gui, Listview, % this.LVHwnd ;checklv
If (NewData != "")
{
If (IsObject(NewData))
{
this.hArray[Hwnd].GroupsArray := NewData.GroupsArray
, this.hArray[Hwnd].Slot := NewData.Slot
, this.hArray[Hwnd].ActiveSlot := NewData.ActiveSlot
, this.Load()
}
Else If (this.hArray.HasKey(NewData))
{
this.hArray[Hwnd].GroupsArray := this.hArray[NewData].GroupsArray.Clone()
, this.hArray[Hwnd].Slot := this.hArray[NewData].Slot.Clone()
, this.hArray[Hwnd].ActiveSlot := this.hArray[NewData].ActiveSlot
, this.Load()
}
}
}
;=======================================================================================
; Function: Handle.GetData()
; Description: Retrieves the data, history and groups of a previously inserted
; ListView.
; Parameters:
; Hwnd: Hwnd of a previously inserted ListView. If left blank, the
; current active ListView will be returned.
; Return: An object with data, history and groups of a ListView.
;=======================================================================================
GetData(Hwnd := "")
{
If (Hwnd = "")
Hwnd := this.LVHwnd
If (this.hArray.HasKey(Hwnd))
return this.hArray[Hwnd].Clone()
}
;=======================================================================================
; Function: LV_Rows.SetCallback()
; Description: Sets a callback function where the user can take actions based
; on the function being called called. The Callback function
; must return true for the operation to be completed.
; Parameters:
; Func: Name of a user-defined function that should receive 2 parameters:
; The name of the function being called and the Hwnd of the
; current set ListView.
; Return: No return value.
;=======================================================================================
SetCallback(Func)
{
this.Callback := Func
}
;=======================================================================================
; Edit Functions: Edit ListView rows.
;=======================================================================================
; Function: LV_Rows.Copy()
; Description: Copy selected rows to memory.
; Return: Number of copied rows.
;=======================================================================================
Copy()
{
this.CopyData := [], LV_Row := 0
Loop
{
LV_Row := this.LVname.GetNext(LV_Row)
If (!LV_Row)
break
RowData := this.RowText(LV_Row)
, Row := [RowData*]
, this.CopyData.Push(Row)
, CopiedLines := A_Index
}
return CopiedLines
}
;=======================================================================================
; Function: LV_Rows.Cut()
; Description: Copy selected rows to memory and delete them.
; Return: Number of copied rows.
;=======================================================================================
Cut()
{
this.CopyData := [], LV_Row := 0
Loop
{
LV_Row := this.LVname.GetNext(LV_Row)
If (!LV_Row)
break
RowData := this.RowText(LV_Row)
, Row := [RowData*]
, this.CopyData.Push(Row)
, CopiedLines := A_Index
}
this.Delete()
this.RefreshGroups()
return CopiedLines
}
;=======================================================================================
; Function: LV_Rows.Paste()
; Description: Paste copied rows at selected position.
; Parameters:
; Row: If non-zero pastes memory contents at the specified row.
; Multiline: If true pastes the contents at every selected row.
; Return: True if memory contains data or false if not.
;=======================================================================================
Paste(Row := 0, Multiline := false)
{
If (!this.CopyData.Length())
return false
TargetRow := Row ? Row : this.LVname.GetNext()
If (!TargetRow)
{
For each, Row in this.CopyData
this.LVname.Add(Row*)
}
Else
{
If ((!Row) && (Multiline))
{
LV_Row := 0
Loop
{
LV_Row := this.LVname.GetNext(LV_Row - 1)
If (!LV_Row)
break
For e, g in this.Handle.GroupsArray
{
If ((g.Row > 1) && (LV_Row < g.Row))
g.Row += this.CopyData.Length()
}
For each, Row in this.CopyData
this.LVname.Insert(LV_Row, Row*), LV_Row += 1
LV_Row += 1
}
}
Else
{
LV_Row := TargetRow - 1
For e, g in this.Handle.GroupsArray
{
If ((g.Row > 1) && ((LV_Row+1) < g.Row))
g.Row += this.CopyData.Length()
}
For each, Row in this.CopyData
this.LVname.Insert(LV_Row+A_Index, Row*)
}
}
this.RefreshGroups()
return true
}
;=======================================================================================
; Function: LV_Rows.Duplicate()
; Description: Duplicates selected rows.
; Return: Number of duplicated rows.
;=======================================================================================
Duplicate()
{
CopyData := this.CopyData.Clone()
, DupLines := this.Copy()
, this.Paste()
, this.CopyData := CopyData.Clone()
, CopyData.RemoveAt(1, CopyData.Length())
, CopyData := ""
, this.RefreshGroups()
return DupLines
}
;=======================================================================================
; Function: LV_Rows.Delete()
; Description: Delete selected rows.
; Return: Number of removed rows.
;=======================================================================================
Delete()
{
If (this.LVname.GetCount("Selected") = 0)
return false
LV_Row := 0
Loop
{
LV_Row := this.LVname.GetNext(LV_Row - 1)
If (!LV_Row)
break
this.LVname.Delete(LV_Row)
, DeletedLines := A_Index
For e, g in this.Handle.GroupsArray
{
If ((g.Row > 1) && (LV_Row < g.Row))
g.Row--
}
}
this.RefreshGroups()
return DeletedLines
}
;=======================================================================================
; Function: LV_Rows.Move()
; Description: Move selected rows down or up.
; Parameters:
; Up: If false or omitted moves rows down. If true moves rows up.
; Return: Number of rows moved.
;=======================================================================================
Move(Up := false)
{
Selections := [], LV_Row := 0
Critical
If (Up)
{
Loop
{
LV_Row := this.LVname.GetNext(LV_Row)
If (!LV_Row)
break
If (LV_Row = 1)
return
Selections.Push(LV_Row)
}
For each, Row in Selections
{
RowData := this.RowText(Row)
, this.LVname.Insert(Row-1, RowData*)
, this.LVname.Delete(Row+1)
, this.LVname.Modify(Row-1, "Select")
If (A_Index = 1)
this.LVname.Modify(Row-1, "Focus Vis")
}
this.RefreshGroups()
return Selections.Length()
}
Else
{
Loop
{
LV_Row := this.LVname.GetNext(LV_Row)
If (!LV_Row)
break
If (LV_Row = this.LVname.GetCount())
return
Selections.InsertAt(1, LV_Row)
}
For each, Row in Selections
{
RowData := this.RowText(Row+1)
, this.LVname.Insert(Row, RowData*)
, this.LVname.Delete(Row+2)
If (A_Index = 1)
this.LVname.Modify(Row+1, "Focus Vis")
}
this.RefreshGroups()
return Selections.Length()
}
}
;=======================================================================================
; Function: LV_Rows.Drag()
; Description: Drag-and-Drop selected rows showing a destination bar.
; Must be called in the ListView G-Label subroutine when
; A_GuiEvent returns "D" or "d".
; Parameters:
; DragButton: If it is a lower case "d" it will be recognized as a Right-Click
; drag and won't actually move any row, only return the
; destination, otherwise it will be recognized as a Left-Click
; drag. You may pass A_GuiEvent as the parameter.
; AutoScroll: If true or omitted the ListView will automatically scroll
; up or down when the cursor is above or below the control.
; ScrollDelay: Delay in miliseconds for AutoScroll. Default is 100ms.
; LineThick: Thickness of the destination bar in pixels. Default is 2px.
; Color: Color of destination bar. Default is "Black".
; Return: The destination row number.
;=======================================================================================
Drag(DragButton := "D", AutoScroll := true, ScrollDelay := 100, LineThick := 2, Color := "Black")
{
Static LVIR_LABEL := 0x0002
Static LVM_GETITEMCOUNT := 0x1004
Static LVM_SCROLL := 0x1014
Static LVM_GETTOPINDEX := 0x1027
Static LVM_GETCOUNTPERPAGE := 0x1028
Static LVM_GETSUBITEMRECT := 0x1038
Static LV_currColHeight := 0
RestoreGroups := false
If (this.IsGroupViewEnabled())
{
RestoreGroups := true
, this.EnableGroupView(false)
}
;~ SysGet, SM_CXVSCROLL, 2
SM_CXVSCROLL := SysGet(2)
If (InStr(DragButton, "d", true))
DragButton := "RButton"
Else
DragButton := "LButton"
CoordMode "Mouse", "Window"
MouseGetPos , , LV_Win, LV_LView, 2
WinGetPos Win_X, Win_Y, Win_W, Win_H, "ahk_id " . LV_Win
ControlGetPos LV_lx, LV_ly, LV_lw, LV_lh, , "ahk_id " . LV_LView
LV_lw := LV_lw * 96 / A_ScreenDPI
, VarSetCapacity(LV_XYstruct, 16, 0)
While (GetKeyState(DragButton, "P"))
{
MouseGetPos LV_mx, LV_my,, CurrCtrl, 2
LV_mx -= LV_lx, LV_my -= LV_ly
If (AutoScroll)
{
If (LV_my < 0)
{
SendMessage LVM_SCROLL, 0, -LV_currColHeight,, "ahk_id " . LV_LView
Sleep ScrollDelay
}
If (LV_my > LV_lh)
{
SendMessage LVM_SCROLL, 0, LV_currColHeight,, "ahk_id " . LV_LView
Sleep ScrollDelay
}
}
If (CurrCtrl != LV_LView)
{
LV_currRow := ""
;~ Gui, MarkLine:Cancel ;checklv
continue
}
LV_TotalNumOfRows := SendMessage(LVM_GETITEMCOUNT, 0, 0,, "ahk_id " . LV_LView)
;~ LV_TotalNumOfRows := ErrorLevel
LV_NumOfRows := SendMessage(LVM_GETCOUNTPERPAGE, 0, 0,, "ahk_id " . LV_LView)
;~ LV_NumOfRows := ErrorLevel
LV_topIndex := SendMessage(LVM_GETTOPINDEX, 0, 0,, "ahk_id " . LV_LView)
;~ LV_topIndex := ErrorLevel
, Line_W := (LV_TotalNumOfRows > LV_NumOfRows) ? LV_lw - SM_CXVSCROLL : LV_lw
Loop LV_NumOfRows + 1
{
LV_which := LV_topIndex + A_Index - 1
NumPut(LVIR_LABEL, LV_XYstruct, 0, "UInt")
, NumPut(A_Index - 1, LV_XYstruct, 4, "UInt")
SendMessage LVM_GETSUBITEMRECT, LV_which, &LV_XYstruct,, "ahk_id " . LV_LView
LV_RowY := NumGet(LV_XYstruct, 4, "UInt")
, LV_RowY2 := NumGet(LV_XYstruct, 12, "UInt")
, LV_currColHeight := LV_RowY2 - LV_RowY
If (LV_my <= LV_RowY + LV_currColHeight)
{
LV_currRow := LV_which + 1
, LV_currRow0 := LV_which
, Line_Y := Win_Y + LV_ly + LV_RowY
, Line_X := Win_X + LV_lx
If (LV_currRow > (LV_TotalNumOfRows+1))
{
;~ Gui, MarkLine:Cancel ;checklv
LV_currRow := ""
}
Break
}
}
If (LV_currRow)
{
/* ;checklv
Gui, MarkLine:Color, %Color%
Gui, MarkLine:+LastFound +AlwaysOnTop +Toolwindow -Caption +HwndLineMark
Gui, MarkLine:Show, W%Line_W% H%LineThick% Y%Line_Y% X%Line_X% NoActivate
*/
}
}
If (DragButton = "LButton" && LV_currRow)
{
;~ Gui, MarkLine:Cancel ;checklv
Avoid_Row1 := this.LVname.GetNext()
while this.LVname.GetNext(Avoid_Row2)
Avoid_Row2 := this.LVname.GetNext(Avoid_Row2)
if LV_currRow > Avoid_Row1 and LV_currRow < Avoid_Row2 + 1
LV_currRow:=""
else
{
CopyData := this.CopyData.Clone()
Lines := this.Copy()
, this.Paste(LV_currRow)
If (this.LVname.GetNext() < LV_currRow)
o := Lines+1, FocusedRow := LV_currRow-1
Else
o := 1, FocusedRow := LV_currRow
this.Delete()
Loop Lines
{
i := A_Index-o
, this.LVname.Modify(LV_currRow+i, "Select")
}
this.LVname.Modify(FocusedRow, "Focus")
, this.CopyData := CopyData.Clone()
, CopyData.RemoveAt(1, CopyData.Length())
, CopyData := ""
}
}
If (RestoreGroups)
this.EnableGroupView()
return LV_currRow
}
;=======================================================================================
; History Functions: Keep a history of ListView changes and allow Undo and Redo.
; These functions operate on the currently selected ListView.
;=======================================================================================
; Function: Handle.Add()
; Description: Adds an entry on History. This function requires
; initializing: MyListHandle := New LV_Rows()
; Return: The total number of entries in history.
;=======================================================================================
Add()
{
Rows := []
If (this.Handle.ActiveSlot < this.Handle.Slot.Length())
this.Handle.Slot.RemoveAt(this.Handle.ActiveSlot+1, this.Handle.Slot.Length())
Loop this.LVname.GetCount()
{
RowData := this.RowText(A_Index)
, Rows[A_Index] := [RowData*]
}
Groups := []
For e, g in this.Handle.GroupsArray
Groups[e] := {Name: g.Name, Row: g.Row}
this.Handle.Slot.Push({Rows: Rows, Groups: Groups})
this.Handle.ActiveSlot := this.Handle.Slot.Length()
return this.Handle.Slot.Length()
}
;=======================================================================================
; Function: Handle.Undo()
; Description: Replaces ListView contents with previous entry state, if any.
; Return: New entry position or false if it's already the first entry.
;=======================================================================================
Undo()
{
If (this.Handle.ActiveSlot = 1)
return false
this.Handle.ActiveSlot -= 1
, this.Load()
return this.Handle.ActiveSlot
}
;=======================================================================================
; Function: Handle.Redo()
; Description: Replaces ListView contents with next entry state, if any.
; Return: New entry position or false if it's already the last entry.
;=======================================================================================
Redo()
{
If (this.Handle.ActiveSlot = (this.Handle.Slot.Length()))
return false
this.Handle.ActiveSlot += 1
, this.Load()
return this.Handle.ActiveSlot
}
;=======================================================================================
; Function: Handle.ClearHistory()
; Description: Removes all history entries from the ListView.
; Return: New entry position or false if it's already the last entry.
;=======================================================================================
ClearHistory()
{
this.Handle.Slot := []
, this.Handle.ActiveSlot := 1
}
;=======================================================================================
; Group Functions: Set, add and remove Listview Groups.
; These functions are based on just me's LV_EX library:
; http://autohotkey.com/boards/viewtopic.php?t=1256
;=======================================================================================
; Function: Handle.EnableGroups()
; Description: Enables or disables Groups in the currently selected ListView
; initializing: MyListHandle := New LV_Rows()
; Parameters:
; Enable: If TRUE enables GroupView in the selected ListView. If FALSE
; disables it.
; FirstName: Name for the first (mandatory) group at row 1.
; Collapsible: If TRUE makes the groups collapsible.
; StartCollapsed: If TRUE starts all groups collapsed.
; Return: No return value.
;=======================================================================================
EnableGroups(Enable := true, FirstName := "New Group", Collapsible := true, StartCollapsed := false)
{
;~ Gui, Listview, % this.LVHwnd ;checklv
ListCount := this.LVname.GetCount()
, this.Collapsible := Collapsible
, this.EnableGroupView(Enable)
If (Enable)
{
If (!this.Handle.GroupsArray.Length())
this.Handle.GroupsArray := [{Name: FirstName, Row: 1}]
this.RefreshGroups(StartCollapsed)
}
}
;=======================================================================================
; Function: Handle.InsertGroup()
; Description: Inserts or renames a group on top of the specified row.
; Parameters:
; Row: Number of the row for the group to be inserted. If left blank
; the first selected row will be used.
; GroupName: Name of the new group or new name for an existing group.
; Return: TRUE if Row is bigger than 0 or FALSE otherwise.
;=======================================================================================
InsertGroup(Row := "", GroupName := "New Group")
{
If (Row = "")
Row := this.LVname.GetNext()
If (Row <= 0)
return false
For e, g in this.Handle.GroupsArray
{
If (Row = g.Row)
{
this.Handle.GroupsArray[e] := {Name: GroupName, Row: Row}
break
}
If (Row < g.Row)
{
this.Handle.GroupsArray.InsertAt(e, {Name: GroupName, Row: Row})
break
}
If (e = this.Handle.GroupsArray.Length())
{
this.Handle.GroupsArray.Push({Name: GroupName, Row: Row})
break
}
}
If (!this.Handle.GroupsArray.Length())
{
this.Handle.GroupsArray.Push({Name: "New Group", Row: 1})
If (Row > 1)
this.Handle.GroupsArray.Push({Name: GroupName, Row: Row})
}
this.RefreshGroups()
return true
}
;=======================================================================================
; Function: Handle.RemoveGroup()
; Description: Removes the group the indicated row belongs to.
; Parameters:
; Row: Number of a row the group belongs to. If left blank the first
; selected row will be used.
; Return: TRUE if Row is bigger than 0 or FALSE otherwise.
;=======================================================================================
RemoveGroup(Row := "")
{
If (Row = "")
Row := this.LVname.GetNext()
If (Row <= 0)
return false
For e, g in this.Handle.GroupsArray
{
If (Row = g.Row)
{
If (g.Row = 1)
return
this.Handle.GroupsArray.RemoveAt(e)
break
}
If (Row < g.Row)
{
If (e = 2)
return
this.Handle.GroupsArray.RemoveAt(e - 1)
break
}
If (e = this.Handle.GroupsArray.Length())
{
If (g.Row = 1)
return
this.Handle.GroupsArray.RemoveAt(e)
break
}
}
this.RefreshGroups()
return true
}
;=======================================================================================
; Function: Handle.InsertAtGroup()
; Description: Inserts a row at indicated position, moving groups after it one
; row down.
; Parameters:
; Row: Number of the row where to insert.
; Return: No return value.
;=======================================================================================
InsertAtGroup(Row)
{
For e, g in this.Handle.GroupsArray
{
If ((Row > 0) && (Row < g.Row))
g.Row++
}
}
;=======================================================================================
; Function: Handle.RemoveAtGroup()
; Description: Removes a row from indicated position, moving groups after it one
; row up.
; Parameters:
; Row: Number of the row where to insert.
; Return: No return value.
;=======================================================================================
RemoveAtGroup(Row)
{
For e, g in this.Handle.GroupsArray
{
If ((Row > 0) && (Row < g.Row))
g.Row--
}
}
;=======================================================================================
; Function: Handle.SetGroups()
; Description: Sets one or more groups in the selected ListView.
; Parameters:
; Groups: A list of groups in the format "GroupName:RowNumber" separated
; by comma. You can use GetGroups() to save a valid String or
; Object to be used with this function.
; Return: No return value.
;=======================================================================================
SetGroups(Groups)
{
this.Handle.GroupsArray := []
If (!Groups.Length())
{
;~ Loop, Parse, Groups, `,, %A_Space%
Loop Parse, Groups, ",", A_Space
{
Pars := StrSplit(A_LoopField, ":", A_Space)
, this.Handle.GroupsArray.Push({Name: Pars[1], Row: Pars[2]})
}
}
Else
this.Handle.GroupsArray := Groups
this.RefreshGroups()
}
;=======================================================================================
; Function: Handle.GetGroups()
; Description: Returns a string or object representing the current groups in
; the selected ListView.
; Parameters:
; AsObject: If TRUE returns an object with the groups, otherwise an string.
; Both can be used with SetGroups().
; Return: No return value.
;=======================================================================================
GetGroups(AsObject := false)
{
If (AsObject)
return this.Handle.GroupsArray.Clone()
For e, g in this.Handle.GroupsArray
GroupsString .= g.Name ":" g.Row ","
return RTrim(GroupsString, ",")
}
;=======================================================================================
; Function: Handle.SetGroupCollapisable()
; Description: Enables or disables Groups Collapsible style.
; Parameters:
; Collapsible: If TRUE enables Collapsible style in the selected ListView.
; If FALSE disables it.
; Return: No return value.
;=======================================================================================
SetGroupCollapisable(Collapsible := true)
{
this.Collapsible := Collapsible
, this.RefreshGroups()
}
;=======================================================================================
; Function: Handle.RemoveAllGroups()
; Description: Removes all groups in the selected ListView.
; Parameters:
; FirstName: Name for the first (mandatory) group at row 1.
; Return: No return value.
;=======================================================================================
RemoveAllGroups(FirstName := "New Group")
{
If (!this.Handle.GroupsArray.Length())
this.Handle.GroupsArray.Push({Name: FirstName, Row: 1})
Else
{
this.Handle.GroupsArray[1] := {Name: FirstName, Row: 1}
, this.Handle.GroupsArray.RemoveAt(2, this.Handle.GroupsArray.Length())
}
this.RefreshGroups()
}
;=======================================================================================
; Function: Handle.CollapseAll()
; Description: Collapses or expands all groups.
; Parameters:
; Collapse: If TRUE collapses all groups in the selected ListView. If FALSE
; expands all groups in the selected ListView.
; Return: No return value.
;=======================================================================================
CollapseAll(Collapse := true)
{
this.RefreshGroups(Collapse)
}
;=======================================================================================
; Function: Handle.RefreshGroups()
; Description: Reloads the ListView to update groups. This function is called
; automatically in from other functions, usually it's not
; necessary to use it in your script.
; Parameters:
; Collapsed: If TRUE collapses all groups in the selected ListView.
; Return: No return value.
;=======================================================================================
RefreshGroups(Collapsed := false)
{
GroupStates := []
;~ Gui, Listview, % this.LVHwnd ;checklv
For e, g in this.Handle.GroupsArray
{
this.GroupGetState(A_Index + 9, IsCollapsed)
, GroupStates.Push(IsCollapsed ? "Collapsed" : "")
}
ListCount := this.LVname.GetCount()
, this.GroupRemoveAll(), GrNum := 1
Loop ListCount
{
If (this.Handle.GroupsArray[GrNum].Row = A_Index)
{
this.GroupInsert(GrNum + 9, this.Handle.GroupsArray[GrNum].Name)
, Styles := Collapsed ? ["Collapsible", "Collapsed"] : this.Collapsible ? ["Collapsible", GroupStates[GrNum]] : []
, this.GroupSetState(GrNum + 9, Styles*)
, GrNum++
}
this.SetGroup(A_Index, GrNum + 8)
}
}
;=======================================================================================
; Internal Functions: These functions are meant for internal use but can also
; be called if necessary.
;=======================================================================================
; Function: Handle.Load()
; Description: Loads a specified entry in History into ListView.
; Parameters:
; Position: Number of entry position to be loaded.
; Return: false if entry exists, false otherwise.
;=======================================================================================
Load(Position := "")
{
If (Position = "")
Position := this.Handle.ActiveSlot
If (!IsObject(this.Handle.Slot[Position]))
return false
this.LVname.Delete()
For each, Row in this.Handle.Slot[Position].Rows
this.LVname.Add(Row*)
this.Handle.GroupsArray := []
For e, g in this.Handle.Slot[Position].Groups
this.Handle.GroupsArray.Push(g)
this.RefreshGroups()
return true
}
;=======================================================================================
; Function: LV_Rows.RowText()
; Description: Creates an Array of values from each cell in a specified row.
; Parameters:
; Index: Index of the row to get contents from.
; Return: An Array with text from the cells and the row checked status.
;=======================================================================================
RowText(Index)
{
Data := []
, ckd := (this.LVname.GetNext(Index-1, "Checked")=Index) ? 1 : 0
, iIcon := this.GetIconIndex(this.LVHwnd, Index)
, Data.Push("Icon" iIcon " Check" ckd)
Loop this.LVname.GetCount("Col")
{
Cell := this.LVname.GetText(Index, A_Index)
, Data.Push(Cell)
}
return Data
}
;=======================================================================================
; Function: LV_Rows.GetIconIndex()
; Description: Retrieves the row's icon index.
; Parameters:
; Hwnd: Hwnd of the ListView.
; Row: 1-based Row number.
; Return: The 1-based icon index from specified row.
;=======================================================================================
GetIconIndex(Hwnd, Row)
{
Static LVIF_IMAGE := 0x00000002
Static LVM_GETITEMA := 0x1005
Static LVM_GETITEMW := 0x104B
Static LVM_GETITEM := A_IsUnicode ? LVM_GETITEMW : LVM_GETITEMA
VarSetCapacity(LVITEM, 6 * 4 + (A_PtrSize * 2), 0)
, NumPut(LVIF_IMAGE, LVITEM, 0, "UInt") ; mask
, NumPut(Row-1, LVITEM, 4, "Int") ; iItem
SendMessage LVM_GETITEM, 0, &LVITEM,, "ahk_id " . Hwnd
return NumGet(LVITEM, 5 * 4 + (A_PtrSize * 2), "Int") + 1 ; iImage
}
; ======================================================================================================================
; Namespace: LV_EX
; Function: Some additional functions to use with AHK ListView controls.
; Tested with: AHK 1.1.20.03 (A32/U32/U64)
; Tested on: Win 8.1 (x64)
; Note: This version has been modified to include only Group related functions, the complete
; library can be found at https://autohotkey.com/boards/viewtopic.php?t=1256
; Changelog:
; 1.1.00.00/2015-03-13/just me - added basic tile view support (suggested by toralf),
; added basic (XP compatible) group view support,
; revised code and made some minor changes.
; 1.0.00.00/2013-12-30/just me - initial release.
; Notes:
; In terms of Microsoft
; Item stands for the whole row or the first column of the row
; SubItem stands for the second to last column of a row
; All functions require the handle of the ListView (HWND). You get this handle using the 'Hwnd' option when
; creating the control per 'Gui, Add, HwndHwndOfLV ...' or using 'GuiControlGet, HwndOfLV, Hwnd, MyListViewVar'
; after control creation.
; Credits:
; LV_EX tile view functions:
; Initial idea by segalion (old forum: /board/topic/80754-listview-with-multiline-in-report-mode-help/)
; based on code from Fabio Lucarelli (http://users.skynet.be/oleole/ListView_Tiles.htm).
; ======================================================================================================================
; This software is provided 'as-is', without any express or implied warranty.
; In no event will the authors be held liable for any damages arising from the use of this software.
; ======================================================================================================================
Class LV_EX
{
; ======================================================================================================================
; LV_EX_EnableGroupView - Enables or disables whether the items in a list-view control display as a group.
; ======================================================================================================================
EnableGroupView(Enable := true)
{
; LVM_ENABLEGROUPVIEW = 0x109D -> msdn.microsoft.com/en-us/library/bb774900(v=vs.85).aspx
;~ SendMessage, 0x109D, % (!!Enable), 0, , % "ahk_id " . this.LVHwnd
SendMessage 0x109D, (!!Enable), 0, , "ahk_id " . this.LVHwnd
Return (ErrorLevel >> 31) ? 0 : 1
}
; ======================================================================================================================
; LV_EX_GetGroup - Gets the ID of the group the list-view item belongs to.
; ======================================================================================================================
GetGroup(Row)
{
; LVM_GETITEMA = 0x1005 -> http://msdn.microsoft.com/en-us/library/bb774953(v=vs.85).aspx
Static OffGroupID := 28 + (A_PtrSize * 3)
this.LVITEM(LVITEM, 0x00000100, Row) ; LVIF_GROUPID
SendMessage 0x1005, 0, &LVITEM, , "ahk_id " . this.LVHwnd
Return NumGet(LVITEM, OffGroupID, "UPtr")
}
; ======================================================================================================================
; LV_EX_GroupGetHeader - Gets the header text of a group by group ID
; ======================================================================================================================
GroupGetHeader(GroupID, MaxChars := 1024)
{
; LVM_GETGROUPINFO = 0x1095
Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
Static LVGF_HEADER := 0x00000001
Static OffHeader := 8
Static OffHeaderMax := 8 + A_PtrSize
VarSetCapacity(HeaderText, MaxChars * 2, 0)
VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
NumPut(LVGF_HEADER, LVGROUP, 4, "UInt")
NumPut(&HeaderText, LVGROUP, OffHeader, "Ptr")
NumPut(MaxChars, LVGROUP, OffHeaderMax, "Int")
SendMessage 0x1095, GroupID, &LVGROUP, , "ahk_id " . HLV
Return StrGet(&HeaderText, MaxChars, "UTF-16")
}
; ======================================================================================================================
; LV_EX_GroupGetState - Get group states (requires Win Vista+ for most states).
; ======================================================================================================================
GroupGetState(GroupID, ByRef Collapsed := "", ByRef Collapsible := "", ByRef Focused := "", ByRef Hidden := ""
, ByRef NoHeader := "", ByRef Normal := "", ByRef Selected := "")
{
; LVM_GETGROUPINFO = 0x1095 -> msdn.microsoft.com/en-us/library/bb774932(v=vs.85).aspx
Static OS := DllCall("GetVersion", "UChar")
Static LVGS5 := {Collapsed: 0x01, Hidden: 0x02, Normal: 0x00}
Static LVGS6 := {Collapsed: 0x01, Collapsible: 0x08, Focused: 0x10, Hidden: 0x02, NoHeader: 0x04, Normal: 0x00, Selected: 0x20}
Static LVGF := 0x04 ; LVGF_STATE
Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
Static OffStateMask := 8 + (A_PtrSize * 3) + 8
Static OffState := OffStateMask + 4
SetStates := 0
LVGS := OS > 5 ? LVGS6 : LVGS5
For Each, State In LVGS
SetStates |= State
VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
NumPut(LVGF, LVGROUP, 4, "UInt")
NumPut(SetStates, LVGROUP, OffStateMask, "UInt")
SendMessage 0x1095, GroupID, &LVGROUP, , "ahk_id " . this.LVHwnd
States := NumGet(&LVGROUP, OffState, "UInt")
For Each, State in LVGS
%Each% := States & State ? True : False
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupInsert - Inserts a group into a list-view control.
; ======================================================================================================================
GroupInsert(GroupID, Header, Align := "", Index := -1)
{
; LVM_INSERTGROUP = 0x1091 -> msdn.microsoft.com/en-us/library/bb761103(v=vs.85).aspx
Static Alignment := {1: 1, 2: 2, 4: 4, C: 2, L: 1, R: 4}
Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
Static OffHeader := 8
Static OffGroupID := OffHeader + (A_PtrSize * 3) + 4
Static OffAlign := OffGroupID + 12
Static LVGF := 0x11 ; LVGF_GROUPID | LVGF_HEADER | LVGF_STATE
Static LVGF_ALIGN := 0x00000008
Align := (A := Alignment[SubStr(Align, 1, 1)]) ? A : 0
Mask := LVGF | (Align ? LVGF_ALIGN : 0)
PHeader := A_IsUnicode ? &Header : this.PWSTR(Header, WHeader)
VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
NumPut(Mask, LVGROUP, 4, "UInt")
NumPut(PHeader, LVGROUP, OffHeader, "Ptr")
NumPut(GroupID, LVGROUP, OffGroupID, "Int")
NumPut(Align, LVGROUP, OffAlign, "UInt")
SendMessage 0x1091, Index, &LVGROUP, , "ahk_id " . this.LVHwnd
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupRemove - Removes a group from a list-view control.
; ======================================================================================================================
GroupRemove(GroupID)
{
; LVM_REMOVEGROUP = 0x1096 -> msdn.microsoft.com/en-us/library/bb761149(v=vs.85).aspx
SendMessage 0x10A0, GroupID, 0, , "ahk_id " . this.LVHwnd
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupRemoveAll - Removes all groups from a list-view control.
; ======================================================================================================================
GroupRemoveAll()
{
; LVM_REMOVEALLGROUPS = 0x10A0 -> msdn.microsoft.com/en-us/library/bb761147(v=vs.85).aspx
SendMessage 0x10A0, 0, 0, , "ahk_id " . this.LVHwnd
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_GroupSetState - Sets the state of the specified group (requires Win Vista+ for most states).
; ======================================================================================================================
GroupSetState(GroupID, States*)
{
; LVM_SETGROUPINFO = 0x1093 -> msdn.microsoft.com/en-us/library/bb761167(v=vs.85).aspx
Static OS := DllCall("GetVersion", "UChar")
Static LVGS5 := {Collapsed: 0x01, Hidden: 0x02, Normal: 0x00, 0: 0, 1: 1, 2: 2}
Static LVGS6 := {Collapsed: 0x01, Collapsible: 0x08, Focused: 0x10, Hidden: 0x02, NoHeader: 0x04, Normal: 0x00
, Selected: 0x20, 0: 0, 1: 1, 2: 2, 4: 4, 8: 8, 16: 16, 32: 32}
Static LVGF := 0x04 ; LVGF_STATE
Static SizeOfLVGROUP := (4 * 6) + (A_PtrSize * 4)
Static OffStateMask := 8 + (A_PtrSize * 3) + 8
Static OffState := OffStateMask + 4
SetStates := 0
LVGS := OS > 5 ? LVGS6 : LVGS5
For Each, State In States {
If (State = "")
continue
If !LVGS.HasKey(State)
Return false
SetStates |= LVGS[State]
}
VarSetCapacity(LVGROUP, SizeOfLVGROUP, 0)
NumPut(SizeOfLVGROUP, LVGROUP, 0, "UInt")
NumPut(LVGF, LVGROUP, 4, "UInt")
NumPut(SetStates, LVGROUP, OffStateMask, "UInt")
NumPut(SetStates, LVGROUP, OffState, "UInt")
SendMessage 0x1093, GroupID, &LVGROUP, , "ahk_id " . this.LVHwnd
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_HasGroup - Determines whether the list-view control has a specified group.
; ======================================================================================================================
HasGroup(GroupID)
{
; LVM_HASGROUP = 0x10A1 -> msdn.microsoft.com/en-us/library/bb761097(v=vs.85).aspx
SendMessage 0x10A1, GroupID, 0, , "ahk_id " . this.LVHwnd
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_IsGroupViewEnabled - Checks whether the list-view control has group view enabled.
; ======================================================================================================================
IsGroupViewEnabled()
{
; LVM_ISGROUPVIEWENABLED = 0x10AF -> msdn.microsoft.com/en-us/library/bb761133(v=vs.85).aspx
SendMessage 0x10AF, 0, 0, , "ahk_id " . this.LVHwnd
Return ErrorLevel
}
; ======================================================================================================================
; LV_EX_SetGroup - Assigns a list-view item to an existing group.
; ======================================================================================================================
SetGroup(Row, GroupID)
{
; LVM_SETITEMA = 0x1006 -> http://msdn.microsoft.com/en-us/library/bb761186(v=vs.85).aspx
Static OffGroupID := 28 + (A_PtrSize * 3)
this.LVITEM(LVITEM, 0x00000100, Row) ; LVIF_GROUPID
NumPut(GroupID, LVITEM, OffGroupID, "UPtr")
SendMessage 0x1006, 0, &LVITEM, , "ahk_id " . this.LVHwnd
Return ErrorLevel
}
; ======================================================================================================================
; ======================================================================================================================
; Function for internal use ============================================================================================
; ======================================================================================================================
; ======================================================================================================================
LVITEM(ByRef LVITEM, Mask := 0, Row := 1, Col := 1)
{
Static LVITEMSize := 48 + (A_PtrSize * 3)
VarSetCapacity(LVITEM, LVITEMSize, 0)
NumPut(Mask, LVITEM, 0, "UInt"), NumPut(Row - 1, LVITEM, 4, "Int"), NumPut(Col - 1, LVITEM, 8, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------
PWSTR(Str, ByRef WSTR)
{ ; ANSI to Unicode
VarSetCapacity(WSTR, StrPut(Str, "UTF-16") * 2, 0)
StrPut(Str, &WSTR, "UTF-16")
Return &WSTR
}
}
}
I want to use LV_Rows drag in ahkv2
Please help me
Code: Select all
#include Class_LV_Rows.ahk
Gui := GuiCreate()
LV := Gui.Add("ListView", "r20 w700 ", "Name|Size (KB)")
Loop Files, "c:\*.*"
LV.Add(, A_LoopFileName, A_LoopFileSizeKB)
LVHandle := New LV_Rows(LV,LV.hwnd)
Gui.Show
Gui.OnEvent("Close", "Gui_Close")
Gui_Close(){
ExitApp
}
OnMessage(0x200, "WM_MOUSEMOVE")
WM_MOUSEMOVE(wParam, lParam, msg, Hwnd) {
global
If (hwnd = LV.hwnd)
LVHandle.Drag()
}