Jump to content

Virtual listviews for huge number of rows


Recommended Posts

  • Replies 139
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Virtual listviews are lightning fast and can handle millions of rows. Virtual listviews are of interest when you have to insert more than 10,000 rows. When there are less than 10,000 rows, the st

Of course +1 must be added to $iFrom and $iTo. Because your item_id's starts at item_id = 1 and my item_id's starts at item_id = 0.   Sorting columns by clicking the column header. I would do i

You certainly can. Your code is well structured. Easy to read and understand. I like that. There are a few minor issues and one major issue. A virtual listview must include the $LVS_OWNERDATA sty

Posted Images

The easy way is to store the index of the selected item in a global variable, $iSelItem, and remove the selected state. Then the back and fore colors of the selected item can be drawn with usual custom draw code.

This is an example with a normal listview. It works in the same way for a virtual listview.

;#AutoIt3Wrapper_UseX64=y

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

Opt( "MustDeclareVars", 1 )

Global $hListView, $iItems = 100, $iSelItem = -1

Example()

Func Example()
  ; Create GUI
  GUICreate( "Selected item custom color", 420, 200 )

  ; Create ListView
  Local $idListView = GUICtrlCreateListView( "", 10, 10, 400, 180, $GUI_SS_DEFAULT_LISTVIEW, $WS_EX_CLIENTEDGE )
  _GUICtrlListView_SetExtendedListViewStyle( $idListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT )
  $hListView = GUICtrlGetHandle( $idListView )          ; Reduces flicker

  ; Add columns to ListView
  _GUICtrlListView_InsertColumn( $idListView, 0, "Column 1", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 1, "Column 2", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 2, "Column 3", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 3, "Column 4", 94 )

  ; Fill ListView
  For $i = 0 To $iItems - 1
    GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView )
  Next

  ; Register WM_NOTIFY message handler
  GUIRegisterMsg( $WM_NOTIFY, "WM_NOTIFY" )

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  ; Cleanup
  GUIDelete()
EndFunc

Func WM_NOTIFY( $hWnd, $iMsg, $wParam, $lParam )
  Local $tNMHDR = DllStructCreate( $tagNMHDR, $lParam )
  Local $hWndFrom = HWnd( DllStructGetData( $tNMHDR, "hWndFrom" ) )
  Local $iCode = DllStructGetData( $tNMHDR, "Code" )

  Switch $hWndFrom
    Case $hListView
      Switch $iCode
        Case $NM_CUSTOMDRAW
          Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $lParam )
          Local $dwDrawStage = DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" )
          Switch $dwDrawStage                ; Holds a value that specifies the drawing stage
            Case $CDDS_PREPAINT
              ; Before the paint cycle begins
              Return $CDRF_NOTIFYITEMDRAW    ; Notify the parent window of any item-related drawing operations
            Case $CDDS_ITEMPREPAINT
              ; Before painting an item
              Local $iItem = DllStructGetData($tNMLVCUSTOMDRAW, "dwItemSpec") ; Item index
              DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", $iItem = $iSelItem ? 0xADFF2F : 0xFFFFFF )
              Return $CDRF_NEWFONT           ; $CDRF_NEWFONT must be returned after changing font or colors
          EndSwitch

        Case $LVN_ITEMCHANGED
          Local $tNMLISTVIEW = DllStructCreate( $tagNMLISTVIEW, $lParam )
          _GUICtrlListView_RedrawItems( $hListView, $iSelItem, $iSelItem )
          $iSelItem = DllStructGetData( $tNMLISTVIEW, "Item" )
          _GUICtrlListView_SetItemSelected( $hListView, $iSelItem, False )         ; Remove selected state
          _GUICtrlListView_SetItemState( $hListView, $iSelItem, 0, $LVIS_FOCUSED ) ; Remove focused state
      EndSwitch
  EndSwitch

  Return $GUI_RUNDEFMSG
  #forceref $hWnd, $iMsg, $wParam
EndFunc

 

Link to post
Share on other sites

I refer to your example

But my program can not change color

Can you help me

 

