Spiff59 Posted July 22, 2009 Posted July 22, 2009 (edited) $LVS_EX_BORDERSELECT That extended style seems to lay the whammy on any ListView I apply it to. Is broken? Or am I missing something? Edit: I searched on the full variable name, instead of just "borderselect" and got some archived hits. I guess this only works with large icons? I have a listview where the rows have different background colors depending upon the type of record, and I wanted to retain those colors even when the row was selected. I'm not sure if there is a way for force a border color change on an entire selected row, keeping the original background color? Any CustomDraw magic that will do it? (Grr... this post would been better in the GUI forum) Edited July 23, 2009 by Spiff59
Authenticity Posted July 22, 2009 Posted July 22, 2009 After a few tests it seems the only difference is that if $LVS_EX_BORDERSELECT is not specified then the image gets highlighted as well whereas specifying this extended style won't highlight the image: #Include <GuiImageList.au3> #include <GUIListView.au3> Global $hGUI = GUICreate('', 200, 200) Global $ListView = GUICtrlCreateListView('1|2|3', 0, 0, 200, 200, $LVS_DEFAULT) Global $hListView = GUICtrlGetHandle($ListView) Global $hImage = _GUIImageList_Create(16, 16, 5) _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_BORDERSELECT, $LVS_EX_FULLROWSELECT)) _GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110) _GUICtrlListView_SetImageList($hListView, $hImage, 1) _GUICtrlListView_BeginUpdate($hListView) For $i = 0 To 9 $Item = GUICtrlCreateListViewItem('A|B|C', $ListView) GUICtrlSetBkColor($Item, Random(13369344, 13434879, 1)) _GUICtrlListView_SetItemImage($hListView, $i, 0) Next _GUICtrlListView_EndUpdate($hListView) For $i = 0 To 2 _GUICtrlListView_SetColumnWidth($hListView, $i, 150) Next GUISetState() Do Until GUIGetMsg() = -3 _GUIImageList_Destroy($hImage) _GUICtrlListView_Destroy($hListView) GUIDelete() Exit
Spiff59 Posted July 23, 2009 Author Posted July 23, 2009 I'd prefer some sort of outlining of the selected row, but if that's not possible, I thought maybe highlighting the entire row in the current background color of the "key" cell might be an option. I've been tinkering with some code, but can only get it to outline the area of the rectangle occupied by text, rather than the entire rectangle. So, instead of a solid color bar across the selected row, I get the color broken into pieces. Anyone have an idea how to color all parts of the selected row? expandcollapse popup#Include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #Include <GuiListView.au3> Global $Row_Changed $hGUI = GUICreate("Listview Custom Draw", 400, 300) $cListView = GUICtrlCreateListView("", 2, 2, 394, 268, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) $hListView = GUICtrlGetHandle($cListView) $label = GUICtrlCreateLabel("", 50, 275, 100, 15) _GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 90) _GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 140) _GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100) ; Add items For $i = 1 To 30 _GUICtrlListView_AddItem($hListView, "Row" & $i & ": Col 1", $i-1) For $j = 1 To 2 _GUICtrlListView_AddSubItem ($hListView, $i-1, "Row" & $i & ": Col " & $j+1, $j) Next Next GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUISetState() Do If $Row_Changed Then $Row_Changed = 0 GUICtrlSetData($label, "Row selected: " & _GUICtrlListView_GetSelectionMark($hListView)) EndIf Until GUIGetMsg() = $GUI_EVENT_CLOSE Exit ;------------------------------------------------------------------------------- Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $iColor, $iBkColor $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom") $iIDFrom = DllStructGetData($tNMHDR, "IDFrom") $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $hListView Switch $iCode Case $NM_CLICK, -155 ; up/down $Row_Changed = 1 Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = DllStructGetData($tCustDraw, "dwDrawStage") If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec") Local $iSubItem = DllStructGetData($tCustDraw, "iSubItem") If _GUICtrlListView_GetItemSelected($hWndFrom, $iItem) Then Local $sText = _GUICtrlListView_GetItemText($hWndFrom, $iItem, $iSubitem) Switch Mod($iItem, 3) Case 0 $iBkColor = RGB2BGR(0xFF0000) $iColor = RGB2BGR(0xFFFFFF) Case 1 $iBkColor = RGB2BGR(0x00FF00) $iColor = RGB2BGR(0x000000) Case 2 $iBkColor = RGB2BGR(0x0000FF) $iColor = RGB2BGR(0xFFFFFF) EndSwitch $tRect = DllStructCreate('long;long;long;long') DllStructSetData($tRect, 2, $iSubitem) DllCall('user32.dll','int','SendMessage', 'hwnd',$hWndFrom, 'uint',$LVM_GETSUBITEMRECT, 'wparam',$iItem, 'lparam',DllStructGetPtr($tRect)) $hDC = DllStructGetData($tCustDraw, 'hdc');_WinAPI_GetDC($hWndFrom) ; $rc = DllStructGetData($tCustDraw, 'rc') DLLCall("gdi32.dll","int","SetTextColor", "ptr", $hDC, "int", $iColor) DLLCall("gdi32.dll","int","SetBkColor", "ptr", $hDC, "int", $iBkColor) DLLCall("gdi32.dll","int","SetBkMode", "ptr", $hDC, "int", 2) DllStructSetData($tRect, 1, DllStructGetData($tRect, 1) + 6) _WinAPI_DrawText($hDC, $sText, $tRect, 0x8000) ;; $DT_END_ELLIPSIS Return $CDRF_SKIPDEFAULT EndIf Switch Mod($iItem, 3) ; alternate bg/text colors Case 0 $iColor = RGB2BGR(0xFF0000) $iBkColor = RGB2BGR(0xFFFFFF) Case 1 $iColor = RGB2BGR(0x00FF00) Case 2 $iColor = RGB2BGR(0x0000FF) $iBkColor = RGB2BGR(0xFFFFFF) EndSwitch If $iSubitem = 1 Then ; only paint column 2 DllStructSetData($tCustDraw, 'clrTextBk', $iColor) DllStructSetData($tCustDraw, 'clrText', $iBkColor) Else DllStructSetData($tCustDraw, 'clrTextBk', 0xFFFFFF) DllStructSetData($tCustDraw, 'clrText', 0) EndIf Return $CDRF_NEWFONT EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func RGB2BGR($iColor) Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF) EndFunc
Authenticity Posted July 23, 2009 Posted July 23, 2009 You can easily fill the items and subitems using a brush and the _WinAPI_FillRect() function. To outline the brush you need to use a pen and the Rectangle function. It's a straightforward way and may not be to your likes but it's applicable. ;]
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