Mithrandir Posted July 16, 2012 Posted July 16, 2012 (edited) 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: expandcollapse popup#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 July 16, 2012 by Mithrandir Help with SOAP message!!
PhoenixXL Posted July 16, 2012 Posted July 16, 2012 (edited) This may helpexpandcollapse popup#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 July 16, 2012 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.
Mithrandir Posted July 16, 2012 Author Posted July 16, 2012 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 Help with SOAP message!!
BrewManNH Posted July 16, 2012 Posted July 16, 2012 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. expandcollapse popup#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 GudeHow 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
Quual Posted July 16, 2012 Posted July 16, 2012 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.
Mithrandir Posted July 18, 2012 Author Posted July 18, 2012 (edited) 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. expandcollapse popupFunc _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 July 18, 2012 by Mithrandir Help with SOAP message!!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now