#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
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEnter, $aAccelKeys[1][2] = [["{ENTER}", $hEnter]]
$iSelItem=-1
Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0
Local $tText = DllStructCreate("wchar Text[256]")
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT][4], $aShowdata2[$iITEM_COUNT][4], $aShowdata3[$iITEM_COUNT][4]
Local $sSomeString = ""
Local $hGUI, $hListView, $hListView2, $hListView3
 
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView[" & UBound($aShowdata) & "]", 600, 605)
  
  
$hListView2 = GUICtrlCreateListView("$hListView2| | ", 300, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT  + $LVS_EX_CHECKBOXES+ $LVS_EX_DOUBLEBUFFER);+ $LVS_EX_DOUBLEBUFFER
;~ _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);
_GUICtrlListView_SetImageList($hListView2, $hImage, 1);
 
GUISetState()
 

For $i = 0 To $iITEM_COUNT - 1

    If $i = 18 Then
        GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
    EndIf
    
   
    $aShowdata2[$i][0] = "2AA" & $i
    $aShowdata2[$i][1] = "2BB" & $i
    $aShowdata2[$i][2] = "2CC" & $i
    $aShowdata2[$i][3] = 4096;
    
    
Next
 
While 1
    $bCtrlDown = _IsPressed("11", $hUser32);
    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_GETDISPINFO($iIDFrom, $ilParam, $aShowdata2)
                
                    
                Case $NM_CUSTOMDRAW
                    
                  Local $tNMLVCUSTOMDRAW = DllStructCreate( $tagNMLVCUSTOMDRAW, $ilParam )
                  Local $dwDrawStage = DllStructGetData( $tNMLVCUSTOMDRAW, "dwDrawStage" )
                  Switch $dwDrawStage                ; Holds a value that specifies the drawing stage
                    Case $CDDS_PREPAINT
                      ; Before the paint cycle begins
                      Return $CDRF_NOTIFYITEMDRAW    ; Notify the parent window of any item-related drawing operations
                    Case $CDDS_ITEMPREPAINT
                      ; Before painting an item
                      Local $iItem = DllStructGetData($tNMLVCUSTOMDRAW, "dwItemSpec") ; Item index
                      DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", $iItem = $iSelItem ? 0xADFF2F : 0xFFFFFF )
                      Return $CDRF_NEWFONT           ; $CDRF_NEWFONT must be returned after changing font or colors
                  EndSwitch




                Case $LVN_ITEMCHANGED ; An item has changed
                    
                  Local $tNMLISTVIEW = DllStructCreate( $tagNMLISTVIEW, $ilParam )
                  _GUICtrlListView_RedrawItems( $hListView, $iSelItem, $iSelItem )
                  $iSelItem = DllStructGetData( $tNMLISTVIEW, "Item" )
                  _GUICtrlListView_SetItemSelected( $hListView, $iSelItem, False )         ; Remove selected state
                  _GUICtrlListView_SetItemState( $hListView, $iSelItem, 0, $LVIS_FOCUSED ) ; Remove focused state
                
                

            EndSwitch
 
    EndSwitch
    Return $GUI_RUNDEFMSG
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)
 
    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])
    DllStructSetData($tInfo, "Text", DllStructGetPtr($tText))
    DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]))
EndFunc

 

Edited by kklee69
Link to post
Share on other sites
Link to post
Share on other sites
1 hour ago, LarsJ said:

Replace $hListView with $hListView2 in the "Case $LVN_ITEMCHANGED" code section.

I see ..... I see...

My mistake
3Q for HELP
 
I would like to ask another question
How to convert 【DllStructSetData( $tNMLVCUSTOMDRAW, "ClrTextBk", $iItem = $iSelItem ? 0xADFF2F : 0xFFFFFF )】  FOR   AUTOIT V3.3.8 
 
I usually use  AUTOIT V3.3.8   BUT  V3.3.8    not support 【$iItem = $iSelItem ? 0xADFF2F : 0xFFFFFF
Link to post
Share on other sites
Link to post
Share on other sites

I need help

I have a program that can be checked to produce a different color

like this code AND JPG

 

#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
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEnter, $aAccelKeys[1][2] = [["{ENTER}", $hEnter]]
$iSelItem=-1
Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0
Local $tText = DllStructCreate("wchar Text[256]")
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT][4], $aShowdata2[$iITEM_COUNT][4], $aShowdata3[$iITEM_COUNT][4]
Local $sSomeString = ""
Local $hGUI, $hListView, $hListView2, $hListView3
 
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView[" & UBound($aShowdata) & "]", 600, 605)
  
  
$hListView2 = GUICtrlCreateListView("$hListView2| | ", 300, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT  + $LVS_EX_CHECKBOXES+ $LVS_EX_DOUBLEBUFFER);+ $LVS_EX_DOUBLEBUFFER
;~ _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);
_GUICtrlListView_SetImageList($hListView2, $hImage, 1);
 
