9

I am trying to click on 'OK' button on a message box of C# Windows Forms using WinAPI . Below is the code that I am working on.

private const int WM_CLOSE = 16;
private const int BN_CLICKED = 245;

[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string  windowTitle);

// this works
hwnd = FindWindow(null, "Message");
if(hwnd!=0)
      SendMessage(hwnd, WM_CLOSE, 0, IntPtr.Zero);

// this doesn't work.
hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "Button", "ok");
SendMessage((int)hwndChild, BN_CLICKED, 0, IntPtr.Zero);

Though I get a value in hwndChild, it is not recognising BN_CLICKED. I am not sure what am I missing. any help?

I am trying to close the message box button of another application and this is what I am doing. But, I m still missing something.

IntPtr hwndChild = IntPtr.Zero;
hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero,' '"Button", "OK");
SendMessage((int)hwndChild, WM_COMMAND, (BN_CLICKED '<<16) | IDOK, hwndChild);
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Virus
  • 3,215
  • 7
  • 29
  • 46
  • Since you're using C#, you may as well use the `System.Windows.Automation` namespace. Here's an example that [pushes the "7" button in Calculator](http://stackoverflow.com/questions/14108742/manipulating-the-simple-windows-calculator-using-win32-api-in-c/14111246#14111246). Just change "Calculator" to "Message" and "7" to "OK". – Raymond Chen Feb 19 '13 at 18:04

2 Answers2

13

BN_CLICKED is not a message. You need to send a WM_COMMAND message containing the BN_CLICKED notification and the button ID in the wParam and the button handle in lParam.

The parent window of the button receives this notification code through the WM_COMMAND message.

private const uint WM_COMMAND = 0x0111;
private const int BN_CLICKED = 245;
private const int IDOK = 1;

[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, uint msg, int wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string  windowTitle);

SendMessage(hwndChild, WM_COMMAND, (BN_CLICKED << 16) | IDOK, hwndChild);
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
7

Finallu, this works for me. First click probably activates the window and second click clicks the button.

SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
Virus
  • 3,215
  • 7
  • 29
  • 46
  • Thanks i had problem to click on button inside dialog. Your sollution to click twice helped me. As you said 1st click activate window and second send message to click. – Peter M. Dec 12 '14 at 07:20