[Listview] _ Change rows position/number/index Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User
Posts: 407
Joined: 26 Jun 2017, 08:12

[Listview] _ Change rows position/number/index

05 Jul 2018, 00:51

Hi,

is it possible to change Listview rows position/number/index through listview built-in funtions, guicontrol or control commands?

(Obs): I don't want to use the delete/re-insert row method!

Right now I'm using the workaround below, but if there is a better way to do the same thing, please post here!
95_ Ternary Operator _ +0.5 and -0.5 in use (no Bug).gif
95_ Ternary Operator _ +0.5 and -0.5 in use (no Bug).gif (753.7 KiB) Viewed 2441 times

Code: Select all

count := 20

gui, add, text, , - Select a row and press "F12" to edit its "Id" `n       or `n- Select a row, then "Left click" it againt to edit its "Id" 

gui, add, listview, h400 BackgroundWhite Grid -ReadOnly gLVLAbel checked, Id|Test

ImageListID := IL_Create(10)  ; Create an ImageList to hold 10 small icons.

LV_SetImageList(ImageListID)  ; Assign the above ImageList to the current ListView.

Loop 10  ; Load the ImageList with a series of icons from the DLL.
    IL_Add(ImageListID, "shell32.dll", A_Index) 

Loop 10  ; Add rows to the ListView (for demonstration purposes, one for each icon).
    LV_Add("Icon" . A_Index, A_Index, count++)

loop, 2
LV_ModifyCol(a_index, "70")  ;width 70

gui, show

return

LVLAbel:	;____________________ Listview Events _______________

if (A_GuiEvent = "e")		;e (lowercase E): The user has finished editing the first field of a row
{
LV_GetText(UserInput, A_EventInfo, 1)
;"A_EventInfo" contains the row number that the user has finished editing the first field
;"1" is the column number

	if (InStr(UserInput, ".") = 0)			;if "UserInput" does not contain "." (a dot character), so it is an integer number
	{
	UserInput := A_EventInfo < UserInput ? UserInput + 0.5 : A_EventInfo > UserInput ? UserInput - 0.5 : UserInput
	;Ternary operator, (? = if) and (: = else)
	;"A_EventInfo" contains the row number that the user has finished editing the first field
	;if EditedtRow < UserInput, UserInput = UserInput + 0.5, else, if EditedtRow > UserInput, UserInput = UserInput - 0.5, else, UserInput = UserInput

	LV_Modify(A_EventInfo, "Col1", UserInput)
	}

	;msgbox, % "Wait: " A_EventInfo " - " UserInput

LV_ModifyCol(1, "Sort Float left")
;"1" column 1
;"Sort", Immediately sorts the column in ascending order (even if it has the Desc option).
;"Float" For sorting purposes, indicates that this column contains floating point numbers (hexadecimal format is not supported). Sorting performance for Float and Text columns is up to 25 times slower than it is for integers.
;"Integer" sorting instead "Float" sort prove to be buggy (not accurate)
;"Left", Left-justifies the column's text


;Update rows index numbers
loop, % LV_GetCount()			;the function returns the total number of rows in the control
LV_Modify(a_index, "Col1", a_index)
}

return


guiclose:	;____________________ gui close ___________________
exitapp
Old Example
Last edited by User on 09 Jul 2018, 17:12, edited 3 times in total.
User avatar
TheDewd
Posts: 1513
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Listview] _ Change rows position/number/index

06 Jul 2018, 12:50

Here's what I used in another project:

Code: Select all

#SingleInstance, Force

Gui, Margin, 10, 10
Gui, Add, ListView, w600 r14, Col1|Col2|Col3

; Add test data
Loop, 20 {
	LV_Add("", A_Index, "Test TEST test", "Test TEST test")
}

; Auto-size columns to fit data
Loop, % LV_GetCount("Col") {
	LV_ModifyCol(A_Index, "AutoHdr")
}

Gui, Add, Button, xm y+10 w100 h28 gMoveUp, Up
Gui, Add, Button, x+10 yp w100 h28 gMoveDown, Down

Gui, Show, AutoSize, Example
return


MoveUp:
	LVMoveRow()
return

MoveDown:
	LVMoveRow(false)
return

