Jump to content

double click in autoit3 how ?


Recommended Posts

Are you wanting to detect when the label is double clicked? Here's one way

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <WinApi.au3>

Global $hGUI = GUICreate("Double Click", 144, 144)
Global $lblLabel = GUICtrlCreateLabel("Double click this!" & @CRLF & "For something cool", 10, 10)
Global $hWnd_wndproc = DllCallbackRegister("NewWndProc", "ptr", "hwnd;uint;wparam;lparam")
Global $ptr_new_wndproc = DllCallbackGetPtr($hWnd_wndproc)
Global $ptr_old_wndproc = _WinAPI_SetWindowLong(GUICtrlGetHandle($lblLabel), $GWL_WNDPROC, $ptr_new_wndproc)

GUISetState(@SW_SHOW, $hGUI)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hGUI)
            DllCallbackFree($hWnd_wndproc)
            Exit 0

        Case $lblLabel
            ConsoleWrite("Label clicked" & @LF)
    EndSwitch
WEnd

Func NewWndProc($hWndFrom, $iMsg, $wParam, $lParam)
    Switch $hWndFrom
        Case GUICtrlGetHandle($lblLabel)
            Switch $iMsg
                Case $WM_LBUTTONDBLCLK
                    ConsoleWrite("Label Double clicked!" & @LF)
                    MsgBox("", "Double Click!", "You double clicked my label!")
            EndSwitch
    EndSwitch

    Return _WinAPI_CallWindowProc($ptr_old_wndproc, $hWndFrom, $iMsg, $wParam, $lParam)
EndFunc   ;==>NewWndProc

Here's another one using WM_COMMAND

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <WinApi.au3>

Global $hGUI = GUICreate("Double Click", 144, 144)
Global $lblLabel = GUICtrlCreateLabel("Double click this!" & @CRLF & "For something cool", 10, 10)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

GUISetState(@SW_SHOW, $hGUI)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hGUI)
            Exit 0

        Case $lblLabel
            ConsoleWrite("Label clicked" & @LF)
    EndSwitch
WEnd

Func WM_COMMAND($hWndFrom, $iMsg, $wParam, $lParam)
    Local $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    Local $iCode = BitShift($wParam, 16) ; Hi Word

    Switch ($hWndFrom)
        Case $hGUI
            Switch ($iIDFrom)
                Case $lblLabel
                    If ($iCode) Then
                        ConsoleWrite("Label Double clicked!" & @LF)
                        MsgBox("", "Double Click!", "You double clicked my label!")
                    EndIf
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

 

Link to comment
Share on other sites

21 hours ago, InunoTaishou said:

Are you wanting to detect when the label is double clicked? Here's one way

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <WinApi.au3>

Global $hGUI = GUICreate("Double Click", 144, 144)
Global $lblLabel = GUICtrlCreateLabel("Double click this!" & @CRLF & "For something cool", 10, 10)
Global $hWnd_wndproc = DllCallbackRegister("NewWndProc", "ptr", "hwnd;uint;wparam;lparam")
Global $ptr_new_wndproc = DllCallbackGetPtr($hWnd_wndproc)
Global $ptr_old_wndproc = _WinAPI_SetWindowLong(GUICtrlGetHandle($lblLabel), $GWL_WNDPROC, $ptr_new_wndproc)

GUISetState(@SW_SHOW, $hGUI)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hGUI)
            DllCallbackFree($hWnd_wndproc)
            Exit 0

        Case $lblLabel
            ConsoleWrite("Label clicked" & @LF)
    EndSwitch
WEnd

Func NewWndProc($hWndFrom, $iMsg, $wParam, $lParam)
    Switch $hWndFrom
        Case GUICtrlGetHandle($lblLabel)
            Switch $iMsg
                Case $WM_LBUTTONDBLCLK
                    ConsoleWrite("Label Double clicked!" & @LF)
                    MsgBox("", "Double Click!", "You double clicked my label!")
            EndSwitch
    EndSwitch

    Return _WinAPI_CallWindowProc($ptr_old_wndproc, $hWndFrom, $iMsg, $wParam, $lParam)
EndFunc   ;==>NewWndProc

Here's another one using WM_COMMAND

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <WinApi.au3>

Global $hGUI = GUICreate("Double Click", 144, 144)
Global $lblLabel = GUICtrlCreateLabel("Double click this!" & @CRLF & "For something cool", 10, 10)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

GUISetState(@SW_SHOW, $hGUI)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hGUI)
            Exit 0

        Case $lblLabel
            ConsoleWrite("Label clicked" & @LF)
    EndSwitch
WEnd

