-2

I am trying to make a program click a button on another program; I decided to use the function:

SendMessage(hWndVariable, MsgVariable, wParamVariable, lParamVariable)

but there is an issue. The window with the window handle hWndVariable has 3 buttons. I initially planned to use the following parameters in the SendMessage function:

SendMessage(hWndVariable, BN_CLICK, 0, 0);

Question:: but since there are 3 buttons, how would the program know which one is being clicked? lol I am guessing that I am either missing something or doing something completely wrong.

cf-
  • 8,598
  • 9
  • 36
  • 58
user3552287
  • 123
  • 4
  • 11
  • 2
    What language are you using? (You've tagged three different ones.) – Alan Stokes Apr 20 '14 at 19:16
  • Do you mean [BN_CLICKED](http://msdn.microsoft.com/en-us/library/windows/desktop/bb761825(v=vs.85).aspx), which is reasonably well documented? – Alan Stokes Apr 20 '14 at 19:19
  • @user3552287 As Alan noted, please don't use three different language tags on your question. You've done this with your other questions as well, and it makes helping you more difficult than it would be with one language tag. – cf- Apr 20 '14 at 19:33
  • 2
    You are doing it all wrong anyway. Use automation as you are intended to do. – David Heffernan Apr 20 '14 at 19:33
  • I am using c++, sorry about that :P – user3552287 Apr 20 '14 at 20:10
  • 2
    No matter what language you're using, you should still use UI Automation to do this. `BN_CLICKED` is *not* a message, it is a notification. And if the button is in a dialog, you need to send this notification to the dialog, not the button. Things start getting complicated really quickly trying to do it the wrong way. – Cody Gray - on strike Apr 21 '14 at 07:57

2 Answers2

1

SendMessage(hWndVariable, BN_CLICK, 0, 0);

This is your problem right here. First, you're sending a nonexistent message (you meant BN_CLICKED). Second, you're not sending the message correctly.

As described in answers to your previous questions, you need to get the button's ID. You can do this using Spy++.

Then, per the BN_CLICKED documentation, you can send your message like this:

SendMessage(parentWindowhWnd, WM_COMMAND, (BN_CLICKED << 16) | BUTTONID, buttonhWnd);

Fill in the values appropriately - parentWindowhWnd is the HWND of the window containing the button, BUTTONID is the button's ID, and buttonhWnd is the HWND of the button itself.

Community
  • 1
  • 1
cf-
  • 8,598
  • 9
  • 36
  • 58
  • Awesome. I know how to get the parentWidowhWnd with FindWindowEx() but how would I go about finding the button handle? I mean I used spy++ to get the window name and used that in FindWindowEX to find the handle, but I couldn't find the button's ID... what steps must I take to find the button's ID in spy++? – user3552287 Apr 20 '14 at 20:15
  • btw, why did you use WM_COMMAND where I thought BN_CLICKED should be? – user3552287 Apr 20 '14 at 20:23
  • You would find the button handle as [this answer](http://stackoverflow.com/a/23173692/2245528) shows: `EnumChildWindows` on the parent window, then check each child window's ID via `GetWindowLong` with `GWL_ID` against the ID you get from Spy++. When you find a matching ID, there you go. – cf- Apr 21 '14 at 03:53
  • And I used `WM_COMMAND` because the `BN_CLICKED` docs say _The parent window of the button receives this notification code through the WM_COMMAND message._ Please look at the links I left in my post, I believe they answer your questions fairly neatly. – cf- Apr 21 '14 at 03:54
  • The thing is every time I run the program again, the child window has a different handle and ID, so If I get the ID from spy++, that ID will only be valid while the program is still running. If tomorrow I run it again, there will be a new ID and handle value... so how do I get around that issue? – user3552287 Apr 21 '14 at 21:08
  • The button ID should remain the same. The handle will not, which is why you `FindWindowEx` to get the parent window and `EnumChildWindows` to get the button. – cf- Apr 21 '14 at 21:31
  • thing is EnumChildWindows is used to look through each child window in the callback function, but what function can I use to find the button ID for the buttons inside the child windows? Is there any function you know of? – user3552287 Apr 21 '14 at 22:54
  • computerfreaker... do you know any way I can see all the controls a specific window has? I know that GetDlgCtrlID() can be used to get the Id of a control so If I knew what controls are there maybe I could work something out – user3552287 Apr 21 '14 at 22:59
  • @user3552287 Why not use Spy++ to get the button's ID, then `EnumChildWindows` to iterate through the parent window's controls, checking each control's ID against the one you got from Spy++? – cf- Apr 21 '14 at 23:02
  • thats the thing bro, I have been trying to use spy++ to get the button's ID but i cant seem to find out how to do it. I mean I click the "log" button and then pick the "finder tool" which seems to only click on windows. There is even a text next to the finder tool that says: "Drag the Finder Tool over a window to select, then release the mouse button."... window, not button... ahh im confused how to find a buttons info – user3552287 Apr 21 '14 at 23:07
  • Buttons are a type of window too, really. Almost every control is. (If it helps, creating buttons requires a call to `CreateWindowEx`.) You can drag the finder tool over a button the same as you can drag it over a window. – cf- Apr 21 '14 at 23:10
0

BN_CLICKED is a notification that the button sends to its parent window. You are thinking of the BM_CLICK message instead, which you can send to a button window to simulate a click on it:

//SendMessage(hWndVariable, BM_CLICK, 0, 0);
SendMessage(hWndVariable, BM_CLICK, 0, 0);

In order for this to work, hWndVariable has to point to the specific button that you want to click on, not its parent window like you are currently doing.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770