Jump to content

Adding a checkbox inside a listview/detecting change


Recommended Posts

Another relatively simple question, I was wonderign if someone could give me a command to reference in the help file in relation to adding checkboxes to a list view.

I also want to make it so only one check box can be selected, I think in order to do this I need to be able to detect when a checkbox is checked, and uncheck any others that have been checked, is there any way of detecting each time a checkbox is selected?

Link to comment
Share on other sites

  • Moderators

nullschritt,

I would do it like this:

#include <GUIConstantsEx.au3>
#include <GUIListView.au3>

$hGUI = GUICreate("Test", 500, 500)

$cListView = GUICtrlCreateListView("Column1", 10, 10, 480, 250, Default, $LVS_EX_CHECKBOXES)

$cStart = GUICtrlCreateDummy()
For $i = 0 To 9
    GUICtrlCreateListViewItem("Item " & $i, $cListView)
Next
$cEnd = GUICtrlCreateDummy()

GUISetState()

While 1

    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cStart + 1 To $cEnd - 1
            ; Which item was clicked - possibly on checkbox?
            $iIndex = $iMsg - ($cStart + 1)
            ; Is this item clicked?
            If _GUICtrlListView_GetItemChecked($cListView, $iIndex) Then
                ; Delete all checks
                For $i = 0 To _GUICtrlListView_GetItemCount($cListView) - 1
                    ; Except the one just made
                    If $i <> $iIndex Then
                        _GUICtrlListView_SetItemChecked($cListView, $i, False)
                    EndIf
                Next
            EndIf
    EndSwitch

WEnd
All clear? :)

 

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Hi,

I would do it this way as the main while will be more responsive :

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListView.au3>
 
Global Const $LVM_CHECKED = 8192, $LVM_UNCHECKED = 4096
 
Global $iLastItemChecked = -1
 
#region GUI
Local $hGUI = GUICreate("MyGUI", 500, 500)
 
Global $iLw1 = GUICtrlCreateListView("Column1", 10, 10, 480, 250, Default, $LVS_EX_CHECKBOXES)
 
For $i = 0 To 9
    GUICtrlCreateListViewItem("Item " & $i, $iLw1)
Next
 
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $hGUI)
#endregion
 
While GUIGetMsg() <> $GUI_EVENT_CLOSE
    Sleep(10)
WEnd
 
GUIDelete($hGUI)
 
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $iIDFrom = 0, $iCode = 0, $tNMHDR = 0, $tInfo = 0
 
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
 
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
 
    Switch $iIDFrom
        Case $iLw1
            Switch $iCode
                Case $LVN_ITEMCHANGING
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    $iNewState = DllStructGetData($tInfo, "NewState")
 
                    Switch $iNewState
                        Case $LVM_CHECKED
                            If $iLastItemChecked <> -1 Then
                                _GUICtrlListView_SetItemChecked($iLw1, $iLastItemChecked, False)
                            EndIf
 
                            $iLastItemChecked = DllStructGetData($tInfo, "Item")
                        Case $LVM_UNCHECKED
                            $iLastItemChecked = -1
                    EndSwitch
            EndSwitch
    EndSwitch
 
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
Link to comment
Share on other sites

 

Hi,

I would do it this way as the main while will be more responsive :

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListView.au3>
 
Global Const $LVM_CHECKED = 8192, $LVM_UNCHECKED = 4096
 
Global $iLastItemChecked = -1
 
#region GUI
Local $hGUI = GUICreate("MyGUI", 500, 500)
 
Global $iLw1 = GUICtrlCreateListView("Column1", 10, 10, 480, 250, Default, $LVS_EX_CHECKBOXES)
 
For $i = 0 To 9
    GUICtrlCreateListViewItem("Item " & $i, $iLw1)
Next
 
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $hGUI)
#endregion
 
While GUIGetMsg() <> $GUI_EVENT_CLOSE
    Sleep(10)
WEnd
 
