找回密码
 加入
搜索
查看: 6482|回复: 26

[AU3基础] 虚拟列表 LISTVIEW的颜色自定义 如何更改内定的高亮颜色

 火..   [复制链接]
发表于 2017-8-10 13:11:48 | 显示全部楼层 |阅读模式
虚拟列表 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[3] ; 排序用陣列
 
Global $hActLst
Global $bCtrlDown = False;listview控制項ctrl鍵按下標識
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEnter, $aAccelKeys[1][2] = [["{ENTER}", $hEnter]];虛擬控制項的控制碼和綁定的快速鍵
 
Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0;勾選的行數
Local $tText = DllStructCreate("wchar Text[256]");建個結構,用來放listview列資料
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT][4], $aShowdata2[$iITEM_COUNT][4], $aShowdata3[$iITEM_COUNT][4];注意陣列最大專案數為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][0] = "2爺爺" & $i
    $aShowdata2[$i][1] = "2爸爸" & $i
    $aShowdata2[$i][2] = "2兒子" & $i
    $aShowdata2[$i][3] = 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[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
                                        $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[0]) ;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[0])
                                                                        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][3] = 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][3])
    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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 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)
 楼主| 发表于 2017-8-10 14:41:55 | 显示全部楼层
回复 2# fenhanxue


    ㄟ  好像是ㄟ   可是 到底是為什麼  真搞不懂....
发表于 2017-8-10 15:08:53 | 显示全部楼层
Return $CDRF_SKIPDEFAULT 这行取消注销就可以用原来的高亮效果
 楼主| 发表于 2017-8-10 15:27:11 | 显示全部楼层
回复 4# yamakawa

我知道 可是我就是想換成自己定義的顏色  不想使用原來的
 楼主| 发表于 2017-8-10 15:27:57 | 显示全部楼层
本帖最后由 kk_lee69 于 2017-8-10 15:37 编辑

回复 2# fenhanxue


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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2017-8-10 16:04:57 | 显示全部楼层
回复 6# kk_lee69


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

132行
DllStructSetData($tRect, 1, 2)
你试着把这个2设高点,,比如20.。
 楼主| 发表于 2017-8-10 16:15:24 | 显示全部楼层
本帖最后由 kk_lee69 于 2017-8-10 16:17 编辑

回复 7# yamakawa

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

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

不知道是否有解決方法
发表于 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) ;字体颜色
应该就能满足你的要求了吧
发表于 2017-8-10 16:23:54 | 显示全部楼层
刚发现还有个图标被盖掉了。。。那个20你继续改吧。。。38?40左右应该就可以
 楼主| 发表于 2017-8-10 16:28:10 | 显示全部楼层
回复 10# yamakawa

我改37 可以了  其他的 我再研究看看  謝啦
发表于 2017-8-12 16:52:57 | 显示全部楼层
回复 11# kk_lee69


    闲的蛋疼,又看了一次代码。。。
   好像那个获取dc有问题。。你试着这样改看看
          $hDC = DllStructGetData($tCustDraw, 'hdc')
发表于 2017-8-12 16:54:13 | 显示全部楼层
回复 11# kk_lee69


    用你的源码,改了这句,,可以用双缓冲了。。但是好像有其他问题。。前面图标没了。。看来需要自己添加了
发表于 2017-8-15 21:33:16 | 显示全部楼层
应该可以吧
 楼主| 发表于 2017-8-16 09:29:36 | 显示全部楼层
回复 13# yamakawa


    是阿 前面圖標  還是勾選的地方不見了   看來 還是原本那個 好像比較好些
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-4-20 02:23 , Processed in 0.083005 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表