none
How to simulate button click ?

    Question

  • I have some window application that using win32 ( MFC ).
    On this window i have one button and the only thing that i know if the button text.
    I want to simulate button click - and i don't know how to do it.

    Tuesday, January 19, 2010 4:42 AM

Answers

  • Hello Ronili,

    If we know the parent handle, we can use FindWindowEx API to get the children window handle. I quote codes sample from the pinvoke site,
    http://www.pinvoke.net/default.aspx/user32.findwindowex
    ---------------------------------------------------------
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  IntPtr windowTitle);

    //Find that button using the following codes,
    IntPtr buttonHandle = FindWindowEx(parentHandle, new IntPtr(0), "Button", "button text");
    ---------------------------------------------------------
    (Typically, a button's class name is "Button". Of course, we can get the exact class name from the Spy++ tool)

    To simulate a click, we can call SendMessage API
    http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx
    http://msdn.microsoft.com/en-us/library/bb775985(VS.85).aspx
    http://www.pinvoke.net/default.aspx/user32.SendMessage
    http://www.pinvoke.net/default.aspx/Constants/BM_CLICK.html
    ------------------------------------------------------
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    //Calling codes
    const int BM_CLICK = 0x00F5;
    SendMessage(buttonHandle, BM_CLICK, new IntPtr(0), new IntPtr(0));
    ------------------------------------------------------
    (Note the remark section in BM_CLICK MSDN documentation,
    "If the button is in a dialog box and the dialog box is not active, the BM_CLICK message might fail. To ensure success in this situation, call the SetActiveWindow function to activate the dialog box before sending the BM_CLICK message to the button.")


    Best regards,
    Ji Zhou
    MSDN Subscriber Support in Forum
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Tuesday, January 19, 2010 6:17 AM
    Moderator

All replies

  • Hi,

    I you don't have handle to your windows application, you can use :

    DllImport("user32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    and use the method sendKey like this :

        Process[] processes = Process.GetProcessesByName("notepad");
        foreach (Process p in processes) {
            IntPtr pFoundWindow = p.MainWindowHandle;
            SetForegroundWindow(pFoundWindow);
            SendKeys.Send("{ENTER}");
        }

    In my example i suppose the button have focus else sendkey TAB

    It's just an idea.

    Hope this helps,

    Mathieu
    Mathieu Francesch Sharplog Engineering
    Tuesday, January 19, 2010 5:40 AM
  • But let say that i dont know the process that pop up this window -

    The only information that i hold is window title ( i know how to find the main ( parent ) window handle ) - and now i need to get hanle to the button that exist on the main window ( as i said ... i know the button text ).

    Now, beside find this button handle ( that i dont know how to do it ) i need also send message ( BM_CLICK ) to this window.

    Tuesday, January 19, 2010 5:54 AM
  • Tuesday, January 19, 2010 6:09 AM
  • Hello Ronili,

    If we know the parent handle, we can use FindWindowEx API to get the children window handle. I quote codes sample from the pinvoke site,
    http://www.pinvoke.net/default.aspx/user32.findwindowex
    ---------------------------------------------------------
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  IntPtr windowTitle);

    //Find that button using the following codes,
    IntPtr buttonHandle = FindWindowEx(parentHandle, new IntPtr(0), "Button", "button text");
    ---------------------------------------------------------
    (Typically, a button's class name is "Button". Of course, we can get the exact class name from the Spy++ tool)

    To simulate a click, we can call SendMessage API
    http://msdn.microsoft.com/en-us/library/ms644950(VS.85).aspx
    http://msdn.microsoft.com/en-us/library/bb775985(VS.85).aspx
    http://www.pinvoke.net/default.aspx/user32.SendMessage
    http://www.pinvoke.net/default.aspx/Constants/BM_CLICK.html
    ------------------------------------------------------
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

    //Calling codes
    const int BM_CLICK = 0x00F5;
    SendMessage(buttonHandle, BM_CLICK, new IntPtr(0), new IntPtr(0));
    ------------------------------------------------------
    (Note the remark section in BM_CLICK MSDN documentation,
    "If the button is in a dialog box and the dialog box is not active, the BM_CLICK message might fail. To ensure success in this situation, call the SetActiveWindow function to activate the dialog box before sending the BM_CLICK message to the button.")


    Best regards,
    Ji Zhou
    MSDN Subscriber Support in Forum
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Tuesday, January 19, 2010 6:17 AM
    Moderator