Jump to content

Get Clicked on checkbox of ListView


Recommended Posts

This works.

[autoit]#include <GUIConstants.au3>

#include <GuiListView.au3>

#include "ListViewImageList.au3"

Global $Msg, $GUI, $hListView, $h_LV, $h_images, $image_indexes[3], $image_indexes2[3], $LVH_Bitmap, $h_images2

Global $ListView

Local Const $image_width = 16

Local Const $image_height = 16

Global Const $WM_NOTIFY = 0x004E

Global Const $NM_FIRST = 0

Global Const $NM_CLICK = ($NM_FIRST - 2)

Global Const $NM_DBLCLK = ($NM_FIRST - 3)

Global Const $NM_RCLICK = ($NM_FIRST - 5)

Global Const $LVN_FIRST = -100

Global Const $LVN_ITEMCHANGED = ($LVN_FIRST - 1)

Global $LVCLICKEDITEM[4]=[-1,-1]

Global $LVITEMCK[2]=[-1,0]

Opt("GUIOnEventMode", 1)

$GUI = GUICreate("lvCheckTest", 633, 447, 196, 117)

GuiSetOnEvent(-3,"ExitFunc")

$ListView = GUICtrlCreateListView("Some kind of list", 5, 10, 620, 390)

GUICtrlSetOnEvent(-1, "ListViewClick")

GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_CHECKBOXES, $LVS_EX_CHECKBOXES)

GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)

GUICtrlSendMsg($ListView, 0x101E, 0, 610)

$h_LV = GUICtrlGetHandle($ListView)

$h_images2 = _GUICtrlListViewCreateImageList($image_width, $image_height, 0x0021, 0, 4, 2)

$image_indexes2[0] = _GUICtrlListViewImageListAdd($h_images2, @WindowsDir & '\Cursors\arrow_m.cur')

$image_indexes2[1] = _GUICtrlListViewImageListAdd($h_images2, $AutoItIconsDir & '\filetype1.ico')

$image_indexes2[2] = _GUICtrlListViewImageListAdd($h_images2, @ScriptDir & '\blue.bmp', -1, $image_width, $image_height)

_GuiCtrlListViewSetImageList($h_LV, $h_images2, $LVSIL_SMALL)

Global $Status1 = GUICtrlCreateLabel("", 0, 428, 315, 17, $SS_SUNKEN)

Global $Status2 = GUICtrlCreateLabel("", 318, 428, 313, 17, $SS_SUNKEN)

GUISetState(@SW_SHOW)

Local $oldCursor = GUISetCursor(1,1)

MouseMove(MouseGetPos(0)+1,MouseGetPos(1)+1)

;Create a some items

For $x = 0 to 4099

GuiCtrlSetData($Status1,"Creating item:"&$x)

_GUICtrlListViewInsertItem($ListView,$x,"Checked LvItem #"&$x)

Next

GUICtrlSetData($Status1,"Done.")

GUISetCursor($oldCursor)

MouseMove(MouseGetPos(0)+1,MouseGetPos(1)+1)

;Start WndProc handler

GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

While 1

Sleep(100)

WEnd

Func ListViewClick()

ConsoleWrite("ListViewClick"&@LF)

EndFunc

Func _ListViewCheckedEvent()

ConsoleWrite("ListViewCheckedEvent"&@LF)

Local $state = _GUICtrlListViewGetCheckedState($ListView,$LVCLICKEDITEM[0])

ConsoleWrite(StringFormat("Item:%d Checked State is %d"&@LF,$LVCLICKEDITEM[0],$state))

GUICtrlSetData($Status1,StringFormat("Item:%d Checked State is %d"&@LF,$LVCLICKEDITEM[0],$state))

GuiCtrlSetData($Status2,"Checked Event = True")

If $state Then

_GUICtrlListViewSetItemImage($h_LV, $LVCLICKEDITEM[0], 0, 1)

Else

_GUICtrlListViewSetItemImage($h_LV, $LVCLICKEDITEM[0], 0, 0)

EndIf

EndFunc

Func _ListViewItemClick()

ConsoleWrite("_ListViewItemClick"&@LF)

Local $state = _GUICtrlListViewGetCheckedState($ListView,$LVCLICKEDITEM[0])

ConsoleWrite(StringFormat("Item:%d Checked State is %d"&@LF,$LVCLICKEDITEM[0],$state))

GUICtrlSetData($Status1,StringFormat("Item:%d Checked State is %d"&@LF,$LVCLICKEDITEM[0],$state))

GuiCtrlSetData($Status2,"Checked Event = False")

EndFunc