Func WM_COMMAND($hWndFrom, $iMsg, $wParam, $lParam)
    Local $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    Local $iCode = BitShift($wParam, 16) ; Hi Word

    Switch ($hWndFrom)
        Case $hGUI
            Switch ($iIDFrom)
                Case $lblLabel
                    If ($iCode) Then
                        ConsoleWrite("Label Double clicked!" & @LF)
                        MsgBox("", "Double Click!", "You double clicked my label!")
                    EndIf
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

 

Miraculously , I did as expected , thank you so much , you guys in this forum very friendly. I loved it
Link to comment
Share on other sites

  • 4 weeks later...

I found the first method useful.  But I need to ask a question:

When I tried using it for a RichEdit control, the registered function is never called.  Is a different setup required?  Or a different approach?

#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <GuiRichEdit.au3>
#include <WinApi.au3>

Global $hGUI = GUICreate("Simple Mouse Click Detect", 404, 144)
; THIS WORKS:
;Global $lblLabel = GUICtrlCreateLabel("Double click this!" & @CRLF & "For something cool", 10, 10)
; THIS DOESN'T:
Global $lblLabel = _GUICtrlRichEdit_Create($hGUI, "Double click this!" & @CRLF & "For something cool", 10, 10)

Global $hWnd_wndproc = DllCallbackRegister("NewWndProc", "ptr", "hwnd;uint;wparam;lparam")
Global $ptr_new_wndproc = DllCallbackGetPtr($hWnd_wndproc)
Global $ptr_old_wndproc = _WinAPI_SetWindowLong(GUICtrlGetHandle($lblLabel), $GWL_WNDPROC, $ptr_new_wndproc)

GUISetState(@SW_SHOW, $hGUI)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hGUI)
            DllCallbackFree($hWnd_wndproc)
            Exit 0
        Case $lblLabel
            ConsoleWrite("Label clicked" & @LF)
    EndSwitch
WEnd

Func NewWndProc($hWndFrom, $iMsg, $wParam, $lParam)
    Switch $hWndFrom
        Case GUICtrlGetHandle($lblLabel)
            Switch $iMsg
                Case $WM_LBUTTONDBLCLK
                    ConsoleWrite("Label Double clicked!" & @LF)
                    MsgBox("", "Double Click!", "You double clicked my label!")
            EndSwitch
    EndSwitch
    Return _WinAPI_CallWindowProc($ptr_old_wndproc, $hWndFrom, $iMsg, $wParam, $lParam)
EndFunc   ;==>NewWndProc

Thanks for any suggestions.

 

Link to comment
Share on other sites

Some more RichEdit I see, love me some rtf.

Quote

_WinAPI_SetWindowLong

Parameters

$hWnd Handle of the window
$iIndex Specifies the 0-based offset to the value to be set.
Valid values are in the range zero through the number of bytes of extra window memory, minus four;
for example, if you specified 12 or more bytes of extra memory, a value of 8 would be an index to the third 32-bit integer.
To retrieve any other value specify one of the following values:
    $GWL_EXSTYLE - Sets the extended window styles
    $GWL_STYLE - Sets the window styles
    $GWL_WNDPROC - Sets the address of the window procedure
    $GWL_HINSTANCE - Sets the handle of the application instance
    $GWL_HWNDPARENT - Sets the handle of the parent window, if any
    $GWL_ID - Sets the identifier of the window
    $GWL_USERDATA - Sets the 32-bit value associated with the window
$iValue Specifies the replacement value

The value returned from _GUICtrlRichEdit_Create is not a control id like any of the default controls (GUICtrlCreate*) but it is a handle to a RichEdit window.

If you wanted to write your own window procedure for it you could, all you need to do is remove the GUICtrlGetHandle and just use the value returned from _GUICtrlRichEdit_Create

#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <GuiRichEdit.au3>
#include <WinApi.au3>

Global $hGUI = GUICreate("Simple Mouse Click Detect", 404, 144)
Global $hWnd_rich_edit = _GUICtrlRichEdit_Create($hGUI, "Double click this!" & @CRLF & "For something cool", 10, 10)
Global $hWnd_wndproc = DllCallbackRegister("NewWndProc", "ptr", "hwnd;uint;wparam;lparam")
Global $ptr_new_wndproc = DllCallbackGetPtr($hWnd_wndproc)
Global $ptr_old_wndproc = _WinAPI_SetWindowLong($hWnd_rich_edit, $GWL_WNDPROC, $ptr_new_wndproc)

GUISetState(@SW_SHOW, $hGUI)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hGUI)
            DllCallbackFree($hWnd_wndproc)
            Exit 0
    EndSwitch
WEnd

