Solved

Use Sendmessage to simulate click on "OK" button

Posted on 2009-06-29
6
1,469 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 500 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

MS Dynamics Made Instantly Simpler

Make Your Microsoft Dynamics Investment Count  & Drastically Decrease Training Time by Providing Intuitive Step-By-Step WalkThru Tutorials.

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 …
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…
This video shows how to use Hyena, from SystemTools Software, to update 100 user accounts from an external text file. View in 1080p for best video quality.

734 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