Jump to content

Detect click and doubleclick on ListViewItem


jennico
 Share

Recommended Posts

Hi there !

the problem is: clicking on a listviewitem cannot be detected by guigetcursorinfo() or _ispressed('1').

i was not satisfied with the past solutions on this issue. i know that gary's script works perfectly, but there's a lot of dimming, dll reading and msgregistering which i could not integrate in my program.

so my idea is: the first click pops up a really small child gui at mouse position which disappears after the system's double click delay is passed.

so when you perform a double click the second one will hit the child gui and can so be detected.

i don't like the mousemove operation, but without it there will be passed a third click on the same spot and i don't know why this happens. maybe someone can improve that.

good luck

j.

;---------------------------------------
; my list view click and dclick solution
; without guiregistermsg()
; by jennico
;---------------------------------------
#include "GUIConstants.au3"
;-------main
Dim $pos1
$list_GUI=GUICreate("My listview click and dclick solution without guiregistermsg()",600,513)
$ListView=GUICtrlCreateListView("aaa|bbb|cccc|ddddddd|eeeeeeeee||fffffffffffff|gggggggggggggggggg|hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",10,55,580,400,BitOR($LVS_SHOWSELALWAYS,$LVS_NOSORTHEADER,$LVS_REPORT))
    GUICtrlSendMsg($ListView,$LVM_SETEXTENDEDLISTVIEWSTYLE,$LVS_EX_GRIDLINES,$LVS_EX_GRIDLINES)
    GUICtrlSendMsg($ListView,$LVM_SETEXTENDEDLISTVIEWSTYLE,$LVS_EX_FULLROWSELECT,$LVS_EX_FULLROWSELECT) 
For $i=1 To 100
    GUICtrlCreateListViewItem("1|2222222222222222|33333333333|7777777777|ttttttttttttttt|uuuuuuuuuuuuuuuuuuu|ggggggggggg|pppppppppppp",$ListView)
Next
$click=GUICtrlCreateLabel("Click:",10,20,100,20)
GUISetState()
;-------popup
$list_Popup=GUICreate("",1,1,0,0,$WS_POPUP,-1,$list_GUI);=> sizing variable
;-------loop
Do
    $msg=GUIGetMsg()
    If WinActive($list_Popup) Then
        GUICtrlSetData($click,"Click: Double !!!");=> your dclick event
        MouseMove(12+$pos1[0],53+$pos1[1],0)
        _UnPop()
    ElseIf WinActive($list_GUI) And $Msg=$GUI_EVENT_PRIMARYDOWN Then
        $pos=MouseGetPos()
        $pos1=WinGetPos($list_GUI)
        If $pos[0]-$pos1[0]>14 And $pos[0]-$pos1[0]<575 And $pos[1]-$pos1[1]>96 And $pos[1]-$pos1[1]<459 Then
            WinMove($list_Popup,"",$pos[0],$pos[1])
            GUICtrlSetData($click,"Click: Single");=>your click event
            GUISetState(@SW_SHOW,$list_Popup)
            WinActivate($list_GUI)
            $mousespeed=RegRead("HKCU\Control Panel\Mouse","DoubleClickSpeed")
            If $mousespeed="" Then $mousespeed=500
            AdlibEnable("_UnPop",$mousespeed)
        EndIf
    EndIf
Until $msg=-3
;-------func
Func _UnPop()
    GUISetState(@SW_HIDE,$list_Popup)
    AdlibDisable()
    WinActivate($list_GUI)
EndFunc
Edited by jennico
Spoiler

I actively support Wikileaks | Freedom for Julian Assange ! | Defend freedom of speech ! | Fight censorship ! | I will not silence.OixB7.jpgDon't forget this IP: 213.251.145.96

 

Link to comment
Share on other sites

Personally I have always found GuiRegisterMsg() to work perfectly. Your script works well except for that weird mousemove problem..

i know that gary's script works perfectly, but there's a lot of dimming, dll reading and msgregistering which i could not integrate in my program.

I think that is would always be possible to integrate GuiRegisterMsg()... Edited by Piano_Man
My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]
Link to comment
Share on other sites

i would really like to know why there is a third click and in what way it is performed. if you leave the mousemove line away, you can make experiments. i cannot explain this behaviour. can anyone ?

the idea of the little popup window could be a general model for enabling doubleclick detection on other controls like buttons where a doubleclick is not so easy to detect, either. i could imagine more indications.

in my "big" program (i have several thousands of listviewitems on 120 tabs) i noticed, that the guiregister method extremly reduced the scrolling and tabbing speed. but i did not investigate by what this was caused.

cheers j.

Edited by jennico
Spoiler

I actively support Wikileaks | Freedom for Julian Assange ! | Defend freedom of speech ! | Fight censorship ! | I will not silence.OixB7.jpgDon't forget this IP: 213.251.145.96

 

Link to comment
Share on other sites

ah, we're working on similar problems right now, eh ?

j.

I had similar problem but double click works for me for both TreeListView and ListView. This isn't working example as it did cut it out of my program. But it does work for me so maybe you can use parts of it. Function TreeItemFromPoint is done by someone else.

Func TreeItemFromPoint($hWnd)
    Local $tMPos = _WinAPI_GetMousePos(True, $hWnd)
    Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