Func NewWndProc($hWndFrom, $iMsg, $wParam, $lParam)
    Switch $hWndFrom
        Case $hWnd_rich_edit
            Switch $iMsg
                Case $WM_LBUTTONDBLCLK
                    ConsoleWrite("Label Double clicked!" & @LF)
                    MsgBox("", "Double Click!", "You double clicked my label!")
            EndSwitch
    EndSwitch
    Return _WinAPI_CallWindowProc($ptr_old_wndproc, $hWndFrom, $iMsg, $wParam, $lParam)
EndFunc   ;==>NewWndProc

Alternatively you could use use WM_NOTIFY and set the event masks for the RichEdit to $ENM_MOUSEEVENT, so clicking in the rich edit will trigger the GUI Message

#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <GuiRichEdit.au3>
#include <WinApi.au3>

Global $hGUI = GUICreate("Simple Mouse Click Detect", 404, 144)
Global $hWnd_rich_edit = _GUICtrlRichEdit_Create($hGUI, "Double click this!" & @CRLF & "For something cool", 10, 10)
_GUICtrlRichEdit_SetEventMask($hWnd_rich_edit, $ENM_MOUSEEVENTS)
GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY)
GUISetState(@SW_SHOW, $hGUI)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hGUI)
            ;DllCallbackFree($hWnd_wndproc)
            Exit 0
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Local $tEnLink = DllStructCreate($tagENLINK, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam)
    Local $rtf_get_sel
    Local $selected_text = ""

    Switch (DllStructGetData($tNMHDR, "hWndFrom"))
        Case $hWnd_rich_edit
            Switch (DllStructGetData($tMsgFilter, "Msg"))
                Case $WM_LBUTTONDBLCLK
                    $rtf_get_sel = _GUICtrlRichEdit_GetSel($hWnd_rich_edit)
                    If (Not @Error) Then $selected_text = _GUICtrlRichEdit_GetTextInRange($hWnd_rich_edit, _GUICtrlRichEdit_GetCharPosOfPreviousWord($hWnd_rich_edit, $rtf_get_sel[0]), _GUICtrlRichEdit_GetCharPosOfNextWord($hWnd_rich_edit, $rtf_get_sel[0]))
                    MsgBox("", "Double Click!", "You double clicked my RichEdit!" & @CRLF & "Selected text: " & $selected_text)
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

Edited by InunoTaishou
Didn't free my proc!
Link to comment
Share on other sites

Quote

The value returned from _GUICtrlRichEdit_Create is not a control id like any of the default controls (GUICtrlCreate*) but it is a handle to a RichEdit window.

THAT was a bit of a breakthrough in understanding RichEdits.  Now, more things make sense ... mainly, why they require so many specialized (UDF-style) script steps.

I was able to make both of your methods work in my application script.  The second seems more efficient, in terms of processor efficiency.  But they are both useful.

Thanks for providing such clear examples!

 

Link to comment
Share on other sites

Glad I could help.

Everything that you do in the WM_NOTIFY example you should be able to do in the WndProc funciton as well (It's just a matter of knowing what kind of struct to create using the right parameters of the WndProc function).

Just go with whichever one you prefer.

Link to comment
Share on other sites

  • 1 year later...
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <WinApi.au3>

Global $hGUI = GUICreate("Double Click", 144, 144)
Global $lblLabel = GUICtrlCreateLabel("Double click this!" & @CRLF & "For something cool", 10, 10)
Global $hWnd_wndproc = DllCallbackRegister("NewWndProc", "ptr", "hwnd;uint;wparam;lparam")
Global $ptr_new_wndproc = DllCallbackGetPtr($hWnd_wndproc)
Global $ptr_old_wndproc = _WinAPI_SetWindowLong(GUICtrlGetHandle($lblLabel), $GWL_WNDPROC, $ptr_new_wndproc)

GUISetState(@SW_SHOW, $hGUI)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hGUI)
            DllCallbackFree($hWnd_wndproc)
            Exit 0

        Case $lblLabel
            ConsoleWrite("Label clicked" & @LF)
    EndSwitch
WEnd

Func NewWndProc($hWndFrom, $iMsg, $wParam, $lParam)
    Switch $hWndFrom
        Case GUICtrlGetHandle($lblLabel)
            Switch $iMsg
                Case $WM_LBUTTONDBLCLK
                    ConsoleWrite("Label Double clicked!" & @LF)
                    MsgBox("", "Double Click!", "You double clicked my label!")
            EndSwitch
    EndSwitch

    Return _WinAPI_CallWindowProc($ptr_old_wndproc, $hWndFrom, $iMsg, $wParam, $lParam)
EndFunc   ;==>NewWndProc

InunoTaishou 

if you make the form not active, then click the Label to trigger a double click, although it should not. How can this be remedied?

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