Programmatically press a button on another applica

2019-03-08 08:51发布

I'm trying to use the following code to press a button on my other application:

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
   ButtonHandle = FindWindowEx(wnd, 0, "SaveButton", "&Save");
   SendMessage(wnd, WM_COMMAND, MAKEWORD(GetDlgCtrlID(ButtonHandle), BN_CLICKED ), (LPARAM)ButtonHandle);

}

It doesn't work. I tried passing different handles to MAKEWORD and to change the WPARM and LPARAM but nothing.

Any ideas on how to click a button on another application's window?

Code is appreciated. Thanks.

EDIT: The reason it doesn't seem to work permissions. I sent a PostMessage() and the result was an error with GetLastError() = 5 (or Access Denied). Any ideas?

EDIT2 I don't mean to be rude but please please please, I already searched all the API's including getting and setting the regions for the button and then sending a button down and button up, getting the control ID, getting the class ID and a zillion more. The reason I asked the question here in the first place is because I already exhausted my search on the internet. If you know the answer PLEASE POST CODE, do not suggest an API and that's it, show me how does that API solves the problem. It's not hard. thank you.

EDIT 3: The question's answer was selected automatically when the bounty finished. The question still remains without an answer.

11条回答
SAY GOODBYE
3楼-- · 2019-03-08 08:55

Access Denied errors on SendMessage or PostMessage make no sense unless the process sending the message is running at a lower integrity level than the target process.

This should not be happening unless the process that owns the target window is being run "asAdministrator" or is a service. And its damn hard for services to create windows on the interactive desktop with Windows 6 and up.

You can do some reading about Integrity Levels Here if they apply even remotely to this situation. Internet Explorer is about the only other application that 'opts in' to the integrity security model by purposely lowering the integrity level of itself in order to sandbox itself more effectively.

查看更多
Ridiculous、
4楼-- · 2019-03-08 08:58
  1. Are you sure that "SaveButton" class name is valid? Do you get the button handle?
  2. Try to send messages to ButtonHandle window (directly to the button).

Update: I believe this should work,

SendMessage(ButtonHandle, BM_CLICK, 0, 0);
查看更多
【Aperson】
5楼-- · 2019-03-08 09:01

If you can raise the window containing the button you can send raw mouse event to a position within the boundaries of button.

There are two function to simulate mouse event SendInput and mouse_event. I recommend using mouse_event function. To raise a window you can use ShowWindow. I don't know how to get the handle of a button, but if you have its hWnd its easy to find its absolute position using GetWindowRect function. Try using these, if you run into any problems I will be glad to help.

Or define a custom WM within your application window to handle save request. WM_CUSTOM or WM_USER (cant remember which) marks the start of user defined window messages.

查看更多
Anthone
6楼-- · 2019-03-08 09:04
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);

You have to send a button click twice. Not sure why (maybe the first click only activates the window of the button), but I'm using this code for a long time and it always worked for me.

查看更多
贼婆χ
7楼-- · 2019-03-08 09:10

if you sure ButtonHandle are valid handle you can use pair WM_LBUTTONDOWN and WM_LBUTTONUP message instead of BN_CLICKED

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
    SendMessage(ButtonHandle, WM_LBUTTONDOWN, MK_LBUTTON, 0);
    SendMessage(ButtonHandle, WM_LBUTTONUP, MK_LBUTTON, 0);
}
查看更多
登录 后发表回答