?
Solved

how to use API (sendmessage?) to click a button

Posted on 2000-02-10
23
Medium Priority
?
754 Views
Last Modified: 2008-02-01
I have written a program that enumerates all of the child windows in a running application.  I have found that by getting the class name of the child windows, it will return "Button" for buttons on the form.  I would like to know how to have my program click on the button based on the name of the button.  I thought maybe with SendMessage or PostMessage.

Thanks.
0
Comment
Question by:adjennin
  • 10
  • 8
  • 5
23 Comments
 

Author Comment

by:adjennin
ID: 2507872
Adjusted points to 190
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2507884
TheButtonInQuestion.SetFocus
SendKeys " "
0
 

Author Comment

by:adjennin
ID: 2507981
since the button is merely a handle to a child window, I cannot use .setfocus
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
LVL 10

Expert Comment

by:caraf_g
ID: 2508045
Ah, sorry!
0
 
LVL 32

Accepted Solution

by:
Erick37 earned 760 total points
ID: 2508494
Using PostMessage to click a button knowing its handle:

Option Explicit

Const WM_LBUTTONDOWN = &H201
Const WM_LBUTTONUP = &H202

Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
    (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long


Private Sub Command1_Click()
'Button that receives the posted messages
Debug.Print "Clicked"
End Sub

Private Sub Command2_Click()
'Post the messages knowing the hWnd
Call PostMessage(Command1.hwnd, WM_LBUTTONDOWN, 0, &H10001)
Call PostMessage(Command1.hwnd, WM_LBUTTONUP, 0, &H10001)
End Sub
0
 
LVL 32

Expert Comment

by:Erick37
ID: 2508530
Note:
If you want to see the button press, insert a delay between the PostMessage calls:

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

....

Call PostMessage(Command1.hwnd, WM_LBUTTONDOWN, 0, &H10001)
Call Sleep(100)
Call PostMessage(Command1.hwnd, WM_LBUTTONUP, 0, &H10001)
0
 

Author Comment

by:adjennin
ID: 2508999
Thanks!  That is just what I had in mind.
0
 

Author Comment

by:adjennin
ID: 2511772
That did not work.  nothing happens when command2 is clicked.
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2511796
Perhaps you could try using SendMessage instead of PostMessage? (blind guess)
0
 
LVL 32

Expert Comment

by:Erick37
ID: 2512363
What did not work?
I tried the code, and it "clicked" a VB button and an external app's button as well.
0
 

Author Comment

by:adjennin
ID: 2518483
It wont work without SetFocus.  SetFocus won't work on an external app so you have to use the API version of SetFocus.  That will work.
0
 
LVL 32

Expert Comment

by:Erick37
ID: 2520000
Use AppActivate "AppTitle" just before the PostMessage() calls.
0
 

Author Comment

by:adjennin
ID: 2522239
AppActivate will not work in most cases for Child windows without names.  This is the BEST way to accomplish it:

Private Declare Function SetFocusAPI Lib "user32" Alias "SetFocus" (ByVal hwnd As Long) As Long

call SetFocusAPI(hwnd)
...

then you can send the mouse clicks.
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2522259
Nice detective work adjennin! I'm glad I've kept the notifications going!

Thanks

caraf_g
0
 
LVL 32

Expert Comment

by:Erick37
ID: 2523825
The documentation for SetFocus states:
"The window must be associated with the calling thread’s message queue."
Therefore, SetFocus can not be used to set focus to _another_ application's window through VB.
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2525995
There's always a snag... :-(
0
 

Author Comment

by:adjennin
ID: 2527490
That documentation for SetFocus is for the VB Property SetFocus and not the SetFocus API call.  The API call works, trust me.

0
 
LVL 32

Expert Comment

by:Erick37
ID: 2528022
The documentation I quoted is for the SetFocus API.
http://msdn.microsoft.com/library/psdk/winui/keybinpt_8yb7.htm

I also tried to get it to work, but could not.  Open the FreeCell About dialog and try to click the OK button

AppActivate works:

Private Sub Command2_Click()
    '''This works
    Dim lHwnd As Long
    AppActivate "FreeCell"
    lHwnd = FindWindow(vbNullString, "About FreeCell")
    lHwnd = FindWindowEx(lHwnd, 0, "Button", "OK")
    Call PostMessage(lHwnd, WM_LBUTTONDOWN, 0, &H40004)
    Call Sleep(100)
    Call PostMessage(lHwnd, WM_LBUTTONUP, 0, &H40004)
End Sub


This did not work:

Private Sub Command1_Click()
    '''This does NOT work
    Dim lHwnd As Long
    lHwnd = FindWindow(vbNullString, "About FreeCell")
    Debug.Print SetFocusAPI(lHwnd) 'returns 0
    lHwnd = FindWindowEx(lHwnd, 0, "Button", "OK")
    Call PostMessage(lHwnd, WM_LBUTTONDOWN, 0, &H40004)
    Call Sleep(100)
    Call PostMessage(lHwnd, WM_LBUTTONUP, 0, &H40004)
End Sub
0
 

Author Comment

by:adjennin
ID: 2550750
I got it to work in my app.

I wrote a vb prog and put a button on it that said "OK".  then whn i click on it it pups up a msgbox with an "OK" button.  i had trouble with findwindow so i had to use the exact handle of the button.  sure enough, it will pop up the msgbox.
0
 

Author Comment

by:adjennin
ID: 2550757
my keyboard sucks.
0
 
LVL 32

Expert Comment

by:Erick37
ID: 2550934
Post your code.
0
 

Author Comment

by:adjennin
ID: 2551800
I have the following mess before SetFocusAPI

If IsWindowEnabled(hwnd) = 0 Then retval = EnableWindow(hwnd, 1)
retval = ShowWindow(hwnd, SW_SHOW)
retval = SetForegroundWindow(hwnd)
retval = BringWindowToTop(hwnd)
retval = SetActiveWindow(hwnd)

these functions are all APIs.
0
 
LVL 32

Expert Comment

by:Erick37
ID: 2551992
All you really need is:

retval = ShowWindow(hwnd, SW_RESTORE) 'Restores if minimized
retval = SetForegroundWindow(hwnd) 'Bring to top

After these 2 calls the window will be in the same state as if you called AppActivate.

You do not need to call SetFocusAPI, because SetForegroundWindow sets the window into focus.

Out of curiosity, what was the return value you got from SetFocusAPI?
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

Question has a verified solution.

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

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses

588 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