gobsor Posted December 30, 2010 Share Posted December 30, 2010 Hello, Why doesn't this code select/highlight (in blue 'this-row-is-selected'-colour) the first row in the ListView after loading files to it, using the 'LOAD' button? (As far as I understood it, _GUICtrlListView_SetItemSelected() and _GUICtrlListView_SetItemFocused() should do the job) #include <GuiConstants.au3> #include <GuiListView.au3> #include <File.au3> GUICreate("test", 500, 500) $hListView = GUICtrlCreateListView("", 5, 5, 490, 400, $LVS_SINGLESEL, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT) _GUICtrlListView_AddColumn($hListView, "#", 30) _GUICtrlListView_AddColumn($hListView, "A", 170) _GUICtrlListView_AddColumn($hListView, "B", 170) $idLoad = GUICtrlCreateButton("LOAD", 295, 410, 200, 80) GUISetState(@SW_SHOW) While 1 $msg = GUIGetMsg() If $msg == $GUI_EVENT_CLOSE Then ExitLoop If $msg == $idLoad Then _load() WEnd Func _load() $path = FileSelectFolder("Browse Folder", @DesktopDir, 4) If Not @error Then $ar = _FileListToArray($path, "*.*") For $i = 0 To UBound($ar)-1 Step 1 GUICtrlCreateListViewItem($i & "|" & $ar[$i] & "|" & "test", $hListView) Next $bTest_1 = _GUICtrlListView_SetItemSelected($hListView, 0, True, True) ; Tested both of these functions, in combination or each alone with different values, no effects still MsgBox(0, "SetItemSelected() returned:", $bTest_1) ; $bTest_2 = _GUICtrlListView_SetItemFocused($hListView, 0, True) MsgBox(0, "SetItemFocused() returned:", $bTest_2) EndIf EndFunc ;==> _load() In my actual project I want to highlight rows after a button is pressed or if one clicks a certain row. Not that much of a problem if I, somehow, get those functions working. Or am I failing basically here, ie. using the wrong functions? Any help appreciated. rgrds Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 30, 2010 Moderators Share Posted December 30, 2010 gobsor, I have found that the only reliable way to highlight ListView rows is to use _GUICtrlListView_ClickItem to simulate mouse clicks: #include <GuiConstants.au3> #include <GuiListView.au3> #include <File.au3> GUICreate("test", 500, 500) $hListView = GUICtrlCreateListView("", 5, 5, 490, 400, $LVS_SINGLESEL, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT) _GUICtrlListView_AddColumn($hListView, "#", 30) _GUICtrlListView_AddColumn($hListView, "A", 170) _GUICtrlListView_AddColumn($hListView, "B", 170) $idLoad = GUICtrlCreateButton("LOAD", 295, 410, 200, 80) GUISetState(@SW_SHOW) While 1 $msg = GUIGetMsg() If $msg == $GUI_EVENT_CLOSE Then ExitLoop If $msg == $idLoad Then _load() WEnd Func _load() $path = FileSelectFolder("Browse Folder", @DesktopDir, 4) If Not @error Then $ar = _FileListToArray($path, "*.*") For $i = 0 To UBound($ar)-1 Step 1 GUICtrlCreateListViewItem($i & "|" & $ar[$i] & "|" & "test", $hListView) Next ; Simulate a mouse click on the top item _GUICtrlListView_ClickItem($hListView, 0) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< EndIf EndFunc ;==> _load() In my actual project I want to highlight rows after a button is pressed or if one clicks a certain rowClicking with the mouse will obviously highlight a row as it does in reality what the code above simulates. For buttons, just use code as above. M23 Synapsee 1 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...
gobsor Posted December 30, 2010 Author Share Posted December 30, 2010 Thanks, works fine like this. Just everytime I click on a button or input or just elsewhere, the focus/highlight gets lost. Is it possible to have at least one item focused/highlighted all the time? (Always I press 'Move UP' or 'Move DN' the selection/highlight disappears for a millisec, when I press some other button ([bROWSE]) then it disappears at all.) greets Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 30, 2010 Moderators Share Posted December 30, 2010 gobsor,The default ListView has the $LVS_SHOWSELALWAYS style selected. But on my monitor I have to change the background colour of the ListView to make the selection visible when the ListView loses focus as the default non-active selected colour is too close to the default ListView background colour. 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...
gobsor Posted December 30, 2010 Author Share Posted December 30, 2010 Ah, okay. Would be easier to just change the default LisstView-Highlighted color. Not possible, is it? And how do I change the color for the '_ClickItem($h, $index)' $index'th row? Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 30, 2010 Moderators Share Posted December 30, 2010 gobsor,If you ever find out how to change the default non-active ListView selection colout, please let me know! I am sure it is a system setting, but I cannot find it. Anyway, changing the ListView background colour has always worked for me.As to changing the selected row colour, that too is a system setting - if you want to change it then _WinAPI_GetSysColor/_WinAPI_SetSysColor would be a good place to start looking. But do not blame me if you screw all the system colours while playing with them! 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...
gobsor Posted December 30, 2010 Author Share Posted December 30, 2010 Oh, I was fiddling with GUICtrlSetBkColor(), though I couldn't work out to change the last _GUICtrlListView_ClickItem() 'clicked' row's colour. I rather keep my hands off those functions you just hooked me up with, at least until I got used to AU3 better Thanks for your help Link to comment Share on other sites More sharing options...
Mat Posted December 30, 2010 Share Posted December 30, 2010 I know you aren't interested in this solution, but someone in the future may be. This was adapted (mostly just updated) from (I couldn't have written it anyway).It's a tiny bit less messy. Not as many DllCalls and some code to colour other bits omitted.expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> $GUI = GUICreate("Listview Custom Draw", 400, 300) $cListView = GUICtrlCreateListView("Column 1|Column 2|Column 3", 2, 2, 394, 268, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) $hListView = GUICtrlGetHandle($cListView) ; Add items For $i = 1 To 30 GUICtrlCreateListViewItem("Row" & $i & ": Col 1|Row" & $i & ": Col 2|Row" & $i & ": Col 3", $cListView) Next GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Exit 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), $iDrawStage, $iItem, $iSubitem, $hDC, $tRect, $iColor1, $iColor2, $iColor3 $iDrawStage = DllStructGetData($tCustDraw, 'DrawStage') Switch $iDrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT Return $CDRF_NOTIFYSUBITEMDRAW Case $CDDS_ITEMPOSTPAINT Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM) $iItem = DllStructGetData($tCustDraw, 'ItemSpec') $iSubitem = DllStructGetData($tCustDraw, 'SubItem') If _GUICtrlListView_GetItemSelected($hWndFrom, $iItem) Then $hDC = _WinAPI_GetDC($hWndFrom) $tRect = DllStructCreate($tagRECT) If $iSubitem = 0 Then _SendMessage($hWndFrom, $LVM_GETSUBITEMRECT, $iItem, DllStructGetPtr($tRect)) DllStructSetData($tRect, 1, 2) _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), _WinAPI_GetStockObject($GRAY_BRUSH)) EndIf DllStructSetData($tRect, 1, 2) DllStructSetData($tRect, 2, $iSubitem) _SendMessage($hWndFrom, $LVM_GETSUBITEMRECT, $iItem, DllStructGetPtr($tRect)) Local $sText = _GUICtrlListView_GetItemText($hWndFrom, $iItem, $iSubitem) _WinAPI_SetBkMode($hDC, $TRANSPARENT) DllStructSetData($tRect, 1, DllStructGetData($tRect, 1) + 2) _WinAPI_DrawText($hDC, $sText, $tRect, 0x8000) ;; $DT_END_ELLIPSIS _WinAPI_ReleaseDC($hWndFrom, $hDC) Return $CDRF_SKIPDEFAULT EndIf Return $CDRF_NEWFONT Case BitOR($CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM) Case Else EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func RGB2BGR($iColor) Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF) EndFunc ;==>RGB2BGR AutoIt Project Listing Link to comment Share on other sites More sharing options...
gobsor Posted December 30, 2010 Author Share Posted December 30, 2010 That's almost what I've been looking for, its just as fine though.. But, tbh, its pretty much code for such a little effect. I still might use it though since it enhances the oversight when the user is editing the ListView (using inputs below it in combination with a button to change the values of each row). Each time the user clicks the input field the focus on the ListView is lost and therefore the highlight, too. Your little work-around posted above might be very useful though, let's hope there'll be some function for it coming up in 2011 Link to comment Share on other sites More sharing options...
Mat Posted December 31, 2010 Share Posted December 31, 2010 (edited) Here is an updated version. The code has been tidied up even more, and it now selects the font to be the same as the listviews. I also commented it a bit more. Don't get your hopes up with a new function to do this in 2011... I'd be very surprised if there was one. The problem with custom draw for stuff like this is that it's designed for the user to completely take control of how the control looks, not to tweak one or two things. It looks like a lot of code now, but most of it's getting to the message. If you want to change the text colour, font, draw a border, add a shadow for the text of item for any item now then it would be a few lines of code. expandcollapse popup#include <GuiConstantsEx.au3> #include <GuiListView.au3> #include <ListViewConstants.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <StructureConstants.au3> $GUI = GUICreate("Listview Custom Draw", 400, 300) $cListView = GUICtrlCreateListView("Column 1|Column 2|Column 3", 2, 2, 394, 268, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) $hListView = GUICtrlGetHandle($cListView) ; Add items For $i = 1 To 30 GUICtrlCreateListViewItem("Row" & $i & ": Col 1|Row" & $i & ": Col 2|Row" & $i & ": Col 3", $cListView) Next GUICtrlCreateInput("Click here to test focus", 50, 275, 200, 18) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Exit 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 ; Not in details mode Local $tCustDraw, $iDrawStage, $iItem, $iSubitem, $hDC, $tRect, $iColor1, $iColor2, $iColor3 $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) $iDrawStage = DllStructGetData($tCustDraw, 'dwDrawStage') Switch $iDrawStage Case $CDDS_PREPAINT Return $CDRF_NOTIFYITEMDRAW Case $CDDS_ITEMPREPAINT Return $CDRF_NOTIFYSUBITEMDRAW Case $CDDS_ITEMPOSTPAINT ; Not handled Case BitOR($CDDS_ITEMPREPAINT, $CDDS_SUBITEM) $iItem = DllStructGetData($tCustDraw, 'dwItemSpec') $iSubitem = DllStructGetData($tCustDraw, 'iSubItem') If _GUICtrlListView_GetItemSelected($hWndFrom, $iItem) Then ; Item to draw is selected $hDC = _WinAPI_GetDC($hWndFrom) $tRect = DllStructCreate($tagRECT) ; We draw the background when we draw the first item. If $iSubitem = 0 Then ; We must send the message as we want to use the struct. _GUICtrlListView_GetSubItemRect returns an array. _SendMessage($hWndFrom, $LVM_GETSUBITEMRECT, $iItem, DllStructGetPtr($tRect)) DllStructSetData($tRect, "Left", 2) _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), _WinAPI_GetStockObject($GRAY_BRUSH)) ; Change the bush here. You can use GDI+ to make your own. EndIf DllStructSetData($tRect, "Left", 2) DllStructSetData($tRect, "Top", $iSubitem) _SendMessage($hWndFrom, $LVM_GETSUBITEMRECT, $iItem, DllStructGetPtr($tRect)) Local $sText = _GUICtrlListView_GetItemText($hWndFrom, $iItem, $iSubitem) _WinAPI_SetBkMode($hDC, $TRANSPARENT) ; It uses the background drawn for the first item. ; Select the font we want to use _WinAPI_SelectObject($hDC, _SendMessage($hWndFrom, $WM_GETFONT)) If $iSubitem = 0 Then DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Left") + 2) Else DllStructSetData($tRect, "Left", DllStructGetData($tRect, "Left") + 6) EndIf _WinAPI_DrawText($hDC, $sText, $tRect, BitOR($DT_VCENTER, $DT_END_ELLIPSIS, $DT_SINGLELINE)) _WinAPI_ReleaseDC($hWndFrom, $hDC) Return $CDRF_SKIPDEFAULT ; Don't do default processing EndIf Return $CDRF_NEWFONT ; Let the system do the drawing for non-selected items Case BitOR($CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM) ; Not handled EndSwitch EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func RGB2BGR($iColor) Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF) EndFunc ;==>RGB2BGR MatEdit: See here for an updated version which includes sorting. Edited May 26, 2015 by Mat Added link to updated code. AutoIt Project Listing Link to comment Share on other sites More sharing options...
gobsor Posted January 2, 2011 Author Share Posted January 2, 2011 Thanks you! Its just as fine as a 'normal' highlight. At least it does its job and prevents the user from getting confused in what row he currently is. Will use your code and put it into my little tool when I find some time the upcoming days. Greetings Link to comment Share on other sites More sharing options...
LeXarT Posted February 25, 2011 Share Posted February 25, 2011 Hey mat, Your code work beautiful except that it covers the list-box icon gfx when your list's elements contains list-boxes. Why doesn't _GUICtrlListView_SetItemFocused work as it should? Take it from this Quadriplegic, life is beautiful. Don't know what a quadriplegic is? Check out my short bio.Starting an online business. Link to comment Share on other sites More sharing options...
maniootek Posted April 18, 2016 Share Posted April 18, 2016 (edited) @Mat Is it possible to change selecting style? I just want to make dotted border of selected listview item with transparent bg color (which work with $LVS_EX_SUBITEMIMAGES ExStyle) Edited April 18, 2016 by maniootek Link to comment Share on other sites More sharing options...
Mat Posted April 26, 2016 Share Posted April 26, 2016 @LeXarT, @maniootek, Modifying the code to work with images (incl. subitem images) could be a little tricky, as it will require custom drawing the images. It's a very long time since I looked at this and I'm in the middle of exams at the moment, but I'll add it on to the todo list. In summary though, drawing images is the same as drawing text items. You have to work out what needs redrawing, and where it is, then draw it to the context. Steps are as follows: Start with the HBITMAP. Now this can either be loaded every time you draw or preloaded and stored somewhere (I suspect the latter may be better?). Create a compatible DC for the context you are drawing to (CreateCompatibleDC()), SelectObject() to select the bitmap into the new DC you've created, BitBlt() to the listview DC, then cleanup (last stage might have to use one of the other Blt functions to use transparent backgrounds on the icons). For storing HBITMAPs, first guess would be to store them in the lParam of the items, if multiple are needed then that can point to a structure (of course being careful to free everything in response to deleting the window). However, I expect this is not how it's done by the listview normally so perhaps isn't the right way. Mat AutoIt Project Listing 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