someone Posted April 27, 2009 Share Posted April 27, 2009 Hey everyone, I have a listview I am sorting when the user clicks on the header, and everything is working OK except I would love a way to know what column is sorted and how (ascending/descending). I'm using _GUICtrlListView_RegisterSortCallBack/_GUICtrlListView_SortItems. I do have code but its pretty large and I'm not sure it would help to show. Maybe there is a way to know which column/way the arrow is drawn with _RegisterSortCallBack? Not sure if that would be a different method than knowing what column is sorted though. Thanks for the help in advance. While ProcessExists('Andrews bad day.exe') BlockInput(1) SoundPlay('Music.wav') SoundSetWaveVolume('Louder') WEnd Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted April 27, 2009 Moderators Share Posted April 27, 2009 someone,I knew you could easily get the column value when using GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") and _GUICtrlListView_SimpleSort by using a Global variable:$tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam) $iColumn = DllStructGetData($tInfo, "SubItem")But in trying to find a solution to your problem I have discovered that this method will not work when using _GUICtrlListView_RegisterSortCallBack and _GUICtrlListView_SortItems, even though the WM_NOTIFY function is essentially the same. The $iColumn = DllStructGetData($tInfo, "SubItem") code still works within the function (because using the value obtained as a _GUICtrlListView_SortItems parameter works perfectly), but I cannot find any way of getting the value out of the function. It does not update a global variable, nor will it ConsoleWrite - it is as if there was something preventing the WM_NOTIFY function from having anything to do with the rest of the script when used with _GUICtrlListView_RegisterSortCallBack!I did try using both GUIRegisterMsg and _GUICtrlListView_RegisterSortCallBack in teh same script - I got the column index, but no sorting! :-(I am now at the edge of my (limited) knowledge of this area of AutoIt - perhaps one of the gurus could shed some light on this for us both.M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
picaxe Posted April 28, 2009 Share Posted April 28, 2009 I have a listview I am sorting when the user clicks on the header, and everything is working OK except I would love a way to know what column is sorted and how (ascending/descending). One way is to use a modified version of _GUICtrlListView_SortItems expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <File.au3> #include <WindowsConstants.au3> Global $iColumn, $sSortDirection $Gui = GUICreate("Test", 300, 200) $hListView = GUICtrlCreateListView("Items|SubItems", 2, 2, 296, 196, BitOR($LVS_EDITLABELS, $LVS_REPORT)) _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER )) $sItems ="Item9,44|Item2,22|Item1,11|Item2,33|Item3,|Item1,|Item2,|Item3,|Item1," $aFile = StringSplit($sItems, "|") $iSize = $aFile[0] Dim $result[$iSize][2] For $x = 1 To $iSize $aCol = StringSplit($aFile[$x], ",") $iIndex = _GUICtrlListView_AddItem($hListView, $aCol[1], -1, $x);_GUICtrlListView_GetItemCount($hListView)) For $y = 2 To $aCol[0] _GUICtrlListView_AddSubItem($hListView, $iIndex, $aCol[$y], $y - 1) Next Next GUISetState() _GUICtrlListView_RegisterSortCallBack($hListView) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $hListView ; use modified sort callback __GUICtrlListView_SortItems($hListView, GUICtrlGetState($hListView)) ConsoleWrite("Column: " & $iColumn & " Sort: " & $sSortDirection & @LF) EndSwitch WEnd _GUICtrlListView_UnRegisterSortCallBack($hListView) GUIDelete() ; modified sort call back from include GuiListView.au3 Func __GUICtrlListView_SortItems($hWnd, $iCol) Local $iResult, $iIndex, $pFunction, $hHeader, $iFormat If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) For $x = 1 To $aListViewSortInfo[0][0] If $hWnd = $aListViewSortInfo[$x][1] Then $iIndex = $x ExitLoop EndIf Next $pFunction = DllCallbackGetPtr($aListViewSortInfo[$iIndex][2]) ; get pointer to call back $aListViewSortInfo[$iIndex][3] = $iCol ; $nColumn = column clicked $aListViewSortInfo[$iIndex][7] = 0 ; $bSet $aListViewSortInfo[$iIndex][4] = $aListViewSortInfo[$iIndex][6] ; nCurCol = $nCol $iResult = _SendMessage($hWnd, $LVM_SORTITEMS, $hWnd, $pFunction, 0, "hwnd", "ptr") If $iResult <> 0 Then If $aListViewSortInfo[$iIndex][9] Then ; Use arrow in header $hHeader = $aListViewSortInfo[$iIndex][10] For $x = 0 To _GUICtrlHeader_GetItemCount($hHeader) - 1 $iFormat = _GUICtrlHeader_GetItemFormat($hHeader, $x) If BitAND($iFormat, $HDF_SORTDOWN) Then _GUICtrlHeader_SetItemFormat($hHeader, $x, BitXOR($iFormat, $HDF_SORTDOWN)) ElseIf BitAND($iFormat, $HDF_SORTUP) Then _GUICtrlHeader_SetItemFormat($hHeader, $x, BitXOR($iFormat, $HDF_SORTUP)) EndIf Next $iFormat = _GUICtrlHeader_GetItemFormat($hHeader, $iCol) If $aListViewSortInfo[$iIndex][5] = 1 Then ; ascending _GUICtrlHeader_SetItemFormat($hHeader, $iCol, BitOR($iFormat, $HDF_SORTUP)) $iColumn = $iCol $sSortDirection = "Ascending" Else ; descending _GUICtrlHeader_SetItemFormat($hHeader, $iCol, BitOR($iFormat, $HDF_SORTDOWN)) $iColumn = $iCol $sSortDirection = "Descending" EndIf EndIf EndIf Return $iResult <> 0 EndFunc ;==>_GUICtrlListView_SortItems Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted April 28, 2009 Moderators Share Posted April 28, 2009 (edited) someone,I have a solution. You need to read the $aListViewSortInfo array created by the GuiListView.au3 include file within your While...WEnd loop after calling _GUICtrlListView_SortItems. So the loop in the _GUICtrlListView_SortItems example would look like this:While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $hListView ; Kick off the sort callback _GUICtrlListView_SortItems($hListView, GUICtrlGetState($hListView)) Local $iIndex = $aListViewSortInfo[0][0] ConsoleWrite("Col: " & $aListViewSortInfo[$iIndex][3]) If $aListViewSortInfo[$iIndex][5] = 1 Then ConsoleWrite(" in ascending order" & @CRLF) Else ConsoleWrite(" in descending order" & @CRLF) EndIf EndSwitch WEndI hope this works for you.M23Edit: picaxe, Looks like you beat me to it by a very short head. I must learn to type faster! Edited April 28, 2009 by Melba23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
someone Posted April 28, 2009 Author Share Posted April 28, 2009 Thank you both very much, really appreciate it. Looks likes its exactly what I was hoping for. Any chance either of you know how to highlight in a listview? I want to have permanent highlighting (not done by a user) based on the information populated, say if colum a says 'here' I want the row to be highlighted red, if it says 'there' I want it highlighted yellow, etc. I haven't done as much searching around for that but any pointers is of course greatly appreciated. Not a huge deal but it would be pretty cool to do. Thanks again! While ProcessExists('Andrews bad day.exe') BlockInput(1) SoundPlay('Music.wav') SoundSetWaveVolume('Louder') WEnd Link to comment Share on other sites More sharing options...
picaxe Posted April 29, 2009 Share Posted April 29, 2009 Thank you both very much, really appreciate it. Looks likes its exactly what I was hoping for. Any chance either of you know how to highlight in a listview? I want to have permanent highlighting (not done by a user) based on the information populated, say if colum a says 'here' I want the row to be highlighted red, if it says 'there' I want it highlighted yellow, etc.The examples forum has many custom drawn examples from Siao and others that can do that. My version of a simple exampleexpandcollapse popup#include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> #include <HeaderConstants.au3> #Include <SendMessage.au3> #include <ListViewConstants.au3> #Include <WinAPI.au3> $GUI = GUICreate("Test Script", 300, 230) $ListView = GUICtrlCreateListView("Column", 20, 10, 260, 160, $LVS_REPORT) $hListView = GUICtrlGetHandle($ListView) _GUICtrlListView_SetColumnWidth($hListView, 0, 250) For $i = 0 To 20 GUICtrlCreateListViewItem("Test Item " & StringFormat("%.03u", $i), $ListView) Next ;~ $Highlight_Button = GUICtrlCreateButton("Highlight", 20, 190, 80, 20) ;~ $Clear_Button = GUICtrlCreateButton("Clear", 200, 190, 80, 20) GUISetState(@SW_SHOW, $GUI) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;fonts for custom draw example ;bold Local $aFontBold = DLLCall("gdi32.dll","int","CreateFont", "int", 14, "int", 0, "int", 0, "int", 0, "int", 700, _ "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, _ "dword", 0, "str", "") ;italic Local $aFontItalic = DLLCall("gdi32.dll","int","CreateFont", "int", 14, "int", 0, "int", 0, "int", 0, "int", 400, _ "dword", 1, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, "dword", 0, _ "dword", 0, "str", "") ; hilite the following rows $iIndex = "|2|5|7|11|18|" _WinAPI_RedrawWindow($hListView) ;$iIndex = -1 While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE DLLCall("gdi32.dll","int","DeleteObject", "hwnd", $aFontBold[0]) DLLCall("gdi32.dll","int","DeleteObject", "hwnd", $aFontItalic[0]) Exit ;~ Case $Highlight_Button ;~ $iIndex = _GUICtrlListView_GetSelectedIndices($hListView) ;~ _WinAPI_RedrawWindow($hListView) ;~ Case $Clear_Button ;~ $iIndex = -1 ;~ _WinAPI_RedrawWindow($hListView) EndSwitch WEnd Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CUSTOMDRAW If Not _GUICtrlListView_GetViewDetails($hWndFrom) Then Return $GUI_RUNDEFMSG Local $tCustDraw = DllStructCreate('hwnd hwndFrom;int idFrom;int code;' & _ 'dword DrawStage;hwnd hdc;long rect[4];dword ItemSpec;int ItemState;dword Itemlparam;' & _ 'dword clrText;dword clrTextBk;int SubItem;dword ItemType;dword clrFace;int IconEffect;' & _ 'int IconPhase;int PartID;int StateID;long rectText[4];int Align', _;winxp or later $lParam) Local $iDrawStage, $iItem, $iSubitem, $hDC, $iColor1, $iColor2, $iColor3 $iDrawStage = DllStructGetData($tCustDraw, 'DrawStage') If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW;request custom drawing of items If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW;request drawing each cell separately If Not BitAND($iDrawStage, $CDDS_SUBITEM) Then Return $CDRF_DODEFAULT $iItem = DllStructGetData($tCustDraw, 'ItemSpec') ;$iSubitem = DllStructGetData($tCustDraw, 'SubItem') ;$iColor1 = RGB2BGR(0xFBFFD8); light yellow $iColor1 = RGB2BGR(0xFFFFA8); yellow ;$iColor1 = RGB2BGR(0xFFDDDD); light red $iColor2 = RGB2BGR(-1) ; white ;$iColor3 = RGB2BGR(0xFF0000); red $iColor3 = RGB2BGR(0xFF6060); light red ;$iColor3 = RGB2BGR(0x000080); navy blue If $iIndex = -1 Then Return $CDRF_NEWFONT If StringInStr($iIndex, "|" & $iItem & "|") Then $hDC = DllStructGetData($tCustDraw, 'hdc') DLLCall("gdi32.dll","hwnd","SelectObject", "hwnd", $hDC, "hwnd", $aFontBold[0]) DllStructSetData($tCustDraw, 'clrText', $iColor2) DllStructSetData($tCustDraw, 'clrTextBk', $iColor3) EndIf Return $CDRF_NEWFONT EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func RGB2BGR($iColor) Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF) EndFunc ;==>RGB2BGR Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted April 29, 2009 Moderators Share Posted April 29, 2009 picaxe, Thanks for that script. I was having trouble understanding some of the other examples I came across - I find yours much easier for some reason. Always delighted to learn something new. :-) M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
picaxe Posted April 29, 2009 Share Posted April 29, 2009 @Melba23 You are welcome Link to comment Share on other sites More sharing options...
someone Posted April 29, 2009 Author Share Posted April 29, 2009 Yeah very cool, thanks a lot guys While ProcessExists('Andrews bad day.exe') BlockInput(1) SoundPlay('Music.wav') SoundSetWaveVolume('Louder') WEnd Link to comment Share on other sites More sharing options...
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