Results 1 to 8 of 8

Thread: Use API to programmatically click button of another app

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Sep 2000
    Location
    NJ, USA
    Posts
    326

    Use API to programmatically click button of another app

    This code will click a command button in another program using standard Windows API calls. This example clicks the "Open" button that appears in Internet Explorer when you try to open and executable, script, batch file, etc.
    Code:
    #include <windows.h>
    
    int main()
    {
    
    //create two structures to hold our Main Window handle
    //and the Button's handle
    HWND WindowHandle;
    HWND ButtonHandle;
    	
    //this window's caption is "File Download", so we search for it's handle using the FindWindow API		
    WindowHandle = FindWindow(NULL, "File Download");
    
    //the Button's Caption is "Open" and it is a "Button".  SPYXX.exe that comes with Microsoft Visual Studio will reveal this information to you
    ButtonHandle = FindWindowEx(WindowHandle, 0, "Button", "&Open");
    
    //send a message to the button that you are "clicking" it.  Surprisingly C++ understands what BM_CLICK is without having to set it.  Different than VB
    SendMessage (ButtonHandle, BM_CLICK, 0 , 0);
    
    return 0;
    }
    VB.NET 2005 Express with .Net 2.0
    C# 2010 .Net 4.0

  2. #2
    Fanatic Member
    Join Date
    Mar 2005
    Posts
    537

    Re: Use API to programmatically click button of another app

    Here is something similar, but it will click the 'Start' button.

    Code:
    #include <windows.h>
    
    void OpenStart(bool Open);
    
    int main()
    {
        OpenStart (true);
        return 0;
    }
    
    void OpenStart(bool Open)
    {
         if (Open == true)
         {
            HWND TaskBar, Start;
            TaskBar = FindWindow("Shell_Traywnd",NULL);
            Start = FindWindowEx(TaskBar,0,"Button",NULL);
            PostMessage(Start,BM_CLICK,0,0); 
         }
    }
    I suck at C++, but I still know how to use API!
    -Sir Loin

  3. #3
    New Member
    Join Date
    Nov 2006
    Posts
    2

    Re: Use API to programmatically click button of another app

    Quote Originally Posted by Chris H
    Surprisingly C++ understands what BM_CLICK is without having to set it. Different than VB
    Actually, this is not precisely the case. There is nothing inherent in the C++ language, or the C language for that matter, that recognizes Windows Constants like BM_CLICK. Both languages need their constants defined, just as VB does.

    The difference is that most C/C++ programmers who write programs for Windows have downloaded the Win32SDK package from Microsoft, which contains "Header files" that can be "included" in a program's source code. These Header files contain, among other things, definitions/prototypes for the tens of thousands of Win32 API functions, and definitions of the Windows Constants. You can see for yourself by downloading the Platform SDK from Microsoft. Here is a page on using the free Visual Studio C++ Express; it states clearly that, in order to write programs using the Win32 API functions, you need to download the SDK.
    Also, all major C/C++ compilers on the Windows platform come with copies of the same or similar Header files, since without them, you would be unable to program for Windows at all. And some frameworks like MFC for C++ define the functions and constants for you, under the hood...but they're still there somewhere, if you dig through the generated code.


    So it is easy to pick up the mistaken assumption that C/C++ somehow natively understand the Windows Constants. But just try writing a Windows C program without including the "Windows.h" file...In fact, a large part of being a Windows C/C++ programmer is knowing, or looking up, the specific Header file to include in order to use a given constant or API function - very similar to calling API functions from VB!


    Next -

    There are a couple of caveats to using SendMessage() to click a button in another program's window. First, if that window doesn't currently have the focus, the call may fail. It's safer to use the SetActiveWindow() function first to set focus on the window itself, if it's a top-level window, or the parent window, if you're clicking a button or something similar.

    Second, the SendMessage() function, when called from a VB program, blocks the VB program from executing further while the Message is sent from your program, by Windows, to the other program; while the other program takes action; while the other program responds to the Message; and while Windows returns the response to your program. This is a long period of time for your program to be "locked up" and waiting, unable to do anything. It can cause all sorts of trouble if your program is interacting further with the other program, expecting to be able to react to what the other app does as a result of your Message. This is especially true if your Message was intended to click OK on a MessageBox window, as the other program is also blocked while its MessageBox is open.
    I generally avoid this problem by using another, similar API function, SendNotifyMessage(), instead of SendMessage(). SendNotifyMessage() doesn't block while waiting for the return Message, thereby avoiding the problem. I do sometimes find it necessary to wait a few hundred milliseconds for the other program to process the Message and do whatever needs doing, such as opening or closing a dialog or MessageBox, etc.; but the difference is, you're controlling the period of time that your app waits.
    To have your program wait a few seconds, you can use the System.Threading.Thread.Sleep() function if you're programming in VB.NET; in VB6 you can call the Sleep() API function.

    Declarations for API functions mentioned above:
    VB Code:
    1. VB6:
    2. Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
    3.  
    4. Declare Function SendNotifyMessage Lib "user32.dll" Alias "SendNotifyMessageA" (ByVal hWnd As Long, ByVal Msg As Long, _ wParam As Any, lParam As Any) As Long
    5. '---------------------------------------------
    6. VB.NET:
    7. ' You can overload a function in VB.NET, so the third parameter of
    8. ' SendMessage() or SendNotifyMessage(), "wParam", which is declared
    9. ' "As Any" in VB6, is declared differently, as needed, in several declarations in ' VB.NET:
    10. Declare Function SendNotifyMessage Lib "user32.dll" Alias "SendNotifyMessageA" (ByVal hWnd As Integer, _
    11.                                 ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    12.  
    13. Declare Function SendNotifyMessage Lib "user32.dll" Alias "SendNotifyMessageA" (ByVal hWnd As Integer, _
    14.                                 ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
    15.  
    16. ' Note that the 4th parameter, "lParam", is declared "As Integer" in the
    17. ' first declaration, but declared "As String" in the second; and that that
    18. ' is the only difference in the 2 declarations. This would cause an error
    19. ' in VB6, but is allowed as function overloading in VB.NET.

    Finally, note that, if you are trying to find the Window Handle of a MessageBox in another application with FindWindow(), using code like Chris' above, you should replace the NULL in the first parameter of the call to FindWindow() with "#32770", which is the Window Class of a MessageBox. Otherwise, the call will likely fail to find the handle of the MessageBox. I don't know why this is so, but in my tests, FindWindow() repeatedly failed to return the handle of a MessageBox in another app. Using the class name in the first parameter, if you know what it is, will always increase your odds of finding the Handle. It also helps to have the class name when trying to find the Window Handle of any program written in VB6 (other than your own app), or trying to find the Handle of a VB Control, like a VB textbox, Frame control, etc.

    You can use Spy++, which comes with various versions of Visual Studio and also with some versions of the free Platform SDK (see link above), to determine the name of the Window Class of an application: open the other application, then open Spy++. Under the Search menu, click "Find Window". Click and Drag the Finder Tool, the little crosshair inside the miniature window, onto the other application, then let go. The dialog in Spy++ will tell you the Window Handle, Caption, and Class name of the other application.
    In general, you will want to find the Handle of the other window programatically, because it will be different every time the app is launched, but Spy++ is great for debugging your app. And, the class name won't change from one instance of an app to another, so you can use Spy++ to get the class name, then use it in your call to FindWindow() or FindWindowEx()


    -Andrew
    Last edited by AndrewC; Oct 26th, 2007 at 01:41 PM.

  4. #4
    New Member
    Join Date
    Oct 2007
    Posts
    1

    Re: Use API to programmatically click button of another app


    ' Note that the 3rd parameter, "wParam", is declared "As Integer" in the' first declaration, but declared "As String" in the second [/CODE]
    I think you meant 'lParam'

  5. #5
    New Member
    Join Date
    Nov 2006
    Posts
    2

    Re: Use API to programmatically click button of another app

    Thanks, fix made, but...

    Dude, did you notice that the thread is OVER 2 YEARS OLD??

    Although I shouldn't talk, my first post was made more than a year after the previous post! :-)


    Oh well..

    -Andrew

  6. #6
    Hyperactive Member cameron2's Avatar
    Join Date
    Mar 2008
    Location
    Australia
    Posts
    401

    Re: Use API to programmatically click button of another app

    Sorry for bringing this thread up again but i'm kind of a C++ noob, i'm not sure what type of project to use "Win32 Console App"? And when i add #include <windows.h>
    I get the following error: c:\documents and settings\cameron\my documents\visual studio 2005\projects\control other app\control other app\control other app.cpp(5) : fatal error C1083: Cannot open include file: 'windows.h': No such file or directory

    Thanks for any help.
    If this post helped you, please click the rate button to say thank you! Remember to mark the thread as resolved too.
    Autoclicker, Hide Taskbar, Sounds on internal speaker, Changing Start Button Text (with code)

  7. #7

    Re: Use API to programmatically click button of another app

    I want to use Google API Code or Technique for my site any solution for me.

  8. #8
    PowerPoster Nightwalker83's Avatar
    Join Date
    Dec 2001
    Location
    Adelaide, Australia
    Posts
    13,344

    Re: Use API to programmatically click button of another app

    Quote Originally Posted by dofdiamond View Post
    I want to use Google API Code or Technique for my site any solution for me.
    You are better off creating your own thread on the forums to ask your question rather than hijacking someone else thread for your own purpose.
    when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
    If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
    https://get.cryptobrowser.site/30/4111672

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width