Jump to content

Detect mouse click in Explorer


Recommended Posts

Is this clicking happening in a program you created with autoit?

[u]Helpful tips:[/u]If you want better answers to your questions, take the time to reproduce your issue in a small "stand alone" example script whenever possible. Also, make sure you tell us 1) what you tried, 2) what you expected to happen, and 3) what happened instead.[u]Useful links:[/u]BrettF's update to LxP's "How to AutoIt" pdfValuater's Autoit 1-2-3 Download page for the latest versions of Autoit and SciTE[quote]<glyph> For example - if you came in here asking "how do I use a jackhammer" we might ask "why do you need to use a jackhammer"<glyph> If the answer to the latter question is "to knock my grandmother's head off to let out the evil spirits that gave her cancer", then maybe the problem is actually unrelated to jackhammers[/quote]

Link to comment
Share on other sites

No, maybe you don't understand me...

If want a script that show a message (for example) when I click (double click) on a file or a folder. The message should be contain if the clicked item is a file or a folder and the name of the folder/file.

I hope you understand now :D

Link to comment
Share on other sites

Hi Fsoft

We might need more information in order to help you. I've thought about this and it seems like you need to get the active selection in the explorer listview control and not actually the mouse click. So essentially what I envision is a script that identifies when the selection in the explorer listview changes and then gets information about that selection.

If this technique would work I probably could help you.

Alternatively I guess you would need to use a mouse hook and query whether explorer is active and a selection is made in the listview. Again, perhaps I could help with that technique as well.

Need to know what you really need though

Below is a function which is called by a hotkey. It gets the path and file of the selected and opens it differently based on the file type. Shortcomings of this technique is the navigationbar at the top of the explorer must be visible

func quickview()
    $hwnd= WinGetHandle("[active]")
    $classed = _WinAPI_GetClassName($hwnd)
    local $var = "[CLASS:"&$classed&"]"
    if $var = "[CLASS:ExploreWClass]" or $var = "[CLASS:CabinetWClass]" or $var = "[CLASS:Progman]" Then
                if $var = "[CLASS:Progman]" Then
                $sSelected_Path = "C:\Documents and Settings\user\Desktop"
                Else
                    $sSelected_Path = ControlGetText($var, "", "Edit1")
                EndIf
                    $CLVItem = ControlListView($var, "", "[CLASS:SysListView32; INSTANCE:1]", "GetSelected")
                    $Item = ControlListView($var, "", "[CLASS:SysListView32; INSTANCE:1]", "GetText", $CLVItem)
                    $Item2=StringRight($Item,3)
                if $Item2="au3" Then
                    ShellExecute("F:\applications\autoit\install\SciTe\SciTE.exe", """"&$sSelected_Path & "\" & $Item&"""")
                ElseIf $Item2="vbs" or $Item2="hta" or $Item2="bat" Then
                    ShellExecute("C:\Mshell\programs\notepad2.exe", """"&$sSelected_Path & "\" & $Item&"""")
                EndIf

    EndIf
EndFunc
Edited by picea892
Link to comment
Share on other sites

Thanks for reply.

I tried your script, but it isn't work (maybe I'm running Vista, and you Xp)....I analized it, and it's a very good idea.

However there are some problems:

1) The navigation bar MUST be visible.

2) I want the DOUBLE-CLICKED file or folder, not the selected.

3) It's impossible to distinguish if the selected item is a file or a folder.

It's very strange...in the forum there isn't any topic about getting a double-clicked file/folder.......Am I the first who have this idea? :D

Edited by FSoft
Link to comment
Share on other sites

#include <WinAPI.au3>
#include <GuiListView.au3>
Opt('MustDeclareVars', 1)

HotKeySet('{ESC}', '_EXIT')

Global Const $tagMSLLHOOKSTRUCT = 'int;int;uint;uint;uint;ulong_ptr'
Global Const $WM_MOUSEMOVE                  = 0x0200
Global Const $WM_LBUTTONDOWN                = 0x0201
Global Const $WM_LBUTTONUP                  = 0x0202
Global Const $WM_LBUTTONDBLCLK              = 0x0203
Global Const $WM_RBUTTONDOWN                = 0x0204
Global Const $WM_RBUTTONUP                  = 0x0205
Global Const $WM_RBUTTONDBLCLK              = 0x0206
Global Const $SHELLDLL_DefView              = "SHELLDLL_DefView"