Func ListItemClicked()

ConsoleWrite(@GUI_CtrlId&@LF)

EndFunc

Func _ListViewShowContextMenu()

Local $ret =0

Local $pos = MouseGetPos()

;create context menu on demand.

If ($pos[0] <0 or $pos[1] <0) Then Return

Local $HelpCtx[7]

$HelpCtx[0]= GUICtrlCreateDummy()

$HelpCtx[1]= GUICtrlCreateContextMenu($HelpCtx[0])

$HelpCtx[2]= GUICtrlCreateMenuItem("Check All", $HelpCtx[1])

$HelpCtx[3]= GUICtrlCreateMenuItem("", $HelpCtx[1])

$HelpCtx[4]= GUICtrlCreateMenuItem("Clear All Checked", $HelpCtx[1])

$HelpCtx[5]= GUICtrlCreateMenuItem("", $HelpCtx[1])

$HelpCtx[6]= GUICtrlCreateMenuItem("Invert Checked", $HelpCtx[1])

GUISetState(@SW_SHOW)

Local $hMenu = GUICtrlGetHandle($HelpCtx[1])

;ClientToScreen(WinGetHandle($Gui), $aLVInfo[2], $aLVInfo[3])

Local $ctx = TrackPopupMenu(WinGetHandle($Gui), $hMenu,$pos[0],$pos[1])

;; do something with the result.

Switch $ctx

Case $HelpCtx[2]

_ChangeCheckedStateAll($ListView,1)

Case $HelpCtx[4]

_ChangeCheckedStateAll($ListView,0)

Case $HelpCtx[6]

_ChangeCheckedStateAll($ListView,2)

EndSwitch

;; clean up the context menu.

For $x =0 to UBound($HelpCtx)-1

GUICtrlDelete($HelpCtx[$x])

Next

Return $ret

EndFunc

Func ExitFunc()

_GUICtrlListViewDestroyImageList($h_images2)

_GUICtrlListViewReleaseBitMap($LVH_Bitmap)

Exit

EndFunc

Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)

#forceref $hWndGUI, $MsgID, $wParam

Local $tagNMHDR, $from, $pressed,$event, $retval = $GUI_RUNDEFMSG ;, $event

$tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)

If @error Then

$tagNMHDR =0

Return

EndIf

;$from = DllStructGetData($tagNMHDR, 1);not used

$event = DllStructGetData($tagNMHDR, 3)

Select

Case $wParam = $ListView

Select

Case $event = $NM_CLICK ;<<<<<<this happens before the item changes state

$LVCLICKEDITEM = _LVGetInfo($lParam) ; get the Item clicked

$LVITEMCK[0]= $LVCLICKEDITEM[0] ; retain the item

$LVITEMCK[1]= _GUICtrlListViewGetCheckedState($ListView,$LVCLICKEDITEM[0]); retain the state

Case $event = $NM_DBLCLK ;<<<<<<this happens before the item changes state

$LVCLICKEDITEM = _LVGetInfo($lParam) ; get the Item clicked

$LVITEMCK[0]= $LVCLICKEDITEM[0] ; retain the item

$LVITEMCK[1]= _GUICtrlListViewGetCheckedState($ListView,$LVCLICKEDITEM[0]); retain the state

Case $event = $LVN_ITEMCHANGED ;<<<<<<this happens after the item changes state

;make sure the item is still the same

$LVCLICKEDITEM = _LVGetInfo($lParam)

ConsoleWrite("--$LVCLICKEDITEM:"&$LVCLICKEDITEM[0]&@LF)

If $LVCLICKEDITEM[0] = $LVITEMCK[0] Then

;yes

_ListViewCheckedEvent() ; event handler for item checked

$LVITEMCK[0]=-1 ; reset

$LVITEMCK[1]=-1 ; reset

Else

_ListViewItemClick() ; default action.

EndIf

Case $event = $NM_RCLICK

_ListViewShowContextMenu()

EndSelect

EndSelect

$tagNMHDR = 0

$event = 0

$lParam = 0

Return $retval

EndFunc ;==>WM_Notify_Events

Func _LVGetInfo($lParam)

Local $aClicked[2]

Local $tagNMITEMACTIVATE = DllStructCreate("int;int;int;int;int;int;int;int;int", $lParam)

$aClicked[0] = DllStructGetData($tagNMITEMACTIVATE, 4)

$aClicked[1] = DllStructGetData($tagNMITEMACTIVATE, 5)

if $aClicked[1] < -1 then $aClicked[1] = -1

if $aClicked[0] < -1 then $aClicked[0] = -1