EndFunc   ;==>TreeItemFromPoint
Func TreeListView_Click()
    If Not _GUICtrlTreeView_GetChildren($GUI_ServersView, TreeItemFromPoint($GUI_ServersView)) Then
        Local $server_choice = _GUICtrlTreeView_GetText($GUI_ServersView, TreeItemFromPoint($GUI_ServersView))
        GUICtrlSetData($GUI_Label[50], $server_choice)
        GUICtrlSetData($GUI_Label[51], _HashF_Get($server_choice, $SERVER_STATUS))
        GUICtrlSetData($GUI_Label[52], _HashF_Get($server_choice, $SERVER_PING) & "ms")
    EndIf
EndFunc   ;==>TreeListView_Click
Func TreeListView_DoubleClick()
    Local $server_choice = _GUICtrlTreeView_GetText($GUI_ServersView, TreeItemFromPoint($GUI_ServersView))
    If Not _GUICtrlTreeView_GetChildren($GUI_ServersView, TreeItemFromPoint($GUI_ServersView)) Then
        $test_variable = "no"
        For $a = 1 To UBound($target_servers) - 1
            If $target_servers[$a] = $server_choice Then
                $test_variable = "yes"
                ExitLoop
            EndIf
        Next
        If $test_variable = "no"  Then _ArrayAdd($target_servers, $server_choice)
    EndIf
    _GUICtrlListView_DeleteAllItems($GUI_ServersToCopyView)
    For $a = 1 To UBound($target_servers) - 1
        GUICtrlCreateListViewItem($target_servers[$a] & "|" & _HashF_Get($target_servers[$a], $TARGET_STATUS), $GUI_ServersToCopyView)
    Next
    $target_servers[0] = UBound($target_servers) - 1
EndFunc   ;==>TreeListView_DoubleClick
Func ListView_Click()

EndFunc   ;==>ListView_Click
Func ListView_DoubleClick()
    $server_to_remove = _GUICtrlListView_GetItemTextString($GUI_ServersToCopyView)
    $server_to_remove = StringTrimRight($server_to_remove, StringLen($server_to_remove) - StringInStr($server_to_remove, "|", 1, 1) + 1)
    $FindInArray = _ArraySearch($target_servers, $server_to_remove, 0, 0, 0, True)
    Select
        Case $FindInArray = -1
            ;MsgBox(0, "Not Found", '"' & $server_to_remove & '" was not found in the array.')
        Case Else
            _ArrayDelete($target_servers, $FindInArray)
            _GUICtrlListView_DeleteAllItems($GUI_ServersToCopyView)
            For $a = 1 To UBound($target_servers) - 1
                GUICtrlCreateListViewItem($target_servers[$a] & "|" & _HashF_Get($target_servers[$a], $TARGET_STATUS), $GUI_ServersToCopyView)
            Next
    EndSelect
    $target_servers[0] = UBound($target_servers) - 1
EndFunc   ;==>ListView_DoubleClick
Func WM_Notify_Events($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hwndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview
    Local $hTreeView = $GUI_ServersView
    Local $hListView = $GUI_ServersToCopyView
    $hWndTreeview = $hTreeView
    If Not IsHWnd($hTreeView) Then $hWndTreeview = GUICtrlGetHandle($hTreeView)
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
    
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hwndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hwndFrom
        Case $hWndTreeview
            Switch $iCode
                Case $NM_CLICK  ; The user has clicked the left mouse button within the control
                    TreeListView_Click()
                    Return 0 ; zero to allow the default processing
                Case $NM_DBLCLK  ; The user has double-clicked the left mouse button within the control
                    TreeListView_DoubleClick()
                    Return 0 ; zero to allow the default processing
                Case $NM_RCLICK  ; The user has clicked the right mouse button within the control
                    Return 0 ; zero to allow the default processing
                Case $NM_RDBLCLK  ; The user has clicked the right mouse button within the control
                    Return 0 ; zero to allow the default processing
                    ;Case $NM_KILLFOCUS ; control has lost the input focus
                    ; No return value
                    ;Case $NM_RETURN ; control has the input focus and that the user has pressed the key
                    ;    Return 0 ; zero to allow the default processing
                    ;Case $NM_SETCURSOR ; control is setting the cursor in response to a WM_SETCURSOR message
                    ;
                    ;Case $NM_SETFOCUS ; control has received the input focus
                    ; No return value
            EndSwitch
        Case $hWndListView
            Switch $iCode
                Case $LVN_COLUMNCLICK ; A column was clicked
                    
                Case $LVN_KEYDOWN ; A key has been pressed
                    
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    ListView_Click()
                Case $NM_DBLCLK ; Sent by a list-view control when the user double-clicks an item with the left mouse button
                    ListView_DoubleClick()
                Case $NM_HOVER ; Sent by a list-view control when the mouse hovers over an item
                    
                Case $NM_KILLFOCUS ; The control has lost the input focus
                    ; No return value
                Case $NM_RCLICK ; Sent by a list-view control when the user clicks an item with the right mouse button
                    Return 0 ; allow the default processing
                Case $NM_RDBLCLK ; Sent by a list-view control when the user double-clicks an item with the right mouse button
                    ; No return value
                Case $NM_RETURN ; The control has the input focus and that the user has pressed the ENTER key
                    ; No return value
                Case $NM_SETFOCUS ; The control has received the input focus
                    ; No return value
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_Notify_Events

My little company: Evotec (PL version: Evotec)

Link to comment
Share on other sites

well, that's part of the script i was basically talking about (by gary i think). works with registermsg and wm_notify and lots of variables to be declared.

j.

Edited by jennico
Spoiler

I actively support Wikileaks | Freedom for Julian Assange ! | Defend freedom of speech ! | Fight censorship ! | I will not silence.OixB7.jpgDon't forget this IP: 213.251.145.96

 

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