views:

278

answers:

2

Hi!

I'm wanting to write a virtual keyboard, like windows onscreen keyboard for touchscreen pcs. But I'm having problem with my virtual keyboard stealing the focus from the application being used. The windows onscreen keyboard mantains the focus on the current application even when the user clicks on it. Is there a way to do the same with windows forms in C#?

The only thing I can do for now is to send a keyboard event to an especific application, like notepad in the following code. If I could make the form not focusable, I could get the current focused window with GetForegroundWindow.

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);


[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

private void button1_Click(object sender, EventArgs e)
{
    IntPtr calculatorHandle = FindWindow("notepad", null);
    SetForegroundWindow(calculatorHandle);
    SendKeys.SendWait("111");
}

Is there a way this can be done? Any suggestions of a better way to have the form sending keyboard events to the application being used?

Thanks!!

+4  A: 

Instead of trying to reset the active window after your one has been clicked, I would rather try to prevent your window from receiving focus/being activated.

Have a look at this article. At the end, the author briefly explains how this can be done. Furthermore, in this article he provides a code example for Windows Forms.

Good luck!

gehho
+1 Nice idea/pointers.
KMan
Thanks! Its halfway done! That article solution prevents my form from gaining focus, but does not prevent the other app from losing focus. That is, when I click on my app I get to the situation where none apps has the focus.
Jandex
A: 

Its solved!

I've tried the solution from gehho, but I also needed to override the CreateParams method:

private const int WS_EX_NOACTIVATE = 0x08000000;
protected override CreateParams CreateParams
    {
        get
        {
            CreateParams createParams = base.CreateParams;
            createParams.ExStyle = WS_EX_NOACTIVATE;
            return createParams;
        }
    }

Now its working!

Thanks a lot!

Jandex