GUISetState()
 

For $i = 0 To $iITEM_COUNT - 1

    If $i = 18 Then
        GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
    EndIf
    
   
    $aShowdata2[$i][0] = "2AA" & $i
    $aShowdata2[$i][1] = "2BB" & $i
    $aShowdata2[$i][2] = "2CC" & $i
    $aShowdata2[$i][3] = 4096;
    
    
Next
 
While 1
    $bCtrlDown = _IsPressed("11", $hUser32);
    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 $LVN_COLUMNCLICK ; 
                    _SortItems($iIDFrom, $ilParam, $aShowdata2)
                Case $NM_CUSTOMDRAW;
                    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", $ilParam)
                    Local $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
                    _SetchkedBkClr($tCustDraw, $aShowdata2, 0x738393)
                    
                    Return $CDRF_NEWFONT
                Case $LVN_ITEMCHANGED ; An item has changed

                    _CtrlSel($iIDFrom, $ilParam, $aShowdata2)
                    
                    
                Case $LVN_BEGINSCROLL ; 
                    If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2);
                Case $NM_CLICK;
                    If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2)
                    _chkboxState($iIDFrom, $ilParam, $aShowdata2)
                Case $NM_DBLCLK ; 
                   ; _StartItemEdit($iIDFrom, $ilParam, $aShowdata2)
            EndSwitch
 
    EndSwitch
    Return $GUI_RUNDEFMSG
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)
 
    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])
    DllStructSetData($tInfo, "Text", DllStructGetPtr($tText))
    DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]))
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);
    Else
        DllStructSetData($tCustDraw, "clrTextBk", $ihighBkClr);
        DllStructSetData($tCustDraw, "clrText", 0xFFFFFF) ;
    EndIf
EndFunc


Func _chkboxState($hlst, $ilParam, ByRef $aDataArray);
    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    $iIndex = DllStructGetData($tInfo, "Index")
    $x = DllStructGetData($tInfo, "X")
    If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;使用點擊的x座標來判斷是否在核取方塊上點擊
        If $aDataArray[$iIndex][3] = 4096 Then
            $ichked+=1
            $aDataArray[$iIndex][3] = 8192;
        Else
            $ichked-=1
            $aDataArray[$iIndex][3] = 4096;
        EndIf
        GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
    EndIf    
EndFunc


Func _CtrlSel($hlst, $ilParam, ByRef $aDataArray);
    If $bCtrlDown Then;
        $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
        Local $iIndex = DllStructGetData($tInfo, "Item")
        Local $iNewState = DllStructGetData($tInfo, "NewState")
        If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
            If $aDataArray[$iIndex][3] = 4096 Then
                $ichked+=1
                $aDataArray[$iIndex][3] = 8192;
            Else
                $ichked-=1
                $aDataArray[$iIndex][3] = 4096;
            EndIf
            $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
            DllStructSetData($tInfo, "State", $aDataArray[$iIndex][3]);
            GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
        EndIf
    EndIf
EndFunc

未命名.jpg

 

I would like to add a different color When I selected Item

But I failed

I can not change the color.

AND the checked function also fails  

Can you help me ??

#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
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEnter, $aAccelKeys[1][2] = [["{ENTER}", $hEnter]]
$iSelItem=-1
Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0
Local $tText = DllStructCreate("wchar Text[256]")
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT][4], $aShowdata2[$iITEM_COUNT][4], $aShowdata3[$iITEM_COUNT][4]
Local $sSomeString = ""
Local $hGUI, $hListView, $hListView2, $hListView3
 
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView[" & UBound($aShowdata) & "]", 600, 605)
  
  
$hListView2 = GUICtrlCreateListView("$hListView2| | ", 300, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT  + $LVS_EX_CHECKBOXES+ $LVS_EX_DOUBLEBUFFER);+ $LVS_EX_DOUBLEBUFFER
;~ _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);
_GUICtrlListView_SetImageList($hListView2, $hImage, 1);
 
GUISetState()
 

For $i = 0 To $iITEM_COUNT - 1

    If $i = 18 Then
        GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
    EndIf
    
   
    $aShowdata2[$i][0] = "2AA" & $i
    $aShowdata2[$i][1] = "2BB" & $i
    $aShowdata2[$i][2] = "2CC" & $i
    $aShowdata2[$i][3] = 4096;
    
    