LVMoveRow(Up := True) {
    CO := [], TO := [], F := LV_GetNext("F"), N := F + (Up ? -1 : 1)

    If (!N) || (N > LV_GetCount()) || (!F) {
        return
    }

    Loop, % LV_GetCount("Col") {
        LV_GetText(CT, F, A_Index), LV_GetText(TT, N, A_Index), CO.Push(CT), TO.Push(TT)
    }

    Loop, % CO.MaxIndex() {
        LV_Modify(F, "Col" A_Index, TO[A_Index]), LV_Modify(N, "Col" A_Index, CO[A_Index])
    }

    LV_Modify(F, "-Select"), LV_Modify(N, "Select")
}
User avatar
divanebaba
Posts: 813
Joined: 20 Dec 2016, 03:53
Location: Diaspora

Re: [Listview] _ Change rows position/number/index

06 Jul 2018, 16:17

TheDewd wrote:Here's what I used in another project: ...
Hi.
This code is fantastic. I'm using ListViews all time and your coded job is 250%, what I need too.
Your code looks so pretty, if I were the boss here, I would take this code into official tutorial.
Now I am able to sort ListViews without coding me to death before :mrgreen: :mrgreen:

Sometimes, Google translator gives not real good suggestion. Before I write something wrong, here the german original thought. :crazy:
(Nun bin ich der Lage, ListView's zu sortieren, ohne mich zuvor zu Tode programmiert zu haben.)
Einfach nur ein toller Typ. :mrgreen:
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: [Listview] _ Change rows position/number/index

06 Jul 2018, 17:49

TheDewd wrote:@TheDewd
Thanks for your code, but I wanted something more editable, like for example, move row number 600 to position 400 (so I don't have to click move up/down buttons multiple times!)

And by using your code, checkboxes/Icons/etc are not moved with their correspondent rows!

Your function:
Move Row - TheDewd().gif
Move Row - TheDewd().gif (451.04 KiB) Viewed 2506 times

Code: Select all

#SingleInstance, Force

count := 20

Gui, Add, ListView, h200 w180 checked, Icon & Number|Description

ImageListID := IL_Create(10)  ; Create an ImageList to hold 10 small icons.

LV_SetImageList(ImageListID)  ; Assign the above ImageList to the current ListView.

Loop 10  ; Load the ImageList with a series of icons from the DLL.
    IL_Add(ImageListID, "shell32.dll", A_Index) 

Loop 10  ; Add rows to the ListView (for demonstration purposes, one for each icon).
    LV_Add("Icon" . A_Index, A_Index, count++)

LV_ModifyCol("Hdr")  ; Auto-adjust the column widths.

Gui, Add, Button, xm y+10 w100 h28 gMoveUp, Up
Gui, Add, Button, x+10 yp w100 h28 gMoveDown, Down

Gui, Show, AutoSize, Example
return

guiclose:
exitapp
return

MoveUp:
	LVMoveRow()
return

MoveDown:
	LVMoveRow(false)
return

LVMoveRow(Up := True) {
    CO := [], TO := [], F := LV_GetNext("F"), N := F + (Up ? -1 : 1)

    If (!N) || (N > LV_GetCount()) || (!F) {
        return
    }

    Loop, % LV_GetCount("Col") {
        LV_GetText(CT, F, A_Index), LV_GetText(TT, N, A_Index), CO.Push(CT), TO.Push(TT)
    }

    Loop, % CO.MaxIndex() {
        LV_Modify(F, "Col" A_Index, TO[A_Index]), LV_Modify(N, "Col" A_Index, CO[A_Index])
    }

    LV_Modify(F, "-Select"), LV_Modify(N, "Select")
	guicontrol, focus, % A_DefaultListView
}
my example:
Change rows position or number or index _96_ Float Sort (No Bug).gif
Change rows position or number or index _96_ Float Sort (No Bug).gif (386.2 KiB) Viewed 2506 times
Last edited by User on 09 Jul 2018, 19:51, edited 1 time in total.
just me
Posts: 9490
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [Listview] _ Change rows position/number/index

09 Jul 2018, 06:25

User wrote:... is it possible to change Listview rows position/number/index through listview built-in funtions, guicontrol or control commands?
No.
(Obs): I don't want to use the delete/re-insert row method!
What about the 'insert-then-delete-row' method (of course not using the built-in LV functions)?
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: [Listview] _ Change rows position/number/index

09 Jul 2018, 18:52

just me wrote:What about the 'insert-then-delete-row' method (of course not using the built-in LV functions)?
"Delete-then-Insert" or "Insert-then-Delete", they seem to be the same thing to me, but anyway, if you have such a function and want to share it here, feel free to do it so I can test it!

I updated the main thread post with a new and better code! Now it works the way I want:

Lets say I want to move row 4 to row position 9, all I have to do is edit the first field of row 4 to 9! (the otherwise is valid too!)

Lets say I want to move row 4 and place it between row 8 and 9, but then I don't know if I should edit the first field of row 4 to 8 or 9? Simple, I just edit the first field of row 4 to 8.5 and row 4 will be placed between row 8 and row 9!

I used "Ternary Operator" which really simplified the process!
- if user input value is a float number, nothing is added or subtracted, the value remains the same!
- If user Input value is an integer number, the ternary operator will decide if it adds or subtract 0.5 to the user input value or just keep it the same!
just me
Posts: 9490
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [Listview] _ Change rows position/number/index

11 Jul 2018, 05:57

Code: Select all

; ================================================================================================================================
; LV_MoveRow
; Moves a complete row within an own ListView control.
;     HLV            -  the handle to the ListView
;     RowNumber      -  the number of the row to be moved
;     InsertBefore   -  the number of the row to insert the moved row before
;     MaxTextLength  -  maximum length of item/subitem text being retrieved
; Returns the new row number of the moved row on success, otherwise zero (False).
; ================================================================================================================================
LV_MoveRow(HLV, RowNumber, InsertBefore, MaxTextLength := 257) {
   Static LVM_GETITEM := A_IsUnicode ? 0x104B : 0x1005
   Static LVM_INSERTITEM := A_IsUnicode ? 0x104D : 0x1007
   Static LVM_SETITEM := A_IsUnicode ? 0x104C : 0x1006
   Static OffMask := 0
        , OffItem := OffMask + 4
        , OffSubItem := OffItem + 4
        , OffState := OffSubItem + 4
        , OffStateMask := OffState + 4
        , OffText := OffStateMask + A_PtrSize
        , OffTextLen := OffText + A_PtrSize
   ; Some checks -----------------------------------------------------------------------------------------------------------------
   If (RowNumber = InsertBefore)
      Return True
   Rows := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1004, "Ptr", 0, "Ptr", 0, "Int") ; LVM_GETITEMCOUNT
   If (RowNumber < 1) || (InsertBefore < 1) || (RowNumber > Rows)
      Return False
   ; Move it, if possible --------------------------------------------------------------------------------------------------------
   GuiControl, -Redraw, %HLV%
   HHD := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x101F, "Ptr", 0, "Ptr", 0, "UPtr") ; LVM_GETHEADER
   Columns := DllCall("SendMessage", "Ptr", HHD, "UInt", 0x1200, "Ptr", 0, "Ptr", 0, "Int") ; HDM_GETITEMCOUNT
   Item := RowNumber - 1
   StructSize := 88 + (MaxTextLength << !!A_IsUnicode)
   VarSetCapacity(LVITEM, StructSize, 0)
   NumPut(0x01031F, LVITEM, OffMask, "UInt") ; might need to be adjusted for Win XP/Vista
   NumPut(Item, LVITEM, OffItem, "Int")
   NumPut(-1, LVITEM, OffStateMask, "UInt")
   NumPut(&LVITEM + 88, LVITEM, OffText, "Ptr")
   NumPut(MaxTextLength, LVITEM, OffTextLen, "Int")
   If !DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_GETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
      Return False
   NumPut(InsertBefore - 1, LVITEM, OffItem, "Int")
   NewItem := DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_INSERTITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
   If (NewItem = -1)
      Return False
   DllCall("SendMessage", "Ptr", HLV, "UInt", 0x102B, "Ptr", NewItem, "Ptr", &LVITEM) ; LVM_SETITEMSTATE
   If (InsertBefore <= RowNumber)
      Item++
   VarSetCapacity(LVITEM, StructSize, 0) ; reinitialize
   Loop, %Columns% {
      NumPut(0x03, LVITEM, OffMask, "UInt")
      NumPut(Item, LVITEM, OffItem, "Int")
      NumPut(A_Index, LVITEM, OffSubItem, "Int")
      NumPut(&LVITEM + 88, LVITEM, OffText, "Ptr")
      NumPut(MaxTextLength, LVITEM, OffTextLen, "Int")
      If !DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_GETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
         Return False
      NumPut(NewItem, LVITEM, OffItem, "Int")
      DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_SETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
   }
   Result := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1008, "Ptr", Item, "Ptr", 0) ; LVM_DELETEITEM
   GuiControl, +Redraw, %HLV%
   Return (Result ? (NewItem + 1) : 0)
}
Might fail with LV groups. I didn't test that.
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: [Listview] _ Change rows position/number/index