Dim $hMHook, $pMHook, $hHook

$hMHook = DllCallbackRegister('LowLevelMouseProc', 'long', 'int;wparam;lparam')
$pMHook = DllCallbackGetPtr($hMHook)

$hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pMHook, _WinAPI_GetModuleHandle(0))

While 1
    Sleep(50)
WEnd

Func _EXIT()
    Exit
EndFunc

Func OnAutoItExit()
    DllCallbackFree($hMHook)
    _WinAPI_UnhookWindowsHookEx($hHook)
EndFunc

Func LowLevelMouseProc($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT, $tPOINT
    Local $hWnd
    
    If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    Switch $iwParam 
        Case $WM_MOUSEMOVE, $WM_LBUTTONUP, $WM_RBUTTONUP
            Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    EndSwitch
    
    
    $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)
    $tPOINT = DllStructCreate($tagPOINT)
        DllStructSetData($tPOINT, 1, DllStructGetData($tMSLLHOOKSTRUCT, 1))
        DllStructSetData($tPOINT, 2, DllStructGetData($tMSLLHOOKSTRUCT, 2))
    
    $hWnd = _WinAPI_WindowFromPoint($tPOINT)
    If _WinAPI_GetClassName(_WinAPI_GetParent($hWnd)) = $SHELLDLL_DefView And _
        _WinAPI_IsClassName($hWnd, $__LISTVIEWCONSTANT_ClassName) Then
        Local $avArray = _GUICtrlListView_HitTest($hWnd)
        ConsoleWrite($avArray[0] & @LF)
    EndIf
    
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc

You can process it differently, like if $iwParam = $WM_LBUTTONDBLCLK Then ...

Link to comment
Share on other sites

#include <WinAPI.au3>
#include <GuiListView.au3>
Opt('MustDeclareVars', 1)

HotKeySet('{ESC}', '_EXIT')

Global Const $tagMSLLHOOKSTRUCT = 'int;int;uint;uint;uint;ulong_ptr'
Global Const $WM_MOUSEMOVE                  = 0x0200
Global Const $WM_LBUTTONDOWN                = 0x0201
Global Const $WM_LBUTTONUP                  = 0x0202
Global Const $WM_LBUTTONDBLCLK              = 0x0203
Global Const $WM_RBUTTONDOWN                = 0x0204
Global Const $WM_RBUTTONUP                  = 0x0205
Global Const $WM_RBUTTONDBLCLK              = 0x0206
Global Const $SHELLDLL_DefView              = "SHELLDLL_DefView"


Dim $hMHook, $pMHook, $hHook

$hMHook = DllCallbackRegister('LowLevelMouseProc', 'long', 'int;wparam;lparam')
$pMHook = DllCallbackGetPtr($hMHook)

$hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pMHook, _WinAPI_GetModuleHandle(0))

While 1
    Sleep(50)
WEnd

Func _EXIT()
    Exit
EndFunc

Func OnAutoItExit()
    DllCallbackFree($hMHook)
    _WinAPI_UnhookWindowsHookEx($hHook)
EndFunc

Func LowLevelMouseProc($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT, $tPOINT
    Local $hWnd
    
    If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    Switch $iwParam 
        Case $WM_MOUSEMOVE, $WM_LBUTTONUP, $WM_RBUTTONUP
            Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    EndSwitch
    
    
    $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)
    $tPOINT = DllStructCreate($tagPOINT)
        DllStructSetData($tPOINT, 1, DllStructGetData($tMSLLHOOKSTRUCT, 1))
        DllStructSetData($tPOINT, 2, DllStructGetData($tMSLLHOOKSTRUCT, 2))
    
    $hWnd = _WinAPI_WindowFromPoint($tPOINT)
    If _WinAPI_GetClassName(_WinAPI_GetParent($hWnd)) = $SHELLDLL_DefView And _
        _WinAPI_IsClassName($hWnd, $__LISTVIEWCONSTANT_ClassName) Then
        Local $avArray = _GUICtrlListView_HitTest($hWnd)
        ConsoleWrite($avArray[0] & @LF)
    EndIf
    
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc

You can process it differently, like if $iwParam = $WM_LBUTTONDBLCLK Then ...

Thank you very much! Your script works greatly.

But it shows the file/folder index when I click it. I want to show when the file/folder is double-clicked.

