Solved

vba mouse click event not clicking

Posted on 2012-03-30
9
1,507 Views
Last Modified: 2013-02-08
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long

Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Declare Function GetWindowTextLength Lib "user32" Alias _
"GetWindowTextLengthA" (ByVal hWnd As Long) As Long

Private Declare Sub SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal _
hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As _
Long, ByVal cy As Long, ByVal wFlags As Long)

Private Declare Function SetCursorPos Lib "user32" _
(ByVal X As Integer, ByVal Y As Integer) As Long

Private Declare Function GetWindowRect Lib "user32" _
(ByVal hWnd As Long, lpRect As RECT) As Long

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Declare Sub mouse_event Lib "user32.dll" (ByVal dwFlags As Long, _
ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)

'~~> Constants for pressing left button of the mouse
Private Const MOUSEEVENTF_LEFTDOWN As Long = &H2
'~~> Constants for Releasing left button of the mouse
Private Const MOUSEEVENTF_LEFTUP As Long = &H4

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const SWP_SHOWWINDOW = &H40

Dim Ret As Long, ChildRet As Long, OpenRet As Long
Dim strBuff As String, ButCap As String
Dim pos As RECT

Sub SAVE()
    '~~> Get the handle of the "File Download" Window
    Ret = FindWindow(vbNullString, "File Download")

    If Ret <> 0 Then
        'Msg Box "Main Window Found"

        '~~> Get the handle of the Button's "Window"
        ChildRet = FindWindowEx(Ret, ByVal 0&, "Button", vbNullString)

        '~~> Check if we found it or not
        If ChildRet <> 0 Then
            'MsgBox "Child Window Found"

            '~~> Get the caption of the child window
            strBuff = String(GetWindowTextLength(ChildRet) + 1, Chr$(0))
            GetWindowText ChildRet, strBuff, Len(strBuff)
            ButCap = strBuff

            '~~> Loop through all child windows
            Do While ChildRet <> 0
                '~~> Check if the caption has the word "Open"
                '~~> For "Save" or "Cancel", replace "Open" with
                '~~> "Save" or "Cancel"
                If InStr(1, ButCap, "Save") Then
                    '~~> If this is the button we are looking for then exit
                    OpenRet = ChildRet
                    Exit Do
                End If

                '~~> Get the handle of the next child window
                ChildRet = FindWindowEx(Ret, ChildRet, "Button", vbNullString)
                '~~> Get the caption of the child window
                strBuff = String(GetWindowTextLength(ChildRet) + 1, Chr$(0))
                GetWindowText ChildRet, strBuff, Len(strBuff)
                ButCap = strBuff
            Loop

            '~~> Check if we found it or not
            If OpenRet <> 0 Then
                'MsgBox "The Handle of Open Button is : " & OpenRet

                '~~> Retrieve the dimensions of the bounding rectangle of the
                '~~> specified window. The dimensions are given in screen
                '~~> coordinates that are relative to the upper-left corner of the screen.
                GetWindowRect OpenRet, pos

                '~~> Move the cursor to the specified screen coordinates.
                SetCursorPos (pos.Left - -12), (pos.Top - -7)
                '~~> Suspends the execution of the current thread for a specified interval.
                '~~> This give ample amount time for the API to position the cursor
                Application.Wait Now() + TimeValue("00:00:05")
                Sleep 100
                SetCursorPos pos.Left, pos.Top
                Sleep 100
                SetCursorPos (pos.Left + pos.Right) / 2, (pos.Top + pos.Bottom) / 2

                '~~> Set the size, position, and Z order of "File Download" Window
                SetWindowPos Ret, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
                Sleep 100

                '~~> Simulate mouse motion and click the button
                '~~> Simulate LEFT CLICK
                mouse_event MOUSEEVENTF_LEFTDOWN, (pos.Left + pos.Right) / 2, (pos.Top + pos.Bottom) / 2, 0, 0
                Sleep 1000
                '~~> Simulate Release of LEFT CLICK
                Application.Wait Now() + TimeValue("00:00:02")
                mouse_event MOUSEEVENTF_LEFTUP, (pos.Left + pos.Right) / 2, (pos.Top + pos.Bottom) / 2, 0, 0
                 
                  '~~> Retrieve the dimensions of the bounding rectangle of the
                '~~> specified window. The dimensions are given in screen
                '~~> coordinates that are relative to the upper-left corner of the screen.
                GetWindowRect OpenRet, pos
                 Application.Wait Now() + TimeValue("00:00:05")
                 mouse_event MOUSEEVENTF_LEFTDOWN, (pos.Left + pos.Right) / 2, (pos.Top + pos.Bottom) / 2, 0, 0
                Sleep 1000
                '~~> Simulate Release of LEFT CLICK
                mouse_event MOUSEEVENTF_LEFTUP, (pos.Left + pos.Right) / 2, (pos.Top + pos.Bottom) / 2, 0, 0
                
             
            Else
                MsgBox "The Handle of Open Button was not found"
            End If
        Else
             MsgBox "Child Window Not Found"
        End If
    Else
        MsgBox "Window Not Found"
    End If