11 Jul 2018, 10:15

just me wrote:.
Nice function, but I noticed a little problem!

Examples:
If I want to move row 2 to position 5, your function will place row 2 in position 4!
If I want to move row 2 to position 7, your function will place row 2 in position 6!
If I want to move row 2 to position 10, your function will place row 2 in position 9!

Image

Code: Select all

count := 20

gui, add, text, , - Select a row and press "F12" to edit its "Id" `n       or `n- Select a row, then "Left click" it againt to edit its "Id" 

gui, add, listview, h400 BackgroundWhite Grid -ReadOnly gLVLAbel checked +HwndTableId, Id|Test

ImageListID := IL_Create(10)  ; Create an ImageList to hold 10 small icons.

LV_SetImageList(ImageListID)  ; Assign the above ImageList to the current ListView.

Loop 10  ; Load the ImageList with a series of icons from the DLL.
    IL_Add(ImageListID, "shell32.dll", A_Index) 

Loop 10  ; Add rows to the ListView (for demonstration purposes, one for each icon).
    LV_Add("Icon" . A_Index, A_Index, count++)

loop, 2
LV_ModifyCol(a_index, "70")  ;width 70

gui, show

return

LVLAbel:	;____________________ Listview Events _______________

if (A_GuiEvent = "e")		;e (lowercase E): The user has finished editing the first field of a row
{
LV_GetText(UserInput, A_EventInfo, 1)
;"A_EventInfo" contains the row number that the user has finished editing the first field
;"1" is the column number

LV_MoveRow(TableId, A_EventInfo, UserInput)
;"A_EventInfo" contains the row number that the user has finished editing the first field

;Update rows index numbers
loop, % LV_GetCount()			;the function returns the total number of rows in the control
LV_Modify(a_index, "Col1", a_index)
}