GUIDelete($hGUI)
 
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $iIDFrom = 0, $iCode = 0, $tNMHDR = 0, $tInfo = 0
 
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
 
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
 
    Switch $iIDFrom
        Case $iLw1
            Switch $iCode
                Case $LVN_ITEMCHANGING
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    $iNewState = DllStructGetData($tInfo, "NewState")
 
                    Switch $iNewState
                        Case $LVM_CHECKED
                            If $iLastItemChecked <> -1 Then
                                _GUICtrlListView_SetItemChecked($iLw1, $iLastItemChecked, False)
                            EndIf
 
                            $iLastItemChecked = DllStructGetData($tInfo, "Item")
                        Case $LVM_UNCHECKED
                            $iLastItemChecked = -1
                    EndSwitch
            EndSwitch
    EndSwitch
 
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Thanks works great, but I am having one tiny problem, when I initially load the data from the database, I need to check to see which row is the primary row, and automatically check it, this I have done, HOWEVER, there is an issue with this, as this box will remain checked, until unchecked(unlike the other checkboxes, it will not automatically uncheck itself, allowing two boxes to be checked), is there a workaround for this, maybe a way to clear all checkboxes and then check the selected one?

Observe below:

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListView.au3>
 
Global Const $LVM_CHECKED = 8192, $LVM_UNCHECKED = 4096
 
Global $iLastItemChecked = -1
#region GUI
Local $hGUI = GUICreate("MyGUI", 500, 500)
 
Global $iLw1 = GUICtrlCreateListView("Column1|Column2", 10, 10, 480, 250, Default, $LVS_EX_CHECKBOXES)
 
 
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $hGUI)
#endregion
 
For $i = 0 To 9
$item = _GUICtrlListView_InsertItem($iLw1, "Item " & $i)
if $i=1 then
_GUICtrlListView_SetItemChecked($iLW1, $item)
EndIf
Next
 
While GUIGetMsg() <> $GUI_EVENT_CLOSE
    Sleep(10)
WEnd
 
GUIDelete($hGUI)
 
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $iIDFrom = 0, $iCode = 0, $tNMHDR = 0, $tInfo = 0
 
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
 
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
 
    Switch $iIDFrom
        Case $iLw1
            Switch $iCode
                Case $LVN_ITEMCHANGING
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    $iNewState = DllStructGetData($tInfo, "NewState")
 
                    Switch $iNewState
                        Case $LVM_CHECKED
                            If $iLastItemChecked <> -1 Then
                                _GUICtrlListView_SetItemChecked($iLw1, $iLastItemChecked, False)
                            EndIf
 
                            $iLastItemChecked = DllStructGetData($tInfo, "Item")
                        Case $LVM_UNCHECKED
                            $iLastItemChecked = -1
                    EndSwitch
            EndSwitch
    EndSwitch
 
    Return $GUI_RUNDEFMSG
EndFunc
Edited by nullschritt
Link to comment
Share on other sites

Try this,move the GUIRegisterMsg initialization to after the part where you set the checkbox to checked. This way, the windows message won't fire until AFTER you set it the first time.

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListView.au3>
Global Const $LVM_CHECKED = 8192, $LVM_UNCHECKED = 4096
Global $iLastItemChecked = 1
#region GUI
Local $hGUI = GUICreate("MyGUI", 500, 500)
Global $iLw1 = GUICtrlCreateListView("Column1|Column2", 10, 10, 480, 250, Default, $LVS_EX_CHECKBOXES)
GUISetState(@SW_SHOW, $hGUI)
#endregion GUI
For $i = 0 To 9
    $item = _GUICtrlListView_InsertItem($iLw1, "Item " & $i)
    If $i = 1 Then
        _GUICtrlListView_SetItemChecked($iLw1, $item)
    EndIf
Next
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
While GUIGetMsg() <> $GUI_EVENT_CLOSE
    Sleep(10)
WEnd
GUIDelete($hGUI)
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $iIDFrom = 0, $iCode = 0, $tNMHDR = 0, $tInfo = 0
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $iIDFrom
        Case $iLw1
            Switch $iCode
                Case $LVN_ITEMCHANGING
                    $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    $iNewState = DllStructGetData($tInfo, "NewState")
                    Switch $iNewState
                        Case $LVM_CHECKED
                            If $iLastItemChecked <> -1 Then
                                _GUICtrlListView_SetItemChecked($iLw1, $iLastItemChecked, False)
                            EndIf
                            $iLastItemChecked = DllStructGetData($tInfo, "Item")
                        Case $LVM_UNCHECKED
                            $iLastItemChecked = -1
                    EndSwitch
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

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...