Next
 
While 1
    $bCtrlDown = _IsPressed("11", $hUser32);
    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 $LVN_COLUMNCLICK ; 
                    _SortItems($iIDFrom, $ilParam, $aShowdata2)
                Case $NM_CUSTOMDRAW;
                    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", $ilParam)
                    Local $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
                    _SetchkedBkClr($tCustDraw, $aShowdata2, 0x738393)
                    
                    If $iDrawStage = $CDDS_ITEMPREPAINT Then
                        Local $iItem = DllStructGetData($tCustDraw , "dwItemSpec") ; Item index
                        IF $iItem = $iSelItem Then
                            DllStructSetData( $tCustDraw , "ClrTextBk", 0xADFF2F )
                        Else
                            DllStructSetData( $tCustDraw , "ClrTextBk",0xFFFFFF  )
                        EndIf
                    EndIf
    
                    
                    Return $CDRF_NEWFONT
                Case $LVN_ITEMCHANGED ; An item has changed
                    
                  Local $tNMLISTVIEW = DllStructCreate( $tagNMLISTVIEW, $ilParam )
                  _GUICtrlListView_RedrawItems( $hListView2, $iSelItem, $iSelItem )
                  $iSelItem = DllStructGetData( $tNMLISTVIEW, "Item" )
                  _GUICtrlListView_SetItemSelected( $hListView2, $iSelItem, False )         ; Remove selected state
                  _GUICtrlListView_SetItemState( $hListView2, $iSelItem, 0, $LVIS_FOCUSED ) ; Remove focused state

                    _CtrlSel($iIDFrom, $ilParam, $aShowdata2)
                    
                    
                Case $LVN_BEGINSCROLL ; 
                    If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2);
                Case $NM_CLICK;
                    If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2)
                    _chkboxState($iIDFrom, $ilParam, $aShowdata2)
                Case $NM_DBLCLK ; 
                   ; _StartItemEdit($iIDFrom, $ilParam, $aShowdata2)
            EndSwitch
 
    EndSwitch
    Return $GUI_RUNDEFMSG
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)
 
    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])
    DllStructSetData($tInfo, "Text", DllStructGetPtr($tText))
    DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]))
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);
    Else
        DllStructSetData($tCustDraw, "clrTextBk", $ihighBkClr);
        DllStructSetData($tCustDraw, "clrText", 0xFFFFFF) ;
    EndIf
EndFunc


Func _chkboxState($hlst, $ilParam, ByRef $aDataArray);
    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    $iIndex = DllStructGetData($tInfo, "Index")
    $x = DllStructGetData($tInfo, "X")
    If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;使用點擊的x座標來判斷是否在核取方塊上點擊
        If $aDataArray[$iIndex][3] = 4096 Then
            $ichked+=1
            $aDataArray[$iIndex][3] = 8192;
        Else
            $ichked-=1
            $aDataArray[$iIndex][3] = 4096;
        EndIf
        GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
    EndIf    
EndFunc


Func _CtrlSel($hlst, $ilParam, ByRef $aDataArray);
    If $bCtrlDown Then;
        $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
        Local $iIndex = DllStructGetData($tInfo, "Item")
        Local $iNewState = DllStructGetData($tInfo, "NewState")
        If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
            If $aDataArray[$iIndex][3] = 4096 Then
                $ichked+=1
                $aDataArray[$iIndex][3] = 8192;
            Else
                $ichked-=1
                $aDataArray[$iIndex][3] = 4096;
            EndIf
            $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
            DllStructSetData($tInfo, "State", $aDataArray[$iIndex][3]);
            GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
        EndIf
    EndIf
EndFunc

 

Edited by kklee69
Link to post
Share on other sites
#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
Global $hEdit, $Item = -1, $SubItem = 0
Global $hEnter, $aAccelKeys[1][2] = [["{ENTER}", $hEnter]]
$iSelItem=-1
Local $hUser32 = DllOpen("user32.dll")
Local $ichked = 0
Local $tText = DllStructCreate("wchar Text[256]")
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT][4], $aShowdata2[$iITEM_COUNT][4], $aShowdata3[$iITEM_COUNT][4]
Local $sSomeString = ""
Local $hGUI, $hListView, $hListView2, $hListView3
 
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView[" & UBound($aShowdata) & "]", 600, 605)
  
  
$hListView2 = GUICtrlCreateListView("$hListView2| | ", 300, 2, 295, 296, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT  + $LVS_EX_CHECKBOXES+ $LVS_EX_DOUBLEBUFFER);+ $LVS_EX_DOUBLEBUFFER
;~ _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);
_GUICtrlListView_SetImageList($hListView2, $hImage, 1);
 
