-
Jun 17th, 2005, 08:22 PM
#1
Thread Starter
Hyperactive Member
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
-
Oct 8th, 2005, 02:30 PM
#2
Fanatic Member
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
-
Nov 14th, 2006, 08:13 PM
#3
New Member
Re: Use API to programmatically click button of another app
 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:
VB6:
Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Declare Function SendNotifyMessage Lib "user32.dll" Alias "SendNotifyMessageA" (ByVal hWnd As Long, ByVal Msg As Long, _ wParam As Any, lParam As Any) As Long
'---------------------------------------------
VB.NET:
' You can overload a function in VB.NET, so the third parameter of
' SendMessage() or SendNotifyMessage(), "wParam", which is declared
' "As Any" in VB6, is declared differently, as needed, in several declarations in ' VB.NET:
Declare Function SendNotifyMessage Lib "user32.dll" Alias "SendNotifyMessageA" (ByVal hWnd As Integer, _
ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Declare Function SendNotifyMessage Lib "user32.dll" Alias "SendNotifyMessageA" (ByVal hWnd As Integer, _
ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
' Note that the 4th parameter, "lParam", is declared "As Integer" in the
' first declaration, but declared "As String" in the second; and that that
' is the only difference in the 2 declarations. This would cause an error
' 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.
-
Oct 26th, 2007, 01:36 PM
#4
New Member
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'
-
Oct 26th, 2007, 01:45 PM
#5
New Member
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
-
Apr 7th, 2008, 04:53 AM
#6
Hyperactive Member
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.
-
Dec 14th, 2011, 11:54 PM
#7
New Member
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.
-
Jul 30th, 2012, 07:49 PM
#8
Re: Use API to programmatically click button of another app
 Originally Posted by dofdiamond
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|