End Sub

Open in new window

Hello,

I have attached the code i am using, all works well, except for clicking of the save button. It locates the window, puts the cursor over the top of the button, but it does not click.

I added the second click procedure with a delay. if i physically move and hold the mouse in position it will click..

Please help..

This os for the popup window that you get when you are saving, or opening a file in internet explorer.
0
Comment
Question by:njohnson6378
  • 4
  • 3
  • 2
9 Comments
 
LVL 41

Expert Comment

by:dlmille
ID: 37791772
Your code works for me.  For some reason I couldn't think of a web site that had a popup window for "File Download" so I did the next best thing.  In these posts (like the one I'm responding to you on) there's an option to Choose File for upload.  I hit "Choose File", selected a file, then toggled over to your code.  In your code, I changed the search to find "Open" and to find the button on the "Open" dialog called "Open" then ran the code.  PS - I commented out your .WAIT commands as they weren't necessary (at least not in this test I ran).

It clicked the button, and the dialog closed correctly, so that demonstrates that the code does work as designed.

If you could give me the internet address you're testing this out on, I could be more help trying to diagnose why its not working for you.

Cheers,

Dave
0
 
LVL 85

Expert Comment

by:Rory Archibald
ID: 37794891
Just a thought - if you can get the button handle, you could use SetFocus and then SendMessage to send a BM_CLICK message to the button.
0
 

Author Comment

by:njohnson6378
ID: 37796031
would you have an example to show thew set focus?

i have tried

 SendMessage OpenRet, BM_CLICK, 0, 0
(obviously for the open key, bt i t was unresponsive as well
0
Comprehensive Backup Solutions for Microsoft

Acronis protects the complete Microsoft technology stack: Windows Server, Windows PC, laptop and Surface data; Microsoft business applications; Microsoft Hyper-V; Azure VMs; Microsoft Windows Server 2016; Microsoft Exchange 2016 and SQL Server 2016.

 

Author Comment

by:njohnson6378
ID: 37796041
@ dlmille filehippo.com has files for download that you can try. The site i am using is secure site, thus i cannot publish info regarding that site unfortunatly.
0
 
LVL 85

Accepted Solution

by:
Rory Archibald earned 500 total points
ID: 37796058
It's

Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
                             ByVal hWnd As Long, ByVal uMsg As Long, _
                             ByVal wParam As Long, lParam As Any) As Long
Declare Function SetFocusAPI Lib "user32" Alias "SetFocus" ( _
                             ByVal hWnd As Long) As Long


Public Const BM_CLICK = &HF5&

' here hwndOK is the handle of the button

      lRet = SetFocusAPI(hwndOK)
      lRet = SendMessage(hwndOK, BM_CLICK, 0, ByVal 0&)