GUISetState()
 

For $i = 0 To $iITEM_COUNT - 1

    If $i = 18 Then
        GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
    EndIf
    
   
    $aShowdata2[$i][0] = "2AA" & $i
    $aShowdata2[$i][1] = "2BB" & $i
    $aShowdata2[$i][2] = "2CC" & $i
    $aShowdata2[$i][3] = 4096;
    
    
Next
 
While 1
    $bCtrlDown = _IsPressed("11", $hUser32);
    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   
                Case -177 ; $LVN_GETDISPINFOW = -177   
                    _LVN_GETDISPINFO($iIDFrom, $ilParam, $aShowdata2)
                Case $LVN_COLUMNCLICK ; 
                    ;_SortItems($iIDFrom, $ilParam, $aShowdata2)
                Case $NM_CUSTOMDRAW;
                    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", $ilParam)
                    Local $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
                    ;_SetchkedBkClr($tCustDraw, $aShowdata2, 0x738393)
                ;Func _SetchkedBkClr(ByRef $tCustDraw, ByRef $aDataArray, $ihighBkClr = 0xF7D3AD, $idefBkclr = 0xFFFFFF)
                    Local $iIndex = DllStructGetData($tCustDraw, "ItemSpec")
                    #cs
                    IF $iItem = $iSelItem Then
                        DllStructSetData( $tCustDraw , "ClrTextBk", 0xADFF2F )
                    Else
                        DllStructSetData( $tCustDraw , "ClrTextBk",0xFFFFFF  )
                    EndIf
                    If $aShowdata2[$iIndex][3] = 4096 Then
                        DllStructSetData($tCustDraw, "clrTextBk", 0xFFFFFF);
                    Else
                        DllStructSetData($tCustDraw, "clrTextBk", 0x738393);
                        DllStructSetData($tCustDraw, "clrText", 0xFFFFFF) ;
                    EndIf
                    #ce
                    If $iIndex = $iSelItem And $aShowdata2[$iIndex][3] = 8192 Then
                        DllStructSetData( $tCustDraw , "ClrTextBk", 0x00FFFF )
                    ElseIf $iIndex = $iSelItem Then
                        DllStructSetData( $tCustDraw , "ClrTextBk", 0xADFF2F )
                    ElseIf $aShowdata2[$iIndex][3] = 8192 Then
                        DllStructSetData($tCustDraw, "clrTextBk", 0x738393);
                        DllStructSetData($tCustDraw, "clrText", 0xFFFFFF) ;
                    Else
                        DllStructSetData( $tCustDraw , "ClrTextBk",0xFFFFFF  )
                    EndIf
                ;EndFunc
                    
                    Return $CDRF_NEWFONT
                Case $LVN_ITEMCHANGED ; An item has changed
                  Local $tNMLISTVIEW = DllStructCreate( $tagNMLISTVIEW, $ilParam )
                  _GUICtrlListView_RedrawItems( $hListView2, $iSelItem, $iSelItem )
                  $iSelItem = DllStructGetData( $tNMLISTVIEW, "Item" )
                  _GUICtrlListView_SetItemSelected( $hListView2, $iSelItem, False )         ; Remove selected state
                  _GUICtrlListView_SetItemState( $hListView2, $iSelItem, 0, $LVIS_FOCUSED ) ; Remove focused state
                    
                    ;_CtrlSel($iIDFrom, $ilParam, $aShowdata2)
                    
                Case $LVN_BEGINSCROLL ; 
                    ;If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2);
                Case $NM_CLICK;
                    ;If IsHWnd($hEdit) Then _EndItemEdit($iIDFrom, $aShowdata2)
                    _chkboxState($iIDFrom, $ilParam, $aShowdata2)
                Case $NM_DBLCLK ; 
                   ; _StartItemEdit($iIDFrom, $ilParam, $aShowdata2)
            EndSwitch
 
    EndSwitch
    Return $GUI_RUNDEFMSG
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)
 
    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])
    DllStructSetData($tInfo, "Text", DllStructGetPtr($tText))
    DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]))
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);
    Else
        DllStructSetData($tCustDraw, "clrTextBk", $ihighBkClr);
        DllStructSetData($tCustDraw, "clrText", 0xFFFFFF) ;
    EndIf
