Jump to content

Capturing click on ListView rather than on ListViewItem


Recommended Posts

Hi, all,

I've got a ListView with an arbitrary list of ListViewItems. There are two action buttons that are disabled when no items are selected, enabled when an item is selected. They are disabled on GUI creation. So I've got a function that checks the status of the ListView; it uses _GUICtrlListView_GetSelectedCount and if the returned number is 0 it disables both buttons; otherwise it enables them both.

Here's the problem: if I assign the onEvent handler to the ListView itself, the clicks aren't registered. If I assign the handler to the ListViewItems, then it is registered. The challenge is that if I DESELECT from the ListView by clicking somewhere in the geography of the ListView that is not occupied by a ListViewItem, then that click isn't captured and the function does not run, leaving the two action buttons enabled even though no ListViewItems are selected. Is this expected behavior, and if not what method should I use to capture the click on the View rather than the ViewItems? Code below.

Global $listview = GUICtrlCreateListView("Title",20,367,360,200,BitOR($LVS_NOCOLUMNHEADER,$LVS_SINGLESEL))
GUICtrlSetOnEvent($listview,"checkList")
Link to comment
Share on other sites

  • Moderators

lkalliance,

I am not going to srite a whole script to test this, but I would hazard a guess that the ListView items remain selected even though you click elsewhere in the ListView unless you also use something like _GUICtrlListView_SetItemSelected to remove the "selected" state from the selected items. The fact that you can use the $LVS_SHOWSELALWAYS style reinforces my opinion. :)

If you would care to post a working example of the problem rather then just 2 lines of code, I would be happy to investigate further. :)

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

lkalliance,

I am not going to srite a whole script to test this, but I would hazard a guess that the ListView items remain selected even though you click elsewhere in the ListView unless you also use something like _GUICtrlListView_SetItemSelected to remove the "selected" state from the selected items. The fact that you can use the $LVS_SHOWSELALWAYS style reinforces my opinion. :)

If you would care to post a working example of the problem rather then just 2 lines of code, I would be happy to investigate further. :)

M23

LOL, thanks, Melba. I will investigate based on your recommendations, and I will post what I find here, with more code detail, regardless of success.

Link to comment
Share on other sites

OK, I've cleared out the baggage of my existing script and done a clean one to test this:

#include <GUIConstantsEx.au3>
#Include <GuiListView.au3>
#include <ListviewConstants.au3>


Opt("GUIOnEventMode",1)

Dim $GUImain = GUICreate("Test controls",500,600)
GUISetOnEvent($GUI_EVENT_CLOSE,"endScript")
Dim $listLabel = GUICtrlCreateLabel("Hoping to register a click on the ListView below. Close this window to exit.",20,30,400,40)
Dim $listView = GUICtrlCreateListView("Action",20,75,400,150,BitOR($LVS_NOCOLUMNHEADER,$LVS_SINGLESEL))
GUICtrlSetOnEvent($listView,"alertonclick")
_GUICtrlListView_SetColumnWidth($listView,0,385)
GUICtrlCreateListViewItem("Click on me, you know you wanna",$listView)
GUICtrlCreateListViewItem("No, pick me! Pick me!",$listView)
GUICtrlCreateListViewItem("Humph. I didn't want you to click on me, anyway.",$listView)
GUISetState(@SW_SHOW)

Func alertonclick()
    MsgBox(0,"Capture the click","Hey!, you clicked on the list! " _
        &"I don't care what item you clicked, " _
        &"I'm just happy to be a part of your life")
EndFunc
    
Func endScript()
    MsgBox(0,"You're leaving?","We'll always have Paris.")
    Exit
EndFunc

While 1
    Sleep(1000)
WEnd

A couple things I've noticed:

(a) Having attached the onEvent handler to the ListView in this example, and not to the items, it does NOT register and send the user to the correct function. If I move the GUICtrlSetOnEvent command and apply it to one of the ListViewItems, then it DOES work if that item is clicked.

(1) It does appear that clicking on the "empty space" of the ListView does not deselect the currently selected item; it does leave a selection border there. This visual artifact does not, by the way, occur on my original script, though I do not have any different styles set there.

Any thoughts? The visual feedback provided to the user in my script does not leave the ghosted selection visible as it does in the sample script: it suggests that there is in fact no selected Item. And there is still the matter of setting the ListView onEvent handler to fire on clicks.