Open in new window

0
 

Author Comment

by:njohnson6378
ID: 37796147
 Ret = SetFocusAPI(OpenRet)
                 Ret = SendMessage(OpenRet, BM_CLICK, 0, ByVal 0&)

Open in new window







ok i tried this...


and i also tried the setfocus here
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long

Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Declare Function GetWindowTextLength Lib "user32" Alias _
"GetWindowTextLengthA" (ByVal hwnd As Long) As Long

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Const BM_CLICK = &HF5&

Dim Ret As Long, ChildRet As Long, OpenRet As Long
Dim strBuff As String, ButCap As String

Sub Sample()
    '~~> Get the handle of the "File Download" Window
    Ret = FindWindow(vbNullString, "File Download")

    If Ret <> 0 Then
        MsgBox "Main Window Found"

        '~~> Get the handle of the Button's "Window"
        ChildRet = FindWindowEx(Ret, ByVal 0&, "Button", vbNullString)

        '~~> Check if we found it or not
        If ChildRet <> 0 Then
            MsgBox "Child Window Found"

            '~~> Get the caption of the child window
            strBuff = String(GetWindowTextLength(ChildRet) + 1, Chr$(0))
            GetWindowText ChildRet, strBuff, Len(strBuff)
            ButCap = strBuff

            '~~> Loop through all child windows
            Do While ChildRet <> 0
                '~~> Check if the caption has the word "Open"
                '~~> For "Save" or "Cancel", replace "Open" with
                '~~> "Save" or "Cancel"
                If InStr(1, ButCap, "Open") Then
                    '~~> If this is the button we are looking for then exit
                    OpenRet = ChildRet
                    Exit Do
                End If

                '~~> Get the handle of the next child window
                ChildRet = FindWindowEx(Ret, ChildRet, "Button", vbNullString)
                '~~> Get the caption of the child window
                strBuff = String(GetWindowTextLength(ChildRet) + 1, Chr$(0))
                GetWindowText ChildRet, strBuff, Len(strBuff)
                ButCap = strBuff
            Loop

            '~~> Check if we found it or not
            If OpenRet <> 0 Then
                MsgBox "The Handle of Open Button is : " & OpenRet
                '~~> Click the button using Send Message
                SendMessage OpenRet, BM_CLICK, 0, 0
            Else
                MsgBox "The Handle of Open Button was not found"
            End If
        Else
             MsgBox "Child Window Not Found"
        End If
    Else
        MsgBox "Window Not Found"
    End If
End Sub

Open in new window

Still no luck....Did i add that correctly?
0
 
LVL 85

Expert Comment

by:Rory Archibald
ID: 37796320
It seems that SendMessage doesn't work with that window - I'm guessing your code came from here: http://siddharthrout.wordpress.com/2011/10/23/vbavb-netvb6click-opensavecancel-button-on-ie-download-window/
?

If that doesn't work for you, I'm afraid I don't know why that would be, but you might try removing the messageboxes to ensure that the correct window is active.
0
 

Author Comment

by:njohnson6378
ID: 37797676
yes it did. Ok ill give that a try
0
 
LVL 41

Expert Comment

by:dlmille
ID: 37872438
Yes, the code came from Sid, re: his telltale signatures ;)
0

Featured Post

The Eight Noble Truths of Backup and Recovery

How can IT departments tackle the challenges of a Big Data world? This white paper provides a roadmap to success and helps companies ensure that all their data is safe and secure, no matter if it resides on-premise with physical or virtual machines or in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A little background as to how I came to I design this code: Around 5 years ago I designed an add-in that formatted Excel files to a corporate standard, applying different cell colours and font type depending on whether the cells contained inputs,…
This collection of functions covers all the normal rounding methods of just about any numeric value.
The viewer will learn how to use a discrete random variable to simulate the return on an investment over a period of years, create a Monte Carlo simulation using the discrete random variable, and create a graph to represent the possible returns over…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question