EndFunc


Func _chkboxState($hlst, $ilParam, ByRef $aDataArray);
    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    $iIndex = DllStructGetData($tInfo, "Index")
    $x = DllStructGetData($tInfo, "X")
    If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;?????x???????????????
        If $aDataArray[$iIndex][3] = 4096 Then
            $ichked+=1
            $aDataArray[$iIndex][3] = 8192;
        Else
            $ichked-=1
            $aDataArray[$iIndex][3] = 4096;
        EndIf
        GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
    EndIf    
EndFunc


Func _CtrlSel($hlst, $ilParam, ByRef $aDataArray);
    If $bCtrlDown Then;
        $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
        Local $iIndex = DllStructGetData($tInfo, "Item")
        Local $iNewState = DllStructGetData($tInfo, "NewState")
        If $iIndex > -1 And $iNewState = BitOR($LVIS_FOCUSED, $LVIS_SELECTED) Then
            If $aDataArray[$iIndex][3] = 4096 Then
                $ichked+=1
                $aDataArray[$iIndex][3] = 8192;
            Else
                $ichked-=1
                $aDataArray[$iIndex][3] = 4096;
            EndIf
            $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
            DllStructSetData($tInfo, "State", $aDataArray[$iIndex][3]);
            GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
        EndIf
    EndIf
EndFunc

You should not use a function to execute code in a LVN_GETDISPINFOW or NM_CUSTOMDRAW section. This code should be very fast. Calling a function and passing parameters takes a long time.

Link to post
Share on other sites

Hello

I have a question with my programming language .

Here is the idea .

Why does It work when I use "checked" in the blocks ?

   _GUICtrlListView_SetItemSelected($hlst,$Item,True,True)

As foregoing , it will trun into blue which has been selected

 

but it doesn't work when I just select or "single-click" anywhere except the blocks ?

  _GUICtrlListView_SetItemSelected($hlst,$Item,True,True)

means only the item I selected will turn into blue but anothering else which I selected before will turn back to "unselected" means white .

How could I amend it to integrate the "single-click" and the "checked" ?

Means no matter I "check" in the block or select by "single-click'' except the block , I want to keep all the items I selected in blue and "checked" in the blocks .
In other words , how could I replace " CTRL + Single-Click " by "single-click" ?

 

未命名.jpg

 

#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
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]")
Local $GUI, $hImage
Local $iITEM_COUNT = 1000, $aShowdata[$iITEM_COUNT][4], $aShowdata2[$iITEM_COUNT][4], $aShowdata3[$iITEM_COUNT][4]
Local $sSomeString = ""
Local $hGUI, $hListView, $hListView2, $hListView3
 
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
$hGUI = GUICreate("ListView[" & UBound($aShowdata) & "]", 600, 605)
  
  
$hListView2 = GUICtrlCreateListView("$hListView2| | ", 300, 2, 295, 296, BitOR($LVS_REPORT,  $LVS_SHOWSELALWAYS, $LVS_OWNERDATA), $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT  + $LVS_EX_CHECKBOXES+ $LVS_EX_DOUBLEBUFFER);+ $LVS_EX_DOUBLEBUFFER
                                                                        ;$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);
_GUICtrlListView_SetImageList($hListView2, $hImage, 1);
 
GUISetState()
 

For $i = 0 To $iITEM_COUNT - 1

    If $i = 18 Then
        GUICtrlSendMsg($hListView, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView2, $LVM_REDRAWITEMS, 0, $i)
        GUICtrlSendMsg($hListView3, $LVM_REDRAWITEMS, 0, $i)
    EndIf
    
   
    $aShowdata2[$i][0] = "2AA" & $i
    $aShowdata2[$i][1] = "2BB" & $i
    $aShowdata2[$i][2] = "2CC" & $i
    $aShowdata2[$i][3] = 4096;
    
    
Next
 
