Create a WPF Touch Screen Keyboard Application which sends keys to another window

6.8k Views Asked by At

My touch screen keyboard is highly customizable interface and has every component I need except for sending keys, anyone see a problem with this. Originally when I was creating it I was going to use the Forms.SendKeys.Send() but it's a WPF application... no go. For starters VB.Net in its infinite wisdom decided it would not handle default form messages. Go figure.

Or perhaps, this is my real problem, I can't get the WPF application to stop getting focus. I want it to act like the windows touch keyboard, but Every action that occurs in the transparent WPF makes that application the active one. I want events to still occur but I need the active window to be the window you wish to type into, like notepad.

Any Suggestions on what I should do, to make my WPF not focusable and to send keyboard buttons to the focused (or other) window?

PS, I'm using WPF in Visual Studio 2010 in Vb.Net (I can use C# Code to!)

1

There are 1 best solutions below

6
Chris Taylor On BEST ANSWER

I think you will find the answer here usefull

There are a number of compilcated ways to achieve this, but the solution I posed that the above link is easy and only has one quirk, that to be honest can be worked around. When dragging the input window it does not provide feedback until the move is completed, but you can work around this by handling some non-client messages, I can spend sometime look at the work around if you need, but first confirm this solution is right for you.

Update: A sample of how a the approach above can be applied to a WPF form.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace WpfApplication1
{
  /// <summary>
  /// Interaction logic for Window1.xaml
  /// </summary>
  public partial class Window1 : Window
  {
    public Window1()
    {
      InitializeComponent();
    }

    const int WS_EX_NOACTIVATE = 0x08000000;
    const int GWL_EXSTYLE = -20;

    [DllImport("user32", SetLastError = true)]
    private extern static int GetWindowLong(IntPtr hwnd, int nIndex);

    [DllImport("user32", SetLastError = true)]
    private extern static int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewValue);

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
      WindowInteropHelper wih = new WindowInteropHelper(this);
      int exstyle = GetWindowLong(wih.Handle, GWL_EXSTYLE);
      exstyle |= WS_EX_NOACTIVATE;
      SetWindowLong(wih.Handle, GWL_EXSTYLE, exstyle);
    }    
  }
}