if $aClicked[1] > _GUICtrlListViewGetSubItemsCount($ListView) then $aClicked[1] = -1

if $aClicked[0] > _GUICtrlListViewGetItemCount($ListView) then $aClicked[0] = -1

$tagNMITEMACTIVATE = 0

Return $aClicked

EndFunc

Func _ChangeCheckedStateAll($h_LV,$state = 0)

Local $oldCursor = MouseGetCursor()

GUISetCursor(15,1)

Sleep(100)

Local $lvckstate

For $x =0 to _GUICtrlListViewGetItemCount($ListView)-1

Switch $state

Case 1

$lvckstate = 1

Case 2

$lvckstate = BitXOR(_GUICtrlListViewGetCheckedState($h_LV,$x),1)

Case Else

$lvckstate = 0

EndSwitch

_GUICtrlListViewSetCheckState($ListView,$x,$lvckstate)

GuiCtrlSetData($Status1,"Working..."&$x)

Next

GUISetCursor($oldCursor)

EndFunc

;;;ripped from help file.

; added TPM_RETURNCMD to uflags to get menu item return value.

; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd)

Func TrackPopupMenu($hWnd, $hMenu, $x, $y)

Local $v_ret = DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int",0X100, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)

Return $v_ret[0]

EndFunc

Edited by eltorro
Link to comment
Share on other sites

Create your ListViewItems in an array, then the Item number will correspond to the element number of the array which holds the CtrlId

Yes, that's it, thanks!