return


guiclose:	;____________________ gui close ___________________
exitapp



; ================================================================================================================================
; LV_MoveRow
; Moves a complete row within an own ListView control.
;     HLV            -  the handle to the ListView
;     RowNumber      -  the number of the row to be moved
;     InsertBefore   -  the number of the row to insert the moved row before
;     MaxTextLength  -  maximum length of item/subitem text being retrieved
; Returns the new row number of the moved row on success, otherwise zero (False).
; ================================================================================================================================
LV_MoveRow(HLV, RowNumber, InsertBefore, MaxTextLength := 257) {
   Static LVM_GETITEM := A_IsUnicode ? 0x104B : 0x1005
   Static LVM_INSERTITEM := A_IsUnicode ? 0x104D : 0x1007
   Static LVM_SETITEM := A_IsUnicode ? 0x104C : 0x1006
   Static OffMask := 0
        , OffItem := OffMask + 4
        , OffSubItem := OffItem + 4
        , OffState := OffSubItem + 4
        , OffStateMask := OffState + 4
        , OffText := OffStateMask + A_PtrSize
        , OffTextLen := OffText + A_PtrSize
   ; Some checks -----------------------------------------------------------------------------------------------------------------
   If (RowNumber = InsertBefore)
      Return True
   Rows := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1004, "Ptr", 0, "Ptr", 0, "Int") ; LVM_GETITEMCOUNT
   If (RowNumber < 1) || (InsertBefore < 1) || (RowNumber > Rows)
      Return False
   ; Move it, if possible --------------------------------------------------------------------------------------------------------
   GuiControl, -Redraw, %HLV%
   HHD := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x101F, "Ptr", 0, "Ptr", 0, "UPtr") ; LVM_GETHEADER
   Columns := DllCall("SendMessage", "Ptr", HHD, "UInt", 0x1200, "Ptr", 0, "Ptr", 0, "Int") ; HDM_GETITEMCOUNT
   Item := RowNumber - 1
   StructSize := 88 + (MaxTextLength << !!A_IsUnicode)
   VarSetCapacity(LVITEM, StructSize, 0)
   NumPut(0x01031F, LVITEM, OffMask, "UInt") ; might need to be adjusted for Win XP/Vista
   NumPut(Item, LVITEM, OffItem, "Int")
   NumPut(-1, LVITEM, OffStateMask, "UInt")
   NumPut(&LVITEM + 88, LVITEM, OffText, "Ptr")
   NumPut(MaxTextLength, LVITEM, OffTextLen, "Int")
   If !DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_GETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
      Return False
   NumPut(InsertBefore - 1, LVITEM, OffItem, "Int")
   NewItem := DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_INSERTITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
   If (NewItem = -1)
      Return False
   DllCall("SendMessage", "Ptr", HLV, "UInt", 0x102B, "Ptr", NewItem, "Ptr", &LVITEM) ; LVM_SETITEMSTATE
   If (InsertBefore <= RowNumber)
      Item++
   VarSetCapacity(LVITEM, StructSize, 0) ; reinitialize
   Loop, %Columns% {
      NumPut(0x03, LVITEM, OffMask, "UInt")
      NumPut(Item, LVITEM, OffItem, "Int")
      NumPut(A_Index, LVITEM, OffSubItem, "Int")
      NumPut(&LVITEM + 88, LVITEM, OffText, "Ptr")
      NumPut(MaxTextLength, LVITEM, OffTextLen, "Int")
      If !DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_GETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
         Return False
      NumPut(NewItem, LVITEM, OffItem, "Int")
      DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_SETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
   }
   Result := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1008, "Ptr", Item, "Ptr", 0) ; LVM_DELETEITEM
   GuiControl, +Redraw, %HLV%
   Return (Result ? (NewItem + 1) : 0)
}
just me
Posts: 9490
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: [Listview] _ Change rows position/number/index