While 1
    $bCtrlDown = _IsPressed("11", $hUser32);
    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 $LVN_ITEMCHANGED ; An item has changed
                   
                Case $LVN_BEGINSCROLL ; 
                    
                Case $NM_CLICK;
                    
                    _chkboxState($iIDFrom, $ilParam, $aShowdata2)
                Case $NM_DBLCLK ; 
                   
            EndSwitch
 
    EndSwitch
    Return $GUI_RUNDEFMSG
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)
 
    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])
    DllStructSetData($tInfo, "Text", DllStructGetPtr($tText))
    DllStructSetData($tInfo, "TextMax", StringLen($aDataArray[$iIndex][$iSub]))
EndFunc



Func _chkboxState($hlst, $ilParam, ByRef $aDataArray);
    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
    $iIndex = DllStructGetData($tInfo, "Index")
    $x = DllStructGetData($tInfo, "X")
    If ($x < 16) And (3 < $x) And (BitAND(_GUICtrlListView_GetExtendedListViewStyle($hlst), $LVS_EX_CHECKBOXES) = $LVS_EX_CHECKBOXES) Then;
        If $aDataArray[$iIndex][3] = 4096 Then
            $ichked+=1
            $aDataArray[$iIndex][3] = 8192;
            _GUICtrlListView_SetItemSelected($hlst,$iIndex,True,True)
        Else
            $ichked-=1
            $aDataArray[$iIndex][3] = 4096;
            _GUICtrlListView_SetItemSelected($hlst,$iIndex,False,True)
        EndIf
        GUICtrlSendMsg($hlst, $LVM_REDRAWITEMS, $iIndex, $iIndex)
        
    EndIf    
EndFunc

 

Edited by kklee69
Link to post
Share on other sites

_GUICtrlListView_SetItemSelected() don't know that you are removing the selected state of the selected item to be able to draw a custom background color. If you set selected item with _GUICtrlListView_SetItemSelected() it'll just be drawn with the default blue color. You have to implement your own code for _GUICtrlListView_SetItemSelected(). Or use other ways.


The method of custom drawing the background color of selected item by removing the selected state only works for single selections. It'll not work for multiple selections. Custom drawing the background color of multiple selections is much harder.

If you need multiple selections I'll recommend you to keep the blue default color.

If you insist in using a custom background color for multiple selected items, then it's easiest to first implement all other functionality, and then add code for the custom color as the last step when everything else is working.


The color for selected items is different when the listview has focus (default blue color) and has not focus (default button-face color (light grey)). If you also want to display seleceted items with a custom color when the listview has not focus you have to add code for that too.

Link to post
Share on other sites

YES I want use default color.

So my example did not change the color

You can see my jpg  picture


When I checked the four items THEN I selected  a new one

You can see the checked items Changed the color (NO color)
I hope they keep blue


AND  I hope when i selected item  will be automatic checked


This question has nothing to do with the item changing color
Just how could I replace " CTRL + Single-Click " by "single-click" ?

Link to post
Share on other sites

Oops, I thought it was still about the blue color.

Changing anything in relation to selections is tricky because it's very integrated in the operating system. It's probably possible to change ctrl+single-click to single-click but I don't think it can be done without subclassing the listview. I've never tried it myself. And I'll not recommend it. Changing default functionality can be very confusing for the users. How will you reset the selections again? This is normally done with a single-click. Will you use ctrl+single-click to reset? This will make your users even more confused. I'll recommend you to use other ways.

Link to post
Share on other sites

I see.


【Will you use ctrl+single-click to reset?】
I do not want to reset !! I want to Multiple selected !!

IN  Listview  You can have two ways to do multiple choice

1.  ONE is Use checked
2.  The other one is used ctrl+single-click


But in our ERP system We usually use 【single-click】.
When we click once  Meaning to selected a product
When we click again Meaning to unselected  a product
This is why I need  replace " CTRL + Single-Click " by "single-click"

 

Maybe we can use {CTRLDOWN} at the right time
AND use {CTRLUP} When we finish the selection
But I am very worried that will affect the user input.
And I do not know what time is right

Edited by kklee69
Link to post
Share on other sites

If you insist on using single-click instead of ctrl+single-click I'll see what I can do. But I probably need the weekend.

Link to post
Share on other sites

This is an example with a normal listview. It works in the same way for a virtual listview.

;#AutoIt3Wrapper_UseX64=y

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIShellEx.au3>
#include <GuiListView.au3>

Opt( "MustDeclareVars", 1 )

Global $idListView, $idAddSingleSel, $idDelSingleSel

Example()

