tags:

views:

248

answers:

1

I am having a weird problem with SendKeys.Send

Basically what happens is this. I have Internet Explorer in focus at google.com and I call SendKeys.Send("TestSample\n"); it sometimes sends some keys twice (like TeestSample or TestSSSample) in an unpredictable way. It happens about 20% of the time.

Also, when I include a space in the string SendKeys.Send("Test Sample\n") it is similarly unpredictable except in one point. Every time I do this it enters Test Sample, does the google search, but also scrolls down the result page, as of I had pressed space bar after typing the text.

Has anyone else seen this behavior. It doesn't seem to perform this way with notepad in focus.

(To illustrate here is some sample code. Put it in a one second timer in a form, with the DllImport definitions near the top of the class.) This application fails about 20% of the time with Google.com on Internet Explorer (8.0)

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();

    private void timer1_Tick(object sender, EventArgs e)
    {
        IntPtr foreground = GetForegroundWindow();
        if (foreground != _currentForeground)
        {
            _currentForeground = foreground;
            var titleBuilder = new StringBuilder(200);
            GetWindowText(foreground, titleBuilder, 200);
            string title = titleBuilder.ToString();
            Debug.WriteLine("Title of " + title);
            if (title == "Google - Windows Internet Explorer")
            {
                Debug.WriteLine("Sending keys");
                SendKeys.Send("Test Sample\n");
            }
            if (title == "Untitled - Notepad")
                SendKeys.Send("Test notpad sample\n");
            Thread.Sleep(2000);
        }
    }
    private IntPtr _currentForeground = IntPtr.Zero;
A: 

You may be better served finding the hWnd you want to write in the new data in and then calling SetWindowTextW

[DllImport( "user32.dll" )]
public static extern int SetWindowTextW( HandleRef hWnd, [MarshalAs( UnmanagedType.LPWStr )] string text );

Afterward, find the hWnd of the button and send the WM_LBUTTONDOWN and WM_LBUTTONUP using

[DllImport( "user32.dll" )]
public static extern int PostMessage( HandleRef hWnd, WM msg, int wParam, int lParam );

    WM_LBUTTONDOWN = 0x0201
    WM_LBUTTONUP = 0x0202
JDMX