11 Jul 2018, 11:20

I don't see the problem, the function does what it has been told to do:

Code: Select all

;     InsertBefore   -  the number of the row to insert the moved row before
If you move row 2 to row 10, a new row 10 will be inserted before the current row 10. After that row 2 will be deleted. So the inserted row 10 will become row 9.
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: [Listview] _ Change rows position/number/index

11 Jul 2018, 11:55

just me wrote:I don't see the problem, the function does what it has been told to do
The problem I mentioned is not related to "what the function has been told to do", but, it is related to "what I would want it to do"!

But anyway, it's still a nice function! Thanks for sharing it!
User avatar
TheDewd
Posts: 1513
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Listview] _ Change rows position/number/index

11 Jul 2018, 14:56

User wrote:The problem I mentioned is not related to "what the function has been told to do", but, it is related to "what I would want it to do"!
Try changing the following:

LV_MoveRow(TableId, A_EventInfo, UserInput)

to

LV_MoveRow(TableId, A_EventInfo, (UserInput > A_EventInfo ? UserInput + 1 : UserInput))

Does it do what you need now?
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: [Listview] _ Change rows position/number/index  Topic is solved

11 Jul 2018, 22:36

TheDewd wrote: LV_MoveRow(TableId, A_EventInfo, (UserInput > A_EventInfo ? UserInput + 1 : UserInput))
Yes it does! (Although it does not support Float numbers as we can see in the example from this thread main post!)

just me - LV_MoveRow(Function)

Code: Select all

count := 20

gui, add, text, , - Select a row and press "F12" to edit its "Id" `n       or `n- Select a row, then "Left click" it againt to edit its "Id" 

gui, add, listview, h400 BackgroundWhite Grid -ReadOnly gLVLAbel checked +HwndTableId, Id|Test

ImageListID := IL_Create(10)  ; Create an ImageList to hold 10 small icons.

LV_SetImageList(ImageListID)  ; Assign the above ImageList to the current ListView.

Loop 10  ; Load the ImageList with a series of icons from the DLL.
    IL_Add(ImageListID, "shell32.dll", A_Index) 

Loop 10  ; Add rows to the ListView (for demonstration purposes, one for each icon).
    LV_Add("Icon" . A_Index, A_Index, count++)

loop, 2
LV_ModifyCol(a_index, "70")  ;width 70

gui, show

return

LVLAbel:	;____________________ Listview Events _______________

if (A_GuiEvent = "e")		;e (lowercase E): The user has finished editing the first field of a row
{
LV_GetText(UserInput, A_EventInfo, 1)
;"A_EventInfo" contains the row number that the user has finished editing the first field
;"1" is the column number

LV_MoveRow(TableId, A_EventInfo, UserInput > A_EventInfo ? UserInput + 1 : UserInput)
;"A_EventInfo" contains the row number that the user has finished editing the first field

;Update rows index numbers
loop, % LV_GetCount()			;the function returns the total number of rows in the control
LV_Modify(a_index, "Col1", a_index)
}