But i have notice in your example (from post #15 and #17 to), that the events are not saperated... i mean, how can i know the diferend between pressing the checkbox and selection of item itself - i tryed to remove the function _ListViewItemClick(), so i will see only results when checkbox clicked, but also get info when just item selected.

And i have another problem (it's just came to me :D ) - I need to be able set these checkboxes with pressing of Space bar key, but this function seems that check only clicks events, and also the list view have multiselection style, so when i select more than one item, and press space bar, i get seted only one checkbox (focused one) - i fixed this with _IsPressed() function (i put it in main loop), but how to combain this with all my needs about checking the checkboxes :)

randallc

My understanding is that LV items after 4096 or whatever do not have a control, so no ID!?

Yes, in my script it is a possibility to get over 4096 items in list view, but the chance that this will happend is small, very small (in this case the user will have to keep this much files in the same folder, and not just files, this is javascript files, so the chance that this is will happend is very small, but it's possible, so better to prevent problems if it happend).

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Hi @mscreator

Yes, in my script it is a possibility to get over 4096 items in list view, but the chance that this will happend is small, very small (in this case the user will have to keep this much files in the same folder, and not just files, this is javascript files, so the chance that this is will happend is very small, but it's possible, so better to prevent problems if it happend).

So why did you not just use post #5 in the first place!?

@eltorro, @gafrost

Fantastic!; so why had I not heard of that before?

Why is it not in standard UDF if we can beat the 4096 limit!?

best. randall

Link to comment
Share on other sites

Yes, that's it, thanks!

But i have notice in your example (from post #15 and #17 to), that the events are not saperated... i mean, how can i know the diferend between pressing the checkbox and selection of item itself - i tryed to remove the function _ListViewItemClick(), so i will see only results when checkbox clicked, but also get info when just item selected.

And i have another problem (it's just came to me :D ) - I need to be able set these checkboxes with pressing of Space bar key, but this function seems that check only clicks events, and also the list view have multiselection style, so when i select more than one item, and press space bar, i get seted only one checkbox (focused one) - i fixed this with _IsPressed() function (i put it in main loop), but how to combain this with all my needs about checking the checkboxes :)

randallc

Yes, in my script it is a possibility to get over 4096 items in list view, but the chance that this will happend is small, very small (in this case the user will have to keep this much files in the same folder, and not just files, this is javascript files, so the chance that this is will happend is very small, but it's possible, so better to prevent problems if it happend).

The code in post #21 has two functions,

_ListViewCheckedEvent()        ;called when a box is checked or unchecked.
_ListViewItemClick()               ;called when an item is clicked.
_ListViewShowContextMenu()     ;called on a right click.

The example also handles more than 4096 listview items.

I added a context menu to the listview control to check/uncheck/flip check each item.

see updated post #21

Link to comment
Share on other sites

@eltorro, @gafrost

Fantastic!; so why had I not heard of that before?

Why is it not in standard UDF if we can beat the 4096 limit!?

best. randall

Mainly because it uses GuiRegisterMsg and it would/could conflict with scripts that use GuiRegisterMsg already.

Also see here, Gary's post on the ListViewItem Images.

Link to comment
Share on other sites

eltorro

In the post 21 almoust all perfect, thanks again!

But there two things...

1) When the style $LVS_SINGLESEL is omited (not used), then when you trying to select more then 1 item, you see the line-trakcs of the selection.

2) If i use the space bar to check/uncheck the item(s), then the images not always set.

It can be acomplished?

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

Try this:

#include <GUIConstants.au3>
#include <GuiListView.au3>
#include "ListViewImageList.au3"
Global $Msg, $GUI, $hListView, $h_LV, $h_images, $image_indexes[3], $image_indexes2[3], $LVH_Bitmap, $h_images2
Global $ListView
Local Const $image_width = 16
Local Const $image_height = 16
Global Const $WM_NOTIFY = 0x004E
Global Const $NM_FIRST = 0
Global Const $NM_CLICK   = ($NM_FIRST - 2)
Global Const $NM_DBLCLK  = ($NM_FIRST - 3)
Global Const $NM_RCLICK  = ($NM_FIRST - 5)
Global Const $LVN_FIRST = -100
Global Const $LVN_ITEMCHANGED = ($LVN_FIRST - 1)
Global $LVCLICKEDITEM[4]=[-1,-1]
Global $LVITEMCK[2]=[-1,0]
Global $bCheckedEvent = False
Global $bListViewEvent = False
Global $bShowContext = False
Opt("GUIOnEventMode", 1)

$GUI = GUICreate("lvCheckTest", 633, 447, 196, 117)
GuiSetOnEvent(-3,"ExitFunc")
GuiSetOnEvent($GUI_EVENT_PRIMARYUP,"_CheckLVEvents")
$ListView = GUICtrlCreateListView("Some kind of list", 5, 10, 620, 390,BitOR($LVS_SHOWSELALWAYS,$LVS_REPORT))
GUICtrlSetOnEvent(-1, "ListViewClick")
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_CHECKBOXES, $LVS_EX_CHECKBOXES)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($ListView, 0x101E, 0, 610)
$h_LV = GUICtrlGetHandle($ListView)
    $h_images2 = _GUICtrlListViewCreateImageList($image_width, $image_height, 0x0021, 0, 4, 2)
    $image_indexes2[0] = _GUICtrlListViewImageListAdd($h_images2, @WindowsDir & "\Cursors\arrow_m.cur")
    $image_indexes2[1] = _GUICtrlListViewImageListAdd($h_images2, $AutoItIconsDir & "\filetype1.ico")
    $image_indexes2[2] = _GUICtrlListViewImageListAdd($h_images2, @ScriptDir & "\blue.bmp", -1, $image_width, $image_height)
    _GuiCtrlListViewSetImageList($h_LV, $h_images2, $LVSIL_SMALL)
Global $Status1 = GUICtrlCreateLabel("", 0, 428, 315, 17, $SS_SUNKEN)
Global $Status2 = GUICtrlCreateLabel("", 318, 428, 313, 17, $SS_SUNKEN)
GUISetState(@SW_SHOW)
Local $oldCursor = GUISetCursor(1,1,$GUI)
    MouseMove(MouseGetPos(0)+1,MouseGetPos(1)+1)

;Create a some items
For $x = 0 to 4099
    GuiCtrlSetData($Status1,"Creating item:"&$x)
    _GUICtrlListViewInsertItem($ListView,$x,"Checked LvItem #"&$x)
Next
GUICtrlSetData($Status1,"Done.")
    GUISetCursor(2,0,$GUI)
    
    MouseMove(MouseGetPos(0)+1,MouseGetPos(1)+1)

;Start WndProc handler
GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

While 1
    Sleep(100)
    _CheckLVEvents()
WEnd

Func ListViewClick()
    ConsoleWrite("ListViewClick"&@LF)
    
EndFunc
Func _CheckLVEvents()
    Select
    Case $bCheckedEvent 
        _ListViewCheckedEvent()
        $bCheckedEvent = False
    Case $bListViewEvent 
        _ListViewItemClick()
        $bListViewEvent = False
    EndSelect
EndFunc

Func _ListViewCheckedEvent($item = -1)
    ConsoleWrite("ListViewCheckedEvent"&@LF)
    _ListViewItemClick()
EndFunc
    
Func _ListViewItemClick()
    if $bShowContext then Return
    ConsoleWrite("_ListViewItemClick"&@LF)
    if _GUICtrlListViewGetSelectedCount($h_LV) > 1  Then
    Local $indces = _GUICtrlListViewGetSelectedIndices ($ListView,1)
        If IsArray($indces) Then
            For $x = 1 to $indces[0]
                Local $state = _GUICtrlListViewGetCheckedState($ListView,$indces[$x])
                ConsoleWrite(StringFormat("Item:%d  Checked State is %d"&@LF,$indces[$x],$state))
                GUICtrlSetData($Status1,StringFormat("Item:%d  Checked State is %d"&@LF,$indces[$x],$state))
                GuiCtrlSetData($Status2,"Checked Event = "&($state <> 0))
                If $state Then
                    _GUICtrlListViewSetItemImage($h_LV, $indces[$x], 0, 1)
                Else
                    _GUICtrlListViewSetItemImage($h_LV, $indces[$x], 0, 0)
                EndIf
            Next
        EndIf
    Else
    Local $state = _GUICtrlListViewGetCheckedState($ListView,$LVCLICKEDITEM[0])
        ConsoleWrite(StringFormat("Item:%d  Checked State is %d"&@LF,$LVCLICKEDITEM[0],$state))
        GUICtrlSetData($Status1,StringFormat("Item:%d  Checked State is %d"&@LF,$LVCLICKEDITEM[0],$state))
        GuiCtrlSetData($Status2,"Checked Event = "&($state <> 0))
        If $state Then
            _GUICtrlListViewSetItemImage($h_LV, $LVCLICKEDITEM[0], 0, 1)
        Else
            _GUICtrlListViewSetItemImage($h_LV, $LVCLICKEDITEM[0], 0, 0)
        EndIf
EndIf
EndFunc
Func ListItemClicked()
    ConsoleWrite(@GUI_CtrlId&@LF)
EndFunc
Func _ListViewShowContextMenu()
    Local $ret =0
    Local $pos = MouseGetPos()
    ;create context menu on demand.
    If ($pos[0] <0 or $pos[1] <0) Then Return
    Local $HelpCtx[7]
         $HelpCtx[0]= GUICtrlCreateDummy()
         $HelpCtx[1]= GUICtrlCreateContextMenu($HelpCtx[0])
         $HelpCtx[2]= GUICtrlCreateMenuItem("Check All", $HelpCtx[1])
         $HelpCtx[3]= GUICtrlCreateMenuItem("", $HelpCtx[1])
         $HelpCtx[4]= GUICtrlCreateMenuItem("Clear All Checked", $HelpCtx[1])
         $HelpCtx[5]= GUICtrlCreateMenuItem("", $HelpCtx[1])
         $HelpCtx[6]= GUICtrlCreateMenuItem("Invert Checked", $HelpCtx[1])
    GUISetState(@SW_SHOW)
   Local $hMenu = GUICtrlGetHandle($HelpCtx[1])
    ;ClientToScreen(WinGetHandle($Gui), $aLVInfo[2], $aLVInfo[3])
    Local $ctx = TrackPopupMenu(WinGetHandle($Gui), $hMenu,$pos[0],$pos[1])

;; do something with the result.
    GUISetCursor(15,1,$GUI)
    Switch $ctx
        Case $HelpCtx[2]
            _ChangeCheckedStateAll($h_LV,1)
        Case $HelpCtx[4]
            _ChangeCheckedStateAll($h_LV,0)
        Case $HelpCtx[6]
            _ChangeCheckedStateAll($h_LV,2)
    EndSwitch
    GUISetCursor(2,1,$GUI)
    ;; clean up the context menu.
    For $x =0 to UBound($HelpCtx)-1
        GUICtrlDelete($HelpCtx[$x])
    Next
    Return $ret
EndFunc

Func ExitFunc()
        _GUICtrlListViewDestroyImageList($h_images2)
        _GUICtrlListViewReleaseBitMap($LVH_Bitmap)
    Exit
EndFunc

Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $from, $pressed,$event, $retval = $GUI_RUNDEFMSG ;, $event
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then
        $tagNMHDR =0
        Return
    EndIf
    ;$from = DllStructGetData($tagNMHDR, 1);not used
    $event = DllStructGetData($tagNMHDR, 3)
    Select
        Case $wParam = $ListView
            Select
                Case $event = $NM_CLICK ;<<<<<<this happens before the item changes state
                    $LVCLICKEDITEM = _LVGetInfo($lParam) ; get the Item clicked
                    $LVITEMCK[0]= $LVCLICKEDITEM[0] ; retain the item
                    $LVITEMCK[1]= _GUICtrlListViewGetCheckedState($ListView,$LVCLICKEDITEM[0]); retain the state
                Case $event = $NM_DBLCLK ;<<<<<<this happens before the item changes state
                    $LVCLICKEDITEM = _LVGetInfo($lParam) ; get the Item clicked
                    $LVITEMCK[0]= $LVCLICKEDITEM[0] ; retain the item
                    $LVITEMCK[1]= _GUICtrlListViewGetCheckedState($ListView,$LVCLICKEDITEM[0]); retain the state
                Case $event = $LVN_ITEMCHANGED ;<<<<<<this happens after the item changes state
                    ;make sure the item is still the same
                    $LVCLICKEDITEM = _LVGetInfo($lParam)
                    ;ConsoleWrite("--$LVCLICKEDITEM:"&$LVCLICKEDITEM[0]&@LF)
                            If $LVCLICKEDITEM[0] = $LVITEMCK[0] Then
                                ;yes
                                $bCheckedEvent= True
                                ;_ListViewCheckedEvent() ; event handler for item checked
                                $LVITEMCK[0]=-1 ; reset
                                $LVITEMCK[1]=-1 ; reset
                            Else
                                $bListViewEvent = True
                                ;_ListViewItemClick() ; default action.
                            EndIf
                Case $event = $NM_RCLICK
                    $bShowContext = True        
                    ;_ListViewShowContextMenu()
                EndSelect
        EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
EndFunc   ;==>WM_Notify_Events

Func _LVGetInfo($lParam)
    Local $aClicked[2]
    Local $tagNMITEMACTIVATE = DllStructCreate("int;int;int;int;int;int;int;int;int", $lParam)
     $aClicked[0] = DllStructGetData($tagNMITEMACTIVATE, 4)
     $aClicked[1] = DllStructGetData($tagNMITEMACTIVATE, 5)
    if $aClicked[1] < -1 then $aClicked[1] = -1 
    if $aClicked[0] < -1 then $aClicked[0] = -1 
    if $aClicked[1] > _GUICtrlListViewGetSubItemsCount($ListView) then $aClicked[1] = -1 
    if $aClicked[0] > _GUICtrlListViewGetItemCount($ListView) then $aClicked[0] = -1 
    $tagNMITEMACTIVATE = 0
    Return $aClicked
EndFunc

Func _ChangeCheckedStateAll(ByRef $h_LV,$state = 0)
    Local $oldCursor = MouseGetCursor()
    GUISetCursor(15,1)
    Sleep(100)
    Local $lvckstate
        For $x =0 to _GUICtrlListViewGetItemCount($h_LV)-1
            Switch $state    
                Case 1
                    $lvckstate = 1

                Case 2
                    $lvckstate = BitXOR(_GUICtrlListViewGetCheckedState($h_LV,$x),1)
                Case Else    
                    $lvckstate = 0
            EndSwitch
            _GUICtrlListViewSetCheckState($h_LV,$x,$lvckstate)
            If    $lvckstate Then
                _GUICtrlListViewSetItemImage($h_LV, $x, 0, 1)
            Else
                _GUICtrlListViewSetItemImage($h_LV, $x, 0, 0)
            EndIf
            GuiCtrlSetData($Status1,"Working..."&$x)
        Next
        GUISetCursor($oldCursor,1)
EndFunc

;;;ripped from help file.
; added TPM_RETURNCMD to uflags to get menu item return value.
; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd)
Func TrackPopupMenu($hWnd, $hMenu, $x, $y)
    Local $v_ret = DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int",0X100, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0)
    Return $v_ret[0]
EndFunc

It appears that the WM_Notify_Events must return for the screen update on the Listview to update properly.

Edit: Fixed spacebar select.

Edit: Fixed forum insertion of &apos;

Edited by eltorro
Link to comment
Share on other sites

Hi,

Thanks for all that!

Spacebar click still not working for me, though.

Is there a way to add the icon associated with a file to the image used in this function, like with CtrlSetImage for a LVitem with controlID?

Best, randall

Link to comment
Share on other sites

Hi,

Thanks for all that!

Spacebar click still not working for me, though.

Fixed. See modified post above.

Is there a way to add the icon associated with a file to the image used in this function, like with CtrlSetImage for a LVitem with controlID?

Best, randall

Associate the system image list with the listview. I'll look into it.

Edited by eltorro
Link to comment
Share on other sites

Try this:

Thanks! this is perfect now! I am very appreciate for all the effort and the time that you put into this.

And thanks to all ho tryed to help me, now the work with List View will be much more practical :).

Edit:

P.S

In the example there is somthing not right...

...
_GUICtrlListViewImageListAdd($h_images2, @WindowsDir & &apos;\Cursors\arrow_m.cur&apos;)
...

The &apos; should be " - i think this is a forum mistake.

Edited by MsCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Link to comment
Share on other sites

P.S

In the example there is somthing not right...

...
    _GUICtrlListViewImageListAdd($h_images2, @WindowsDir   & &apos;\Cursors\arrow_m.cur&apos;)
    ...

The &apos; should be " - i think this is a forum mistake.

:)

Edited by eltorro
Link to comment
Share on other sites

Hi,

Just for interest, I have this working for ordinary AutoIt built in listView, checkbox click or spacebar, unlimited number of items etc;/ no need for new Image funcs, or GUIReg, or WMnotify;

Best, Randall

;getcheckclick.au3
#include "_GUICtrlListViewUDF1LVregisterSort.au3"
Opt("GuiOnEventMode", 1)
$GUI = GUICreate("Test")
GUISetOnEvent(-3, "Quit")
_GUISetCheckBoxesPresent (1);******************************
$ListView = _GUICtrlCreateListViewIndexed ("Column1", 20, 40, 250, 250, $WS_VSCROLL, $LVS_EX_CHECKBOXES + $LVS_EX_GRIDLINES)
;~ $ListView = _GUICtrlCreateListView ("Column1", 20, 40, 250, 250, -1, $LVS_EX_CHECKBOXES + $WS_EX_OVERLAPPEDWINDOW)
GUICtrlSetImage(-1, "shell32.dll", 3)
$GUICtrlSetImage = 1
Global $i_CheckedDefault = 0
Local $i_BotIndex
$i_DefaultIconNumber= 0 
GUISetState()
For $i = 1 To 42;00;0;42;00
    _GUICtrlCreateListViewItem ("Item" & $i, $ListView, -1, 0, 1)
    GUICtrlSetOnEvent(-1, "_LVHit")
Next
;~ _GUICtrlListViewHideColumn($ListView, 1)
_GUICtrlListViewSetColumnWidth($ListView, 0, $LVSCW_AUTOSIZE)
GUISetState()
While 1
    $GetMouseInfo = GUIGetCursorInfo($GUI)
    If ($GetMouseInfo[2] = 1 And $GetMouseInfo[4] = $ListView) Then
        $i_LVitemNumber = _GUICtrlListViewGetCurCheckClick($ListView, $i_BotIndex); so it is not doubling up on a hit; only accepts if an Insert item, no controlID
        If ($i_LVitemNumber > -1 And Not $ar_LISTVIEW[$i_LVitemNumber + 1]) Then _GUICtrlListViewDraw($ListView, $i_LVitemNumber, $i_BotIndex)
    EndIf
    If _IsPressed("20") Then ; Spacebar
        Local $indces = _GUICtrlListViewGetSelectedIndices($ListView, 1), $i_ImageNum = 22
        If IsArray($indces) Then
            $i_LVitemNumber = $indces[1]
            If Not $ar_LISTVIEW[$i_LVitemNumber + 1] Then ;LV item has no ControlID
                _GUICtrlListViewDraw($ListView, $i_LVitemNumber, $i_BotIndex)
            Else ;LV item has ControlID
                _SetImage($ListView, $ar_LISTVIEW[$i_LVitemNumber + 1], $i_LVitemNumber)
            EndIf
        EndIf
    EndIf
    Sleep(10)
WEnd
Func _GUICtrlListViewGetCurCheckClick($h_listview, ByRef $_GUICtrlListViewGetBottomIndex)
    $_GUICtrlListViewGetBottomIndex = _GUICtrlListViewGetTopIndex($ListView) + _GUICtrlListViewGetCounterPage($ListView)
    $_GUICtrlListViewGetBottomIndex = _Iif($_GUICtrlListViewGetBottomIndex > $i_LISTVIEWNumItemsView, $i_LISTVIEWNumItemsView, $_GUICtrlListViewGetBottomIndex)
    For $i = _GUICtrlListViewGetTopIndex($ListView) + 1 To $_GUICtrlListViewGetBottomIndex
        If _GUICtrlListViewGetItemText($ListView, $i - 1, _GUICtrlListViewGetSubItemsCount($ListView) - 1) <> _GUICtrlListViewGetCheckedState($ListView, $i - 1) Then ExitLoop
    Next
    If $i > $_GUICtrlListViewGetBottomIndex Then Return -1
    $ar_LISTVIEWArray[$i] = StringTrimRight($ar_LISTVIEWArray[$i], 1) & _GUICtrlListViewGetCheckedState($ListView, $i - 1)
    Return $i - 1
EndFunc   ;==>_GUICtrlListViewGetCurCheckClick
Func _GUICtrlListViewDraw($lv, $i_NumItemsView, $_GUICtrlListViewGetBottomIndex)
    $_GetCheckedState = _GUICtrlListViewGetCheckedState($lv, $i_LVitemNumber)
    _Lock ()
    Local $timerstamp = TimerInit(), $i_ImageNum = 22
    For $i = $i_LISTVIEWNumItemsView To $i_NumItemsView Step - 1
        _GUICtrlListViewDeleteItem($ListView, $i)
    Next
    ; Swap a LV Item created; for an inserted, so image can be applied ===================
    For $i = $i_NumItemsView - 1 To 0 Step - 1
        If Not Number(StringRight($ar_LISTVIEWArray[$i + 1], 1)) Then ; so default check state;
            _GUICtrlListViewDeleteItem($lv, $i)
            _GUICtrlListViewInsertItem($lv, $i, $ar_LISTVIEWArray[$i + 1])
            $ar_LISTVIEW[$i + 1] = 0
            ExitLoop
        EndIf
    Next
    If UBound($ar_LISTVIEW) < $i_NumItemsView + 1 Then ReDim $ar_LISTVIEW[UBound($ar_LISTVIEWArray) ]
    $ar_LISTVIEWArray[$i_NumItemsView + 1] = StringTrimRight($ar_LISTVIEWArray[$i_NumItemsView + 1], 1) & _GUICtrlListViewGetCheckedState($ListView, $i_NumItemsView)
    $ar_LISTVIEW[$i_NumItemsView + 1] = GUICtrlCreateListViewItem($ar_LISTVIEWArray[$i_NumItemsView + 1], $lv)
    GUICtrlSetOnEvent(-1, "_LVHit")
    If Not $_GetCheckedState Then $i_ImageNum = 3
    GUICtrlSetImage(-1, "shell32.dll", $i_ImageNum)
    _GUICtrlListViewSetCheckState($lv, $i_NumItemsView, $_GetCheckedState)
    ; ====================================================================================
    For $a = $i_NumItemsView + 1 To $i_LISTVIEWNumItemsView - 1
        If Number(StringRight($ar_LISTVIEWArray[$a + 1], 1)) Or $ar_LISTVIEW[$a + 1] Then
            $ar_LISTVIEW[$a + 1] = GUICtrlCreateListViewItem($ar_LISTVIEWArray[$a + 1], $lv)
            GUICtrlSetOnEvent(-1, "_LVHit")
            GUICtrlSetImage(-1, "shell32.dll", _Iif(Number(StringRight($ar_LISTVIEWArray[$a + 1], 1)), 22, 3))
        Else
            _GUICtrlListViewInsertItem($lv, -1, $ar_LISTVIEWArray[$a + 1])
        EndIf
        _GUICtrlListViewSetCheckState($lv, $a, Number(StringRight($ar_LISTVIEWArray[$a + 1], 1)))
        If $a = $i_NumItemsView Then MsgBox(0, "", "")
    Next
    ConsoleWrite("aFT LISTVIEW img:" & TimerDiff($timerstamp) & " mseconds to search." & @LF)
    _GUICtrlListViewEnsureVisible($lv, $_GUICtrlListViewGetBottomIndex - 1, 1)
    _ResetLock ()
EndFunc   ;==>_GUICtrlListViewDraw
Func _LVHit()
    For $i = 0 To $i_LISTVIEWNumItemsView
        If @GUI_CtrlId = $ar_LISTVIEW[$i] Then
            _SetImage($ListView, @GUI_CtrlId, $i - 1)
            ExitLoop
        EndIf
    Next
EndFunc   ;==>_LVHit
Func Quit()
    Exit
EndFunc   ;==>Quit
Func _SetImage($lv, $i_ID, $i_Item)
    Local $i_ImageNum = 22
    If Not _GUICtrlListViewGetCheckedState($lv, $i_Item) Then $i_ImageNum = 3
    $ar_LISTVIEWArray[$i_Item + 1] = StringTrimRight($ar_LISTVIEWArray[$i_Item + 1], 1) & _GUICtrlListViewGetCheckedState($lv, $i_Item)
    GUICtrlSetData($ar_LISTVIEW[$i_Item + 1], $ar_LISTVIEWArray[$i_Item + 1])
    GUICtrlSetImage($ar_LISTVIEW[$i_Item + 1], "shell32.dll", $i_ImageNum)
EndFunc   ;==>_SetImage
Link to comment
Share on other sites

@randallc,

That great!

Any way to speed it up? There's a delay with the image changing with the inserted items.

ElTorro

Edited by eltorro
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...