kk_lee69 发表于 2017-8-10 13:11:48

虚拟列表 LISTVIEW的颜色自定义 如何更改内定的高亮颜色

虚拟列表 LISTVIEW的颜色自定义 如何更改内定的高亮颜色

虚拟列表 LISTVIEW 的 颜色自定义,如何更改内定的选中 高亮颜色

请看以下的程序求高手帮忙 解决是哪个区块有问题

如何 无法更改 高亮颜色

标准的 LISTVIE 可以更改如 右边的图

理论上 左边的图 单击后应该也要能够秀出 像右边的图 那样子的 黑色 黄色字才对

请高手帮忙完善程序




#PRE_UseX64=n
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
;#include <WinAPITheme.au3>
#include <GuiListView.au3>
#include <WinAPISys.au3>
#include <WinAPI.au3>
#include <GuiEdit.au3>
#include <array.au3>
#include <Misc.au3>

Global $B_DESCENDING ; 排序用陣列

Global $hActLst
Global $bCtrlDown = False;listview控制項ctrl鍵按下標識
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEnter, $aAccelKeys = [["{ENTER}", $hEnter]];虛擬控制項的控制碼和綁定的快速鍵

Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0;勾選的行數
Local $tText = DllStructCreate("wchar Text");建個結構,用來放listview列資料
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT], $aShowdata2[$iITEM_COUNT], $aShowdata3[$iITEM_COUNT];注意陣列最大專案數為2^24(16777216),所以$iITEM_COUNT = 4194304為二維陣列$aShowdata最大行數
Local $sSomeString = ""
Local $hGUI, $hListView, $hListView2, $hListView3

Global $aFont1 = 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
Global $aFont2 = 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", "")


GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView虛表 載入[" & UBound($aShowdata) & "]資料 核取方塊 原地編輯例子 By_Crossdoor", 600, 605)




$hListView2 = GUICtrlCreateListView("$hListView2| | ", 100, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
;~ _WinAPI_SetWindowTheme(GUICtrlGetHandle($hListView), "Explorer");設置主題

;設置列寬
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 0, 110)
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 1, 80)
GUICtrlSendMsg($hListView2, $LVM_SETCOLUMNWIDTH, 2, 80)
GUICtrlSendMsg($hListView2, $LVM_SETITEMCOUNT, $iITEM_COUNT, 0);設定數據總數



;===========創建並關聯圖像清單
$hImage = _GUIImageList_Create()
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 110)
_GUICtrlListView_SetImageList($hListView, $hImage, 1);分配圖像清單到清單視圖控制項$hListView
_GUICtrlListView_SetImageList($hListView2, $hImage, 1);分配圖像清單到清單視圖控制項$hListView2


GUISetState()

;==================在表單顯示後再初始化資料,因為初始化陣列資料比較慢
;如果先初始化陣列後顯示視窗,會卡很久,就造成虛表也很慢的假像
For $i = 0 To $iITEM_COUNT - 1
    ;重繪 刷新 listview 0-13行(讓ListView顯示陣列資料),不用太多行,只需要一屏的行數就就可以
    ;因為下拉滾動的時候listview會收到LVN_GETDISPINFO消息,這個消息我們在WM_NOTIFY內處理過了
    If $i = 18 Then
      GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)

    EndIf
   
   
    $aShowdata2[$i] = "2爺爺" & $i
    $aShowdata2[$i] = "2爸爸" & $i
    $aShowdata2[$i] = "2兒子" & $i
    $aShowdata2[$i] = 4096;核取方塊狀態4096未選中 8192選中
   
   
Next

While 1
    $bCtrlDown = _IsPressed("11", $hUser32);取ctrl按鍵的狀態
    Switch GUIGetMsg()
      Case -3
            ExitLoop

    EndSwitch