return


guiclose:	;____________________ gui close ___________________
exitapp



; ================================================================================================================================
; LV_MoveRow
; Moves a complete row within an own ListView control.
;     HLV            -  the handle to the ListView
;     RowNumber      -  the number of the row to be moved
;     InsertBefore   -  the number of the row to insert the moved row before
;     MaxTextLength  -  maximum length of item/subitem text being retrieved
; Returns the new row number of the moved row on success, otherwise zero (False).
; ================================================================================================================================
LV_MoveRow(HLV, RowNumber, InsertBefore, MaxTextLength := 257) {
   Static LVM_GETITEM := A_IsUnicode ? 0x104B : 0x1005
   Static LVM_INSERTITEM := A_IsUnicode ? 0x104D : 0x1007
   Static LVM_SETITEM := A_IsUnicode ? 0x104C : 0x1006
   Static OffMask := 0
        , OffItem := OffMask + 4
        , OffSubItem := OffItem + 4
        , OffState := OffSubItem + 4
        , OffStateMask := OffState + 4
        , OffText := OffStateMask + A_PtrSize
        , OffTextLen := OffText + A_PtrSize
   ; Some checks -----------------------------------------------------------------------------------------------------------------
   If (RowNumber = InsertBefore)
      Return True
   Rows := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1004, "Ptr", 0, "Ptr", 0, "Int") ; LVM_GETITEMCOUNT
   If (RowNumber < 1) || (InsertBefore < 1) || (RowNumber > Rows)
      Return False
   ; Move it, if possible --------------------------------------------------------------------------------------------------------
   GuiControl, -Redraw, %HLV%
   HHD := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x101F, "Ptr", 0, "Ptr", 0, "UPtr") ; LVM_GETHEADER
   Columns := DllCall("SendMessage", "Ptr", HHD, "UInt", 0x1200, "Ptr", 0, "Ptr", 0, "Int") ; HDM_GETITEMCOUNT
   Item := RowNumber - 1
   StructSize := 88 + (MaxTextLength << !!A_IsUnicode)
   VarSetCapacity(LVITEM, StructSize, 0)
   NumPut(0x01031F, LVITEM, OffMask, "UInt") ; might need to be adjusted for Win XP/Vista
   NumPut(Item, LVITEM, OffItem, "Int")
   NumPut(-1, LVITEM, OffStateMask, "UInt")
   NumPut(&LVITEM + 88, LVITEM, OffText, "Ptr")
   NumPut(MaxTextLength, LVITEM, OffTextLen, "Int")
   If !DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_GETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
      Return False
   NumPut(InsertBefore - 1, LVITEM, OffItem, "Int")
   NewItem := DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_INSERTITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
   If (NewItem = -1)
      Return False
   DllCall("SendMessage", "Ptr", HLV, "UInt", 0x102B, "Ptr", NewItem, "Ptr", &LVITEM) ; LVM_SETITEMSTATE
   If (InsertBefore <= RowNumber)
      Item++
   VarSetCapacity(LVITEM, StructSize, 0) ; reinitialize
   Loop, %Columns% {
      NumPut(0x03, LVITEM, OffMask, "UInt")
      NumPut(Item, LVITEM, OffItem, "Int")
      NumPut(A_Index, LVITEM, OffSubItem, "Int")
      NumPut(&LVITEM + 88, LVITEM, OffText, "Ptr")
      NumPut(MaxTextLength, LVITEM, OffTextLen, "Int")
      If !DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_GETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
         Return False
      NumPut(NewItem, LVITEM, OffItem, "Int")
      DllCall("SendMessage", "Ptr", HLV, "UInt", LVM_SETITEM, "Ptr", 0, "Ptr", &LVITEM, "Int")
   }
   Result := DllCall("SendMessage", "Ptr", HLV, "UInt", 0x1008, "Ptr", Item, "Ptr", 0) ; LVM_DELETEITEM
   GuiControl, +Redraw, %HLV%
   Return (Result ? (NewItem + 1) : 0)
}
I will mark this as solved! Thanks guys!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Mycroft-47, Rohwedder and 161 guests