Func Example()
  ; Create GUI
  GUICreate( "ctrl+single-click --> single-click", 420, 200 )

  ; Create ListView
  $idListView = GUICtrlCreateListView( "", 10, 10, 400, 180, $GUI_SS_DEFAULT_LISTVIEW-$LVS_SINGLESEL, $WS_EX_CLIENTEDGE )
  _GUICtrlListView_SetExtendedListViewStyle( $idListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT )
  Local $hListView = GUICtrlGetHandle( $idListView )

  ; Add columns to ListView
  _GUICtrlListView_InsertColumn( $idListView, 0, "Column 1", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 1, "Column 2", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 2, "Column 3", 94 )
  _GUICtrlListView_InsertColumn( $idListView, 3, "Column 4", 94 )

  ; Fill ListView
  Local $iItems = 100
  For $i = 0 To $iItems - 1
    GUICtrlCreateListViewItem( $i & "/Column 1|" & $i & "/Column 2|" & $i & "/Column 3|" & $i & "/Column 4", $idListView )
  Next

  ; Subclass ListView to receive keyboard/mouse messages
  Local $pListViewFunc = DllCallbackGetPtr( DllCallbackRegister( "ListViewFunc", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr" ) )
  _WinAPI_SetWindowSubclass( $hListView, $pListViewFunc, 0, 0 ) ; $iSubclassId = 0, $pData = 0

  ; Add/del single selection
  $idAddSingleSel = GUICtrlCreateDummy()
  $idDelSingleSel = GUICtrlCreateDummy()
  Local $iItem

  ; Show GUI
  GUISetState( @SW_SHOW )

  ; Message loop
  While 1
    Switch GUIGetMsg()
      Case $idAddSingleSel
        $iItem = GUICtrlRead( $idAddSingleSel )
        _GUICtrlListView_SetItemSelected( $idListView, $iItem, True )
        _GUICtrlListView_SetItemFocused( $idListView, $iItem )
      Case $idDelSingleSel
        $iItem = GUICtrlRead( $idDelSingleSel )
        _GUICtrlListView_SetItemSelected( $idListView, $iItem, False )
        _GUICtrlListView_SetItemFocused( $idListView, $iItem )
      Case $GUI_EVENT_CLOSE
        ExitLoop
    EndSwitch
  WEnd

  ; Cleanup
  _WinAPI_RemoveWindowSubclass( $hListView, $pListViewFunc, 0 )
  GUIDelete()
EndFunc

Func ListViewFunc( $hWnd, $iMsg, $wParam, $lParam, $iSubclassId, $pData )
  If $iMsg <> $WM_LBUTTONDOWN Then Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]

  Switch $wParam
    Case 0x0001  ; 0x0001 = MK_LBUTTON (LButton down)
      If _GUICtrlListView_GetSelectedCount( $idListView ) Then
        Local $aHit = _GUICtrlListView_HitTest( GUICtrlGetHandle( $idListView ), BitAND( $lParam, 0xFFFF ), BitShift( $lParam, 16 ) )
        If Not ( @error Or $aHit[0] = -1 ) Then
          If _GUICtrlListView_GetItemSelected( $idListView, $aHit[0] ) Then
            GUICtrlSendToDummy( $idDelSingleSel, $aHit[0] )
          Else
            GUICtrlSendToDummy( $idAddSingleSel, $aHit[0] )
          EndIf
        EndIf
        Return 0 ; Disable single-click in ListView to prevent resetting selections
      EndIf

    Case 0x0009  ; 0x0009 = MK_LBUTTON (LButton down) + MK_CONTROL (Ctrl down)
      Return 0   ; Disable single selections in ListView with ctrl+single-click
  EndSwitch

  Return DllCall( "comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam )[0]
  ; Call next function in subclass chain (this forwards messages to main GUI)
  #forceref $iSubclassId, $pData
EndFunc

 

Link to post
Share on other sites

Can I ask a question?

--------------------------------------------------------------------------
  ; Cleanup
  _WinAPI_RemoveWindowSubclass( $hListView, $pListViewFunc, 0 )
--------------------------------------------------------------------------

If I want to close the program , Can I exit directly without executing  _WinAPI_RemoveWindowSubclass?

What will happen ??  something bad ?? Will WINDOWS crash?

Should the memory have a mechanism for recycling?

SO... Can I exit directly without executing  _WinAPI_RemoveWindowSubclass?

Just want to know what will happen

This does not mean that I want to fail to follow the rules

Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...