One hypothesis is that clicking on the blank space, since it might not actually deselect all items, might not trigger an event because nothing is happening (i.e. Item N was selected before the click, and is selected after the click, therefore nothing "happened"). BUT if that is what's happening, then why don't I get feedback when I DO have a legitimate change (selection changes)?

Link to comment
Share on other sites

Further experiment: I altered my action button on my original script to generate a message box that shows how many selected items are in the ListView:

--Item selected, button pressed -> "1". Item highlight disappears and APPEARS to be deselected

--Immediate second action button click -> "1". Item clearly IS still highlighted.

--Click in blank area, button pressed -> "0". All items DO appear to be deselected when clicking in the blank area.

Link to comment
Share on other sites

  • Moderators

lkalliance,

Interesting little problem. :)

I have got this to work - a bit of a work-around, but it seems to do what you want: :)

#include <GUIConstantsEx.au3>
#Include <GuiListView.au3>
#include <ListviewConstants.au3>

Opt("GUIOnEventMode",1)

Dim $GUImain = GUICreate("Test controls",500,600)
GUISetOnEvent($GUI_EVENT_CLOSE,"endScript")

; Look for a mouse down event
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "Clicker")

Dim $listLabel = GUICtrlCreateLabel("Hoping to register a click on the ListView below. Close this window to exit.",20,30,400,40)

Dim $listView = GUICtrlCreateListView("Action",20,75,400,150,BitOR($LVS_NOCOLUMNHEADER,$LVS_SINGLESEL))

_GUICtrlListView_SetColumnWidth($listView,0,385)

GUICtrlCreateListViewItem("Click on me, you know you wanna",$listView)
GUICtrlCreateListViewItem("No, pick me! Pick me!",$listView)
GUICtrlCreateListViewItem("Humph. I didn't want you to click on me, anyway.",$listView)

$hButton = GUICtrlCreateButton("", 10, 250, 80, 30)
GUICtrlSetState(-1, $GUI_DISABLE)

GUISetState(@SW_SHOW)

Func endScript()
    Exit
EndFunc

Func Clicker()
    ; Is the ListView focused
    If _WinAPI_GetFocus() <> GUICtrlGetHandle($listView) Then
        ; Return if not
        Return
    Else
        ; Are any items selected
        $iCount = _GUICtrlListView_GetSelectedCount($listView)
        ; Set the button text
        GUICtrlSetData($hButton, $iCount)
        If $iCount Then
            ; If items selected then enable button
            GUICtrlSetState($hButton, $GUI_ENABLE)
        Else
            ; If not then disable button
            GUICtrlSetState($hButton, $GUI_DISABLE)
        EndIf
    EndIf
EndFunc

While 1
    Sleep(1000)
WEnd

Now I shall wait for Mat to come and tell me I am displaying my "hobbyist coder" behaviour again by not doing something really sexy with GUIRegisterMsg! :P

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

lol@GUIRegisterMsg. I looked at those bits in the help file, and I felt that I was opening up a can of worms that didn't need opening. But to a man with a hammer...

I will play around with the solution you've got here. It's a workaround but it at least doesn't create major WTF code overhead. I fall in the "hobbyist" bucket too. :)

In further testing, I've found that "$LVS_SHOWSELALWAYS"...er, doesn't work. Perhaps I'm not declaring it correctly. But if there are other GUI controls in the window, the selection ceases showing if the ListView loses focus. Sometimes the correct selection comes back when I reattain focus; sometimes it doesn't (I haven't done enough experiments yet to figure out what conditions account for the inconsistency). Perhaps it has to do with intervening scripts? Perhaps the act of examining with, say, _GUICtrlListView_GetSelectedCount does something funky?

Link to comment
Share on other sites

  • Moderators

lkalliance,

"$LVS_SHOWSELALWAYS"...er, doesn't work

I used to think that too. :P

The problem is that in Windows the default colour for "selected but not focused" is nearly the same as the default background colour of the ListView. Try colouring the ListView with GUICtrlSetBkColor and see if it stands out better then. :)

M23

Edit:

You might find my GUIRegisterMsg tutorial in the Wiki useful if you do not use it much. :)

Edited by Melba23

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

  • Moderators

lkalliance,

That is one you will never forget from now on! :)

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

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