#Sorry for bad english!

Link to comment
Share on other sites

This procedure doesn't notified about $WM_LBUTTONDBLCLK or $WM_RBUTTONDBLCLK so it needs a little work around. On my system, which is quite old it's not fast but maybe it'll be fast for you.

#include <WinAPI.au3>
#include <GuiListView.au3>
Opt('MustDeclareVars', 1)

HotKeySet('{ESC}', '_EXIT')

Global Const $tagMSLLHOOKSTRUCT = 'int X;int Y;uint;uint;uint;ulong_ptr'
Global Const $WM_MOUSEMOVE      = 0x0200
Global Const $WM_LBUTTONDOWN             = 0x0201
Global Const $WM_LBUTTONUP                  = 0x0202
Global Const $WM_LBUTTONDBLCLK     = 0x0203
Global Const $WM_RBUTTONDOWN             = 0x0204
Global Const $WM_RBUTTONUP                  = 0x0205
Global Const $WM_RBUTTONDBLCLK              = 0x0206
Global Const $SHELLDLL_DefView        = "SHELLDLL_DefView"

Dim $hMHook, $pMHook, $hHook
Dim $iDiff = TimerInit()

$hMHook = DllCallbackRegister('LowLevelMouseProc', 'long', 'int;wparam;lparam')
$pMHook = DllCallbackGetPtr($hMHook)

$hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pMHook, _WinAPI_GetModuleHandle(0))

While 1
    Sleep(50)
WEnd

Func _EXIT()
    Exit
EndFunc

Func OnAutoItExit()
    DllCallbackFree($hMHook)
    _WinAPI_UnhookWindowsHookEx($hHook)
EndFunc

Func LowLevelMouseProc($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)
    Local $hWnd
    
    If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    
    If $iwParam = $WM_LBUTTONDOWN Then
        If TimerDiff($iDiff) < 501 Then
           
            $hWnd = _WinAPI_WindowFromPoint($tMSLLHOOKSTRUCT)
            If _WinAPI_GetClassName(_WinAPI_GetParent($hWnd)) = $SHELLDLL_DefView And _
                _WinAPI_IsClassName($hWnd, $__LISTVIEWCONSTANT_ClassName) Then
                Local $avArray = _GUICtrlListView_HitTest($hWnd)
                If $avArray[0] > -1 Then ConsoleWrite(_GUICtrlListView_GetItemText($hWnd, $avArray[0]) & @LF)
            EndIf
        EndIf
        $iDiff = TimerInit()
    EndIf
    
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc
Link to comment
Share on other sites

This procedure doesn't notified about $WM_LBUTTONDBLCLK or $WM_RBUTTONDBLCLK so it needs a little work around. On my system, which is quite old it's not fast but maybe it'll be fast for you.

#include <WinAPI.au3>
#include <GuiListView.au3>
Opt('MustDeclareVars', 1)

HotKeySet('{ESC}', '_EXIT')

Global Const $tagMSLLHOOKSTRUCT = 'int X;int Y;uint;uint;uint;ulong_ptr'
Global Const $WM_MOUSEMOVE      = 0x0200
Global Const $WM_LBUTTONDOWN             = 0x0201
Global Const $WM_LBUTTONUP                  = 0x0202
Global Const $WM_LBUTTONDBLCLK     = 0x0203
Global Const $WM_RBUTTONDOWN             = 0x0204
Global Const $WM_RBUTTONUP                  = 0x0205
Global Const $WM_RBUTTONDBLCLK              = 0x0206
Global Const $SHELLDLL_DefView        = "SHELLDLL_DefView"

Dim $hMHook, $pMHook, $hHook
Dim $iDiff = TimerInit()

$hMHook = DllCallbackRegister('LowLevelMouseProc', 'long', 'int;wparam;lparam')
$pMHook = DllCallbackGetPtr($hMHook)

$hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pMHook, _WinAPI_GetModuleHandle(0))

While 1
    Sleep(50)
WEnd

Func _EXIT()
    Exit
EndFunc

Func OnAutoItExit()
    DllCallbackFree($hMHook)
    _WinAPI_UnhookWindowsHookEx($hHook)
EndFunc

