[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

Use Sendmessage to simulate click on "OK" button

Posted on 2009-06-29
6
Medium Priority
?
1,537 Views
Last Modified: 2012-05-07
Hi.
I am using VB.Net 2005.   I would like to use API Sendmessage to close a dialog popup window that will wait till you close it or click on the OK button to make it go away.
I have enumerated all the windows and know the handle of the "OK" button and the parent window.  I have used spy++ to verify that the info I have in my code is correct.  

Spy++ reports that the class of this window is "Button"  and that the caption is "OK"

I am using this declare statement
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal handle As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, _
        ByVal lParam As String) As Integer

I am trying to simulate a click on the "OK" button with the following code.

SendMessage(OK_Button_Handle, &H2, Int(0), "") ' Performs button click

Of course it's not working.   I would appreciate some help.

Thanks!
0
Comment
Question by:peispud
  • 4
  • 2
6 Comments
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 24741428
Try...
Private Const BM_CLICK As Integer = &HF5
Private Declare Function SendMessage Lib "user32" (ByVal handle As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
 
    ...
    SendMessage(OK_Button_Handle, BM_CLICK, 0, 0)

Open in new window

0
 

Author Comment

by:peispud
ID: 24743720
Hi
That doesn't seem to work for me.   I must be missing something or perhaps I have not described the problem properly.  Here goes again ...... This time with more detail.  

For simplicity,  I have used Spy++ to get the handle "OK" button in the dialog window.  (See picture)
Again for clarity,  I have included a code snippet that I am trying to use.
This is a dialog window that requires that the user either click on the "OK" button or close the parent window by clicking on the "X"  .
This dialog window prevents focus on the window that I want under it (also shown in the picture).   I am looking forward to this solution



Public Class Form1
 
    Private Const BM_CLICK As Integer = &HF5
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
            (ByVal handle As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, _
            ByVal lParam As String) As Integer
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim OK_Button_Handle As Long = &H507F4   '  Got this from spy++
        SendMessage(OK_Button_Handle, BM_CLICK, 0, 0)
 
    End Sub
End Class

Open in new window

CloseThisWindow1.JPG
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 24746460
You've missed a FUNDAMENTAL concept with respect to handles.   =\

A handle is NOT a static value like a Social Security Number sitting in a database.  Instead, handles are dynamically assigned by the Operating System whenever forms/controls are created.  Thus you cannot determine a handle value via Spy++ and then expect it to be the same value the next time the application runs!  You have to determine the handle values at RUN-TIME...

The RELATIONSHIPS between controls, however, IS typically preserved.  So normally you would find the handle to the MAIN window and then use the information gathered about the hierarchy to find your desired value.  If a control is child to another then you first find the parent handle and then ask for the child using the parent value.

To get a handle to the main window you typically use Process.GetProcessesByName(), FindWindow(), or enumerate all open windows with EnumWindows() looking for a match.
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 2000 total points
ID: 24748156
In this example, I look for the "About Calculator" dialog and, if found, get a handle to the OK button and click it:
Public Class Form1
 
    Private Const WM_LBUTTONDOWN As Integer = &H201
    Private Const BM_SETSTATE As Integer = &HF3
    Private Const BM_CLICK As Integer = &HF5
    Private Const WM_LBUTTONUP As Integer = &H202
 
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
        (ByVal parent As IntPtr, ByVal child As IntPtr, _
        ByVal className As String, ByVal caption As String) As IntPtr
 
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal handle As IntPtr, ByVal uMsg As Integer, _
         ByVal wParam As Integer, ByVal lParam As Integer) As Integer
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim AboutDialog As IntPtr = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "#32770", "About Calculator")
        If Not AboutDialog.Equals(IntPtr.Zero) Then
            Dim btnOK As IntPtr = FindWindowEx(AboutDialog, IntPtr.Zero, "Button", "OK")
            If Not btnOK.Equals(IntPtr.Zero) Then
                ClickButton(btnOK)
            End If
        End If
    End Sub
 
    Private Sub ClickButton(ByVal handle As IntPtr)
        Call SendMessage(handle, WM_LBUTTONDOWN, 0, 0)
        Call SendMessage(handle, BM_SETSTATE, 1, 0)
        Call SendMessage(handle, BM_CLICK, 0, 0)
        Call SendMessage(handle, WM_LBUTTONUP, 0, 0)
    End Sub
 
End Class

Open in new window

0
 

Author Comment

by:peispud
ID: 24753390
Actually,  I am familiar with the concept behind handles.   In fact, I am enumerating all the windows filtering for the appropriate window handle.  I had been using spy++  to verify that I was shooting at the right window.  So,  the handle given in my previous code was valid until such window was destroyed.

Thank you though.   The code that you gave me works perfectly.   One last question...

The following code does work in my code (for now)  ....  The caption on the button says "Connect"

SendMessage(ConnectButton_Handle, BM_CLICK, Int(0), 0)   ' Performs button click

My question...  Should it be coded as follows instead ?

Call SendMessage(ConnectButton_Handle, WM_LBUTTONDOWN, 0, 0)
 Call SendMessage(ConnectButton_Handle, BM_SETSTATE, 1, 0)
 Call SendMessage(ConnectButton_Handle, BM_CLICK, 0, 0)
 Call SendMessage(ConnectButton_Handle, WM_LBUTTONUP, 0, 0)

Thanks for your help!
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 24754379
"Actually,  I am familiar with the concept behind handles."

Whew!  Glad to hear it...I was worried when I saw that post.   =)

I tested on a bunch of different applications and got mixed results.  It probably has to do with what language the app was originally written in and how they handle input.  Some worked with just BM_CLICK while others needed BM_SETSTATE and BMCLICK.  Still others worked with just the LBUTTON constansts...and a few needed ALL four commands.  =\

If you are targeting just one particular app then use what works for your situation.  If you are targeting multiple buttons and want to keep it generic then use the more verbose version to increase your chances of success.
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

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
The Relationships Diagram is a good way to get an overall view of what a database is keeping track of. It is also where relationships are defined. A relationship specifies how two tables connect to each other. As you build tables in Microsoft Ac…
How to fix display issue, screen flickering issue when I plug in power cord to the machine. Before I start explaining the solution lets check out once the issue how it looks like after I connect the power cord. most of you also have faced this…
Suggested Courses

612 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