WEnd
GUIDelete()
DllClose($hUser32)

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
   
    Switch $iIDFrom
         Case $hListView2
            Switch $iCode
                Case -150, -177 ;$LVN_GETDISPINFOA = -150, $LVN_GETDISPINFOW = -177   請求顯示資料
                  _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata2)
                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;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;int Align', _ ;winxp or later
                                        $ilParam), $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('long;long;long;long')
                                                                If $iSubitem = 0 Then
                                                                        DllCall('user32.dll','int','SendMessage', 'hwnd',$hWndFrom, 'uint',$LVM_GETSUBITEMRECT, 'wparam',$iItem, 'lparam',DllStructGetPtr($tRect))
                                                                        DllStructSetData($tRect, 1, 2)
                                                                        DllCall('user32.dll', 'int', 'FillRect', 'ptr', $hDC, 'ptr', DllStructGetPtr($tRect), 'int', _WinAPI_GetStockObject(4))
                                                                EndIf
                                                                DllStructSetData($tRect, 1, 2)
                                                                DllStructSetData($tRect, 2, $iSubitem)
                                                                DllCall('user32.dll','int','SendMessage', 'hwnd',$hWndFrom, 'uint',$LVM_GETSUBITEMRECT, 'wparam',$iItem, 'lparam',DllStructGetPtr($tRect))
                                                                ;Local $sText = _GUICtrlListView_GetItemText($hWndFrom, $iItem, $iSubitem)
                                                                Local $sText = $aShowdata2[$iItem][$iSubitem]
                                                                ;ConsoleWrite($sText&@CRLF)

                                                                DLLCall("gdi32.dll","int","SetTextColor", "ptr", $hDC, "int", RGB2BGR(0xffff00))
                                                                DLLCall("gdi32.dll","int","SetBkMode", "ptr", $hDC, "int", 1)
                                                                DllStructSetData($tRect, 1, DllStructGetData($tRect, 1)+2)
                                                                ;ConsoleWrite($hDC&@CRLF)
                                                                _WinAPI_DrawText($hDC, $sText, $tRect, 0x8000) ;; $DT_END_ELLIPSIS
                                                                _WinAPI_ReleaseDC($hWndFrom, $hDC)
                                                                Return $CDRF_SKIPDEFAULT
                                                               
                                                        EndIf
                                                        Switch $iItem
                                                                Case 0 To 9 ;for rows 1-10 lets do this
                                                                        $iColor1 = RGB2BGR(0xFBFFD8)
                                                                        $iColor2 = RGB2BGR(-1)
                                                                        $iColor3 = RGB2BGR(0xFF0000)
                                                                        If Mod($iSubitem, 2) Then ;odd columns
                                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                                                        DllStructSetData($tCustDraw, 'clrText', 0)
                                                                        Else ;even columns
                                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                                                        DllStructSetData($tCustDraw, 'clrText', $iColor3)
                                                                        EndIf
                                                                Case 10 To 19 ;for rows 11-20 lets do this
                                                                        $iColor1 = RGB2BGR(0xFBFFD8)
                                                                        $iColor2 = RGB2BGR(0x3DF8FF)
                                                                        $hDC = DllStructGetData($tCustDraw, 'hdc')
                                                                        If Mod($iItem, 2) Then
                                                                        If Mod($iSubitem, 2) Then
                                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                                                        Else
                                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                                                        EndIf
                                                                        DLLCall("gdi32.dll","hwnd","SelectObject", "hwnd", $hDC, "hwnd", $aFont1) ;select our chosen font into DC
                                                                        Else
                                                                        If Mod($iSubitem, 2) Then
                                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                                                        Else
                                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                                                        EndIf
                                                                        DLLCall("gdi32.dll","hwnd","SelectObject", "hwnd", $hDC, "hwnd", $aFont2)
                                                                        EndIf
                                                                Case 20 To 29 ;for rows 21-30 lets do this
                                                                        $iColor1 = RGB2BGR(0xFBFFD8)
                                                                        $iColor2 = RGB2BGR(-1)
                                                                        If Mod($iItem, 2) Then ;odd rows
                                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor2)
                                                                        Else
                                                                        DllStructSetData($tCustDraw, 'clrTextBk', $iColor1)
                                                                        EndIf
                                                        EndSwitch
                                                        Return $CDRF_NEWFONT
                                                Case BitOR($CDDS_ITEMPOSTPAINT, $CDDS_SUBITEM)
                                                       
                                                Case Else
                                                       
                                        EndSwitch
            EndSwitch
   EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc


Func _SetchkedBkClr(ByRef $tCustDraw, ByRef $aDataArray, $ihighBkClr = 0xF7D3AD, $idefBkclr = 0xFFFFFF)
    Local $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
    If $aDataArray[$iIndex] = 4096 Then
      DllStructSetData($tCustDraw, "clrTextBk", $idefBkclr);BGR格式顏色值 默認背景色
    Else
      DllStructSetData($tCustDraw, "clrTextBk", $ihighBkClr);BGR格式顏色值 高亮背景色
                DllStructSetData($tCustDraw, "clrText", 0xFFFFFF) ;高亮後文字改為白色
    EndIf
EndFunc


Func _SetchkedBkClr2(ByRef $tCustDraw, ByRef $aDataArray, $ihighBkClr = 0xF7D3AD, $idefBkclr = 0xFFFFFF)
                Local $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
      DllStructSetData($tCustDraw, "clrTextBk", $ihighBkClr);BGR格式顏色值 高亮背景色
                DllStructSetData($tCustDraw, "clrText", 0xFFFFFF) ;高亮後文字改為白色

EndFunc

