Click here to Skip to main content
15,883,883 members
Please Sign up or sign in to vote.
1.00/5 (1 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 9:20am
v3
Comments
Sergey Alexandrovich Kryukov 29-Nov-11 14:34pm    
So, C++ or C#?!
--SA

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"
 
Share this answer
 
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
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:

C#
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
 
Share this answer
 
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
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[^].
 
Share this answer
 
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 :)
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""
C#
// 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);
 
Share this answer
 
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, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900