Func LowLevelMouseProc($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)
    Local $hWnd
    
    If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    
    If $iwParam = $WM_LBUTTONDOWN Then
        If TimerDiff($iDiff) < 501 Then
           
            $hWnd = _WinAPI_WindowFromPoint($tMSLLHOOKSTRUCT)
            If _WinAPI_GetClassName(_WinAPI_GetParent($hWnd)) = $SHELLDLL_DefView And _
                _WinAPI_IsClassName($hWnd, $__LISTVIEWCONSTANT_ClassName) Then
                Local $avArray = _GUICtrlListView_HitTest($hWnd)
                If $avArray[0] > -1 Then ConsoleWrite(_GUICtrlListView_GetItemText($hWnd, $avArray[0]) & @LF)
            EndIf
        EndIf
        $iDiff = TimerInit()
    EndIf
    
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc
Thanks again! The script is great!

On my Pentium 4 3.2 Ghz works speedly. What is your computer?

Link to comment
Share on other sites

  • 7 months later...

I know it's an old post but wanted to build upon Authenticity's script.

How would I go about suppressing the double-click if the file extension is ".au3"?

I'm in a lockdown state at work and want to be able to make a pseudo file association with .au3 so they are run as a parameter of AutIt3.exe instead of automatically opening in notepad. Using this script it will be easy, except I will have it opening both in notepad and executed unless I can suppress the register of the doubleclick.

Hope someone has an idea.

Link to comment
Share on other sites

You can return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure. Make a few tests to see which is posted first in the case of a double click event:

Func LowLevelMouseProc($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)
    Local $hWnd
    Local $sFilename
    
    If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    
    If $iwParam = 0x0203 Then ; WM_LBUTTONDBLCLK
            $hWnd = _WinAPI_WindowFromPoint($tMSLLHOOKSTRUCT)
            If _WinAPI_GetClassName(_WinAPI_GetParent($hWnd)) = $SHELLDLL_DefView And _
                _WinAPI_IsClassName($hWnd, $__LISTVIEWCONSTANT_ClassName) Then
                Local $avArray = _GUICtrlListView_HitTest($hWnd)

                ; Get the filename, may not contain the extension by default Windows settings. It doesn't contain
                ; the path to the file so take it into consideration.
                If $avArray[0] > -1 Then
                    $sFilename = _GUICtrlListView_GetItemText($hWnd, $avArray[0])
                    ; more code
                    Return 1 ; Prevent the system to pass the event to the rest of the chain or the active window's
                             ; message procedure
                EndIf
            EndIf
    EndIf
    
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc
Edited by Authenticity
Link to comment
Share on other sites

Thanks Authenticity

I should have known that and probably did at some level. You made my week!

The below solution works for me but may not work for everyone because the input bar must be visible.

Func LowLevelMouseProc($iCode, $iwParam, $ilParam)
    Local $tMSLLHOOKSTRUCT = DllStructCreate($tagMSLLHOOKSTRUCT, $ilParam)
    Local $hWnd
    
    If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
    
    If $iwParam = $WM_LBUTTONDOWN Then
        
        If TimerDiff($iDiff) < 501 Then
           
            $hWnd = _WinAPI_WindowFromPoint($tMSLLHOOKSTRUCT)
            
            If _WinAPI_GetClassName(_WinAPI_GetParent($hWnd)) = $SHELLDLL_DefView And _
                _WinAPI_IsClassName($hWnd, $__LISTVIEWCONSTANT_ClassName) Then
                Local $avArray = _GUICtrlListView_HitTest($hWnd)
                If $avArray[0] > -1 Then
                    
                    $filename=_GUICtrlListView_GetItemText($hWnd, $avArray[0])
                    if Stringright($filename,3)="au3" then
                        if ControlGetFocus('Program Manager','') = "SysListView321" then ShellExecute("C:\applications\autoit\AutoIt3.exe",'"'&@DesktopDir&"\"&$filename&'"')
                        if ControlGetFocus("[class:ExploreWClass]") = "SysListView321" or ControlGetFocus("[class:CabinetWClass]")= "SysListView321"  then ShellExecute("C:\applications\autoit\AutoIt3.exe",'"'&ControlGetText("", "", "Edit1")&"\"&$filename&'"')
                        ConsoleWrite(_GUICtrlListView_GetItemText($hWnd, $avArray[0]) & @LF)
                        return 1
                    EndIf
                    
                EndIf
            EndIf
        EndIf
        $iDiff = TimerInit()
    EndIf
    
    Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc
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...