Func _LVN_GETDISPINFO($hlst, $ilParam, ByRef $aDataArray)
    If Not IsArray($aDataArray) Then Return
    $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
    $iIndex = Int(DllStructGetData($tInfo, "Item"))
    $iSub = Int(DllStructGetData($tInfo, "SubItem"))

    If BitAND(DllStructGetData($tInfo, "Mask"), $LVIF_IMAGE) And $iSub = 0 Then DllStructSetData($tInfo, "Image", 0);判斷是否有LVIF_IMAGE屬性,有則設置列圖像。不設置_GUICtrlListView_SetImageList則無

    If (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then
      ;===============設置核取方塊資訊
      DllStructSetData($tInfo, "Mask", BitOR($LVIF_STATE, DllStructGetData($tInfo, "Mask")))
      DllStructSetData($tInfo, "StateMask", $LVIS_STATEIMAGEMASK)
      DllStructSetData($tInfo, "State", $aDataArray[$iIndex])
    EndIf

    DllStructSetData($tText, "Text", $aDataArray[$iIndex][$iSub]);列資料放入$tText結構
    DllStructSetData($tInfo, "Text", DllStructGetPtr($tText));$tText結構的指標來設置列資料
    DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]));設置列資料字串長
EndFunc

Func RGB2BGR($iColor)
Return BitAND(BitShift(String(Binary($iColor)), 8), 0xFFFFFF)
EndFunc

fenhanxue 发表于 2017-8-10 14:35:36

实测 貌似是第43行
$LVS_EX_DOUBLEBUFFER
这个样式发生了影响,原理我不懂。。。$hListView2 = GUICtrlCreateListView("$hListView2| | ", 100, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT + $LVS_EX_DOUBLEBUFFER + $LVS_EX_CHECKBOXES)
$hListView2 = GUICtrlCreateListView("$hListView2| | ", 100, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT+ $LVS_EX_CHECKBOXES)

kk_lee69 发表于 2017-8-10 14:41:55

回复 2# fenhanxue


    ㄟ好像是ㄟ   可是 到底是為什麼真搞不懂....

yamakawa 发表于 2017-8-10 15:08:53

Return $CDRF_SKIPDEFAULT 这行取消注销就可以用原来的高亮效果

kk_lee69 发表于 2017-8-10 15:27:11

回复 4# yamakawa

我知道 可是我就是想換成自己定義的顏色不想使用原來的

kk_lee69 发表于 2017-8-10 15:27:57

本帖最后由 kk_lee69 于 2017-8-10 15:37 编辑

回复 2# fenhanxue


    可以幫我一下嗎變黑色的時候那個複選框不見了   能否改成複選框還在

yamakawa 发表于 2017-8-10 16:04:57

回复 6# kk_lee69


    今天手上有事,没空调试,,你说变黑色看不见复选框,那明显是矩形位置不对。。大概看了下。。

132行DllStructSetData($tRect, 1, 2)你试着把这个2设高点,,比如20.。

kk_lee69 发表于 2017-8-10 16:15:24

本帖最后由 kk_lee69 于 2017-8-10 16:17 编辑

回复 7# yamakawa

OK 就是他 啦   謝啦就是找不到要改的位置感謝!!

不過還還是不知道為何 加上 $LVS_EX_DOUBLEBUFFER風格就不行

不知道是否有解決方法

yamakawa 发表于 2017-8-10 16:21:52

回复 7# yamakawa


    嗯,现在闲了,,有空了。。。
   看了下。。。。
1.我也是把那个双缓冲干掉了。。。。具体原因不明,,之前碰到过
2.要自定义颜色,你需要添加一个自定义笔刷,就像之前你的那帖子我说的那样。

   1.。132行 DllCall('user32.dll', 'int', 'FillRect', 'ptr', $hDC, 'ptr', DllStructGetPtr($tRect), 'int', _WinAPI_GetStockObject(4))改为$hbrush = _WinAPI_CreateSolidBrush(0xff4e00);要自定义,所以创建自定义笔刷
                                                                        DllCall('user32.dll', 'int', 'FillRect', 'ptr', $hDC, 'ptr', DllStructGetPtr($tRect), 'int', $hbrush);最后一个参数改成自定义笔刷
                                                                        _WinAPI_DeleteObject($hbrush)142行修改为                                                                _WinAPI_SetTextColor($hDC, 0xFFFFFF) ;字体颜色
应该就能满足你的要求了吧

yamakawa 发表于 2017-8-10 16:23:54

刚发现还有个图标被盖掉了。。。那个20你继续改吧。。。38?40左右应该就可以

kk_lee69 发表于 2017-8-10 16:28:10

回复 10# yamakawa

我改37 可以了其他的 我再研究看看謝啦

yamakawa 发表于 2017-8-12 16:52:57

回复 11# kk_lee69


    闲的蛋疼,又看了一次代码。。。
   好像那个获取dc有问题。。你试着这样改看看          $hDC = DllStructGetData($tCustDraw, 'hdc')

yamakawa 发表于 2017-8-12 16:54:13

回复 11# kk_lee69


    用你的源码,改了这句,,可以用双缓冲了。。但是好像有其他问题。。前面图标没了。。看来需要自己添加了

itljl 发表于 2017-8-15 21:33:16

应该可以吧

kk_lee69 发表于 2017-8-16 09:29:36

回复 13# yamakawa


    是阿 前面圖標還是勾選的地方不見了   看來 還是原本那個 好像比較好些
页: [1] 2
查看完整版本: 虚拟列表 LISTVIEW的颜色自定义 如何更改内定的高亮颜色