Jump to content

Recommended Posts

First of all, I am starting with GUIs but reading examples from the helpfile as well as the forum I made an script in which I have a listview that is going to be populated with user input and sorted at any given moment. When I sort it by the first or second column with the data that was already set when starting the script (1|D,2|C,4|A,3|D ) It sorts correctly but when I add a new element it doesn't sort it right, it seems it dismisses the new entered data. Here is a small example of my code to show the issue:

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

$Form1_1 = GUICreate("Form1", 969, 569, 209, 134)

$ListView1 = GUICtrlCreateListView("Col1|Col2", 32, 128, 353, 321, -1, $LVS_EX_CHECKBOXES)
_GUICtrlListView_RegisterSortCallBack($ListView1)

GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 115)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 115)
$ListView1_0 = GUICtrlCreateListViewItem("1|D", $ListView1)
$ListView1_1 = GUICtrlCreateListViewItem("2|C", $ListView1)
$ListView1_2 = GUICtrlCreateListViewItem("4|A", $ListView1)
$ListView1_3 = GUICtrlCreateListViewItem("3|B", $ListView1)

$bElim = GUICtrlCreateButton("Delete element(s)", 176, 464, 201, 25)
$elem = GUICtrlCreateInput("Element", 88, 16, 241, 21)
$bAdd = GUICtrlCreateButton("Add letter", 112, 48, 201, 33)
GUISetState(@SW_SHOW)

While 1
         $nMsg = GUIGetMsg()
         Switch $nMsg
             Case $GUI_EVENT_CLOSE
                     _GUICtrlListView_UnRegisterSortCallBack($ListView1)
                         Exit
             Case $ListView1
                     _GUICtrlListView_SortItems($ListView1, GUICtrlGetState($ListView1))

             Case $bElim
                     $i = 0
                     $cantitems = _GUICtrlListView_GetItemCount(GUICtrlGetHandle($ListView1))
                     While $i <= $cantitems
                                 If _GUICtrlListView_GetItemChecked(GUICtrlGetHandle($ListView1), $i) Then
                                         _GUICtrlListView_DeleteItem(GUICtrlGetHandle($ListView1), $i)
                                 Else
                                         $i += 1
                                 EndIf
                     WEnd
             Case $bAdd
                         $number = Random(0, 100, 1)
                         $handlelista = GUICtrlGetHandle($ListView1)
                         _GUICtrlListView_AddItem($handlelista, $number)
         _GUICtrlListView_AddSubItem($handlelista, _GUICtrlListView_GetItemCount(GUICtrlGetHandle($ListView1)) - 1, GUICtrlRead($elem), 1)

EndSwitch
WEnd

Note that if you delete all the elements that are set after the script started and you add new ones, it doesn't sort them.

What's wrong? Thanks for your help!

Edited by Mithrandir
Link to comment
Share on other sites

This may help

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

$Form1_1 = GUICreate("Form1", 969, 569, 209, 134)

$ListView1 = GUICtrlCreateListView("Col1|Col2", 32, 128, 353, 321, -1, $LVS_EX_CHECKBOXES)
_GUICtrlListView_RegisterSortCallBack($ListView1)

GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 115)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 115)
$ListView1_0 = GUICtrlCreateListViewItem("1|D", $ListView1)
$ListView1_1 = GUICtrlCreateListViewItem("2|C", $ListView1)
$ListView1_2 = GUICtrlCreateListViewItem("4|A", $ListView1)
$ListView1_3 = GUICtrlCreateListViewItem("3|B", $ListView1)

$bElim = GUICtrlCreateButton("Delete element(s)", 176, 464, 201, 25)
$elem = GUICtrlCreateInput("Element", 88, 16, 241, 21)
$bAdd = GUICtrlCreateButton("Add letter", 112, 48, 201, 33)
GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
_GUICtrlListView_UnRegisterSortCallBack($ListView1)
Exit
Case $ListView1
_GUICtrlListView_SortItems($ListView1, GUICtrlGetState($ListView1))
Case $bElim
$i = 0
$cantitems = _GUICtrlListView_GetItemCount(GUICtrlGetHandle($ListView1))
While $i <= $cantitems
If _GUICtrlListView_GetItemChecked(GUICtrlGetHandle($ListView1), $i) Then
_GUICtrlListView_DeleteItem(GUICtrlGetHandle($ListView1), $i)
Else
$i += 1
EndIf
WEnd
Case $bAdd
$number = Random(0, 100, 1)
GUICtrlCreateListViewItem($number&Opt('GUIDataSeparatorChar')&GUICtrlRead($elem), $ListView1)
EndSwitch
WEnd

Edited by PhoenixXL

My code:

PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail.Ā StringRegExp:Share and learn RegExp.

Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners.

MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool.Ā 

Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead.Ā RestrictEdit_SRE:Ā Restrict text in an Edit Control through a Regular Expression.

Link to comment
Share on other sites

PhoenixXl: Thank you a lot! It's strange though that the functions from the UDF (_GUICtrlListView_AddItem,_GUICtrlListView_AddISubItem) didn't work and the native one (GUICtrlCreateListViewItem) has to be used when the sort function is from the UDF. So, I will look into mixing UDF functions with native ones when required in the future.

PS: If you happen to know about SOAP or webservices, I would appreciate your insights in

Link to comment
Share on other sites

If you need to sort items in a ListView and you're using the UDF functions to add the items, you need to add to the $iParam value. I usually use the Item number + 1000. I've modified your script below to show how it can work with the UDF functions.

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
$Form1_1 = GUICreate("Form1", 969, 569, 209, 134)
$ListView1 = GUICtrlCreateListView("Col1|Col2", 32, 128, 353, 321, -1, $LVS_EX_CHECKBOXES)
_GUICtrlListView_RegisterSortCallBack($ListView1)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 115)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 115)
$ListView1_0 = GUICtrlCreateListViewItem("1|D", $ListView1)
$ListView1_1 = GUICtrlCreateListViewItem("2|C", $ListView1)
$ListView1_2 = GUICtrlCreateListViewItem("4|A", $ListView1)
$ListView1_3 = GUICtrlCreateListViewItem("3|B", $ListView1)
$bElim = GUICtrlCreateButton("Delete element(s)", 176, 464, 201, 25)
$elem = GUICtrlCreateInput("Element", 88, 16, 241, 21)
$bAdd = GUICtrlCreateButton("Add letter", 112, 48, 201, 33)
GUISetState(@SW_SHOW)
$hListview = GUICtrlGetHandle($ListView1)
While 1
     $nMsg = GUIGetMsg()
     Switch $nMsg
          Case $GUI_EVENT_CLOSE
               _GUICtrlListView_UnRegisterSortCallBack($ListView1)
               Exit
          Case $ListView1
               _GUICtrlListView_SortItems($ListView1, GUICtrlGetState($ListView1))
          Case $bElim
               $i = 0
               $cantitems = _GUICtrlListView_GetItemCount($hListview)
               While $i <= $cantitems
                    If _GUICtrlListView_GetItemChecked($hListview, $i) Then
                         _GUICtrlListView_DeleteItem($hListview, $i)
                    Else
                         $i += 1
                    EndIf
               WEnd
          Case $bAdd
               $number = Random(0, 100, 1)
               $handlelista = $hListview
               _GUICtrlListView_AddItem($handlelista, $number, -1, _GUICtrlListView_GetItemCount($hListview)+ 1000 ) ;<<<<<<<<<<<<<< See this line
               _GUICtrlListView_AddSubItem($handlelista, _GUICtrlListView_GetItemCount($hListview) - 1, GUICtrlRead($elem), 1)
     EndSwitch
WEnd

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. Ā - Ā ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. Ā - Ā Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. Ā - Ā _FileGetProperty - Retrieve the properties of a file Ā - Ā SciTE Toolbar - A toolbar demo for use with the SciTE editor Ā - Ā GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. Ā - Ā Ā Latin Square password generator

Link to comment
Share on other sites

This info helped me solve a problem of mine. I added a context menu to a listview., it worked for the first three listviewitems, the fourth item would replace the context menu with a null menu, the fifth item replaced it with the main menu bar's file menu. Almost gave up on the problem it seemed so bizarre.

Not setting an $iParam value fixed the context menu problem, but broke the column sorting feature.

Simply changing the $iParam value from the item number to the item number + 1000 was the fix. Now I can have both the context menu and sortable columns.

My add or update a ListViewItem function.

Func AppGui_Lv_AddOrUpdateItem($sItemStr, $hLV, $iItem, $iImage = -1, $iCurrentId = -1)
    If Not StringInStr($sItemStr, '|') Then Return SetError(2)
    Local $iLvId, $vItems = StringSplit($sItemStr, '|', 2)
    If $iCurrentId = -1 Then
        ;$iLvId = _GUICtrlListView_AddItem($hLV, $vItems[0], $iImage, $iItem - 1)
        ;$iLvId = _GUICtrlListView_AddItem($hLV, $vItems[0], $iImage) ; fixed the context menu... and broke column sorting
        $iLvId = _GUICtrlListView_AddItem($hLV, $vItems[0], $iImage, $iItem + 1000) ; context menu and column sorting both work
        _GUICtrlListView_MapIndexToID($hLV, $iItem - 1)
        For $x = 1 To UBound($vItems) - 1
            If $vItems[$x] = '' Then $vItems[$x] = ' '
            _GUICtrlListView_AddSubItem($hLV, $iLvId, $vItems[$x], $x)
        Next
        _GUICtrlListView_SetItemIndent($hLV, $iLvId, 0)
    Else
        $iLvId = $iCurrentId
        _GUICtrlListView_SetItemText($hLV, $iLvId, $vItems[0])
        For $x = 1 To UBound($vItems) - 1
            If $vItems[$x] = '' Then $vItems[$x] = ' '
            _GUICtrlListView_SetItemText($hLV, $iLvId, $vItems[$x], $x)
        Next
        If $iImage > -1 Then _GUICtrlListView_SetItemImage($hLV, $iLvId, $iImage)
    EndIf
