Click here to Skip to main content
14,389,400 members
Rate this:
Please Sign up or sign in to vote.
See more:
i want to trigger a button click event in my application,
i have the button handle and have passed that handle to sendmessage func but still button is not clicked by my program...

code sample

Process notePad = new Process();

notePad.StartInfo.FileName = @"C:\Users\Fahad\Downloads\Programs\ccleaner.exe";
notePad.Start();

uint processID = 0;
uint threadId = GetWindowThreadProcessId(notePad.MainWindowHandle, out processID);
AttachThreadInput(GetCurrentThreadId(), threadId, true);

SetActiveWindow(notePad.MainWindowHandle);
IntPtr btnHandlr = FindWindowEx(notePad.MainWindowHandle, IntPtr.Zero, "Button", "OK");
SendMessage(btnHandlr, BM_CLICK, 0, 0);
            
CloseHandle(Handle);


Please help....sendmessage() not working
anyother way if please tell...
Posted
Updated 29-Nov-11 10:20am
v3
Comments
Sergey Alexandrovich Kryukov 29-Nov-11 14:34pm
   
So, C++ or C#?!
--SA
Rate this:
Please Sign up or sign in to vote.

Solution 1

It looks like your app is trying to close a dialog in another process.

SetActiveWindow will fail if the window you are trying to activate is not attached to your thread's message queue.
You can attach the current thread in your process by first calling GetWindowThreadProcessId to get the id of the thread for notePad.MainWindowHandle.
Then call AttachThreadInput to attach your thread to the dialog in notepad so you can call SetActiveWindow.

You should use the tool Spy++ that comes with Visual Studio to verify if your button message is being received by the other process. For VS2008, the program is found in:

"C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\spyxx.exe"
   
Comments
fahad.abdulrauf 29-Nov-11 14:55pm
   
thanks Paul for the reply....
what i have read on the internet is that to use sendmessage() i got to have the button handle and i have checked that the i have correct button handle...but its still not working....this is the problem
well i dont get it what u r saying...but whatever i understood i have done a few changes

...............
CODE
..............
uint processID = 0;
uint threadId = GetWindowThreadProcessId(notePad.MainWindowHandle, out processID);
AttachThreadInput(GetCurrentThreadId(), threadId, true);

SetActiveWindow(notePad.MainWindowHandle);
IntPtr btnHandlr = FindWindowEx(notePad.MainWindowHandle, IntPtr.Zero, "Button", "OK");
SendMessage(btnHandlr, BM_CLICK, 0, 0);
.....................
what i m trying to do is make an automated installer, so i have started a new process got the text and handlers of new process windows just cant get the OK button pressed....
PLEASE HELP PAUL
Rate this:
Please Sign up or sign in to vote.

Solution 2

You absolutely don't need to mix native code with .NET code the way you do. Pure .NET code would be more than enough. It looks like you're using your old native-code habits in the world of .NET you are not really familiar with. I would suggest you start from scratch using .NET only.

[EDIT #1]

OK, here is a pattern for using a button. Suppose you have created a button MyButton somewhere and it is already appears on your Form or a Window. Now, how to make it clickable? Here:

myButton.Click += (sender, eventArgs) => {
   SomeMethodToBeCalledOnMyButtonClick();
}

//...

void SomeMethodToBeCalledOnMyButtonClick() { /*...*/ }


The button starts to respond to the user's click as soon as the above '+=' operator is executed. You can add more than one handler, which is important in certain cases. You can call the code with this operator, say, in your constructor after all controls are setup. Now, you can write any code withing the '{}' of this anonymous event handler. But in many cases calling just one separate method like SomeMethodToBeCalledOnMyButtonClick is better. Why? Because sometimes you need to call the same method from some other place (for example, a menu or whatever else). This method is free from the parameters passed in event handler (sender, eventArgs) and can be called from anywhere.

In other case, you may call the same method from the handlers of other controls or create a handler as a named method and add it to different controls. In this case, you will need to parametrize the handle using the one or both of parameters mentioned above.

[EDIT #2]

Perhaps I did not understand you; and you want something very different: to "click" a button on CCLEANER.EXE. If so, I have to say: this is a bad task which I do not recommend to solve at all: you won't get reliable results. It's better to create your own registry cleaner, otherwise you let the user to do it. The application is not designed to be "automated" this way, just don't do it.

—SA
   
v3
Comments
Albert Holguin 29-Nov-11 15:06pm
   
It is odd looking code, good advice... +5
Sergey Alexandrovich Kryukov 29-Nov-11 18:17pm
   
I think this is just the code of a beginner who has native Windows habits. I added some additional advice to help.
Thank you, Albert.
--SA
fahad.abdulrauf 29-Nov-11 15:07pm
   
thanks for pointing it out i will start it from the scratch as soon as this semester project gets completed...but please any help on the question would be appreciated :))
fahad.abdulrauf 29-Nov-11 15:21pm
   
updated the code hope its clearer now....
kindly reply i am stuck
Sergey Alexandrovich Kryukov 29-Nov-11 18:20pm
   
Yes, sure, but the only problem with that is: I still don't see what do you want to achieve. There is no button-related code in you code. Do you simply need to handle button press done by the user or you also need to simulate the click. First thing to remember is: you never need native code.
--SA
fahad.abdulrauf 30-Nov-11 0:50am
   
well i m working on an automated installer so by running the ccleaner.exe
the window is displayed...i got the handle of the window its child handles and all...now i want to click the OK button on the ccleaner setup window so that the setup will continue on to the next screen...for that i have used sendmessage() function passing it button handler and BM_CLICK telling it to perform button click...but its not working and i have checked that i have the right handler in "btnHandler"...hope my question is clearer...
fahad.abdulrauf 30-Nov-11 1:49am
   
SAKryukov...thanks again for the help but i want the button on ccleaner.exe to be clicked actually i am working on my university project and have been asked to make an automated installer in which user has to do nothing so my program will do all the installation so to proceed the OK button on ccleaner setup window is to be pressed....that i cant do
Rate this:
Please Sign up or sign in to vote.

Solution 4

On the other hand ccleaner command line parameters you could use instead of programatically clicking any button: https://www.piriform.com/docs/ccleaner/advanced-usage/command-line-parameters[^].
   
v2
Comments
Richard MacCutchan 27-Oct-15 11:32am
   
Look at the date of this question.
Zoltán Zörgő 27-Oct-15 12:29pm
   
Right :)
Rate this:
Please Sign up or sign in to vote.

Solution 3

bm_click wont work if the button is not visible to your eye.
when you activate window, it takes time (ie: 40ms ) to be visible/usable.

you gotta ""put delay before CLİCK""
// it takes time to make it visible. 
SetActiveWindow(notePad.MainWindowHandle);  

//wait until tabpage or window is fully usable/active (repaint delay)
 System.Threading.Thread.Sleep(500);
  
IntPtr btnHandlr = FindWindowEx(notePad.MainWindowHandle, IntPtr.Zero, "Button", "OK");
SendMessage(btnHandlr, BM_CLICK, 0, 0);
   
v2
Comments
Richard MacCutchan 27-Oct-15 11:32am
   
Please don't post in old dead questions. This was urgent 4 years ago, not any more.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month



CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100