EndFunc

Thanks for giving me the idea, wouldn't have thought of it by myself.

Link to comment
Share on other sites

If you need to sort items in a ListView and you're using the UDF functions to add the items, you need to add to the $iParam value. I usually use the Item number + 1000. I've modified your script below to show how it can work with the UDF functions.

Thank you BrewManNH, that also works. So, what's the meaning of that $IParam value? It is not documented except for the "Application defined data" which I donĀ“t know what it is. I have been looking at the source of GuiListView.au3 and I see that _GUICtrlListView_AddItem actually returns _GUICtrlListView_InsertItem in which $IParam is used in DllStructSetData($tItem, "Param", $iParam) but I still don't get the use of it or why leaving $IParam as default gives trouble.

Func _GUICtrlListView_InsertItem($hWnd, $sText, $iIndex = -1, $iImage = -1, $iParam = 0)
If $Debug_LV Then __UDF_ValidateClassName($hWnd, $__LISTVIEWCONSTANT_ClassName)

Local $fUnicode = _GUICtrlListView_GetUnicodeFormat($hWnd)

Local $iBuffer, $tBuffer, $iRet
If $iIndex = -1 Then $iIndex = 999999999

Local $tItem = DllStructCreate($tagLVITEM)
DllStructSetData($tItem, "Param", $iParam)
If $sText <> -1 Then
$iBuffer = StringLen($sText) + 1
If $fUnicode Then
$tBuffer = DllStructCreate("wchar Text[" & $iBuffer & "]")
$iBuffer *= 2
Else
$tBuffer = DllStructCreate("char Text[" & $iBuffer & "]")
EndIf
DllStructSetData($tBuffer, "Text", $sText)
DllStructSetData($tItem, "Text", DllStructGetPtr($tBuffer))
DllStructSetData($tItem, "TextMax", $iBuffer)
Else
DllStructSetData($tItem, "Text", -1)
EndIf
Local $iMask = BitOR($LVIF_TEXT, $LVIF_PARAM)
If $iImage >= 0 Then $iMask = BitOR($iMask, $LVIF_IMAGE)
DllStructSetData($tItem, "Mask", $iMask)
DllStructSetData($tItem, "Item", $iIndex)
DllStructSetData($tItem, "Image", $iImage)
If IsHWnd($hWnd) Then
If _WinAPI_InProcess($hWnd, $_lv_ghLastWnd) Or ($sText = -1) Then
$iRet = _SendMessage($hWnd, $LVM_INSERTITEMW, 0, $tItem, 0, "wparam", "struct*")
Else
Local $iItem = DllStructGetSize($tItem)
Local $tMemMap
Local $pMemory = _MemInit($hWnd, $iItem + $iBuffer, $tMemMap)
Local $pText = $pMemory + $iItem
DllStructSetData($tItem, "Text", $pText)
_MemWrite($tMemMap, $tItem, $pMemory, $iItem)
_MemWrite($tMemMap, $tBuffer, $pText, $iBuffer)
If $fUnicode Then
$iRet = _SendMessage($hWnd, $LVM_INSERTITEMW, 0, $pMemory, 0, "wparam", "ptr")
Else
$iRet = _SendMessage($hWnd, $LVM_INSERTITEMA, 0, $pMemory, 0, "wparam", "ptr")
EndIf
_MemFree($tMemMap)
EndIf
Else
Local $pItem = DllStructGetPtr($tItem)
If $fUnicode Then
$iRet = GUICtrlSendMsg($hWnd, $LVM_INSERTITEMW, 0, $pItem)
Else
$iRet = GUICtrlSendMsg($hWnd, $LVM_INSERTITEMA, 0, $pItem)
EndIf
EndIf
Return $iRet
EndFunc ;==>_GUICtrlListView_InsertItem

EDIT: I think some of the answers to my doubts are in this post:

Quual: It's great to see that the answer to one question can be the answer of another one :)

Edited by Mithrandir
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...