WPF中的虚拟键盘:模拟真实的输入设备?

时间:2012-04-12 03:33:50

标签: c# wpf button keyboard keyevent

我想在win7中创建一个简单的虚拟键盘,如

|---|---|---| 9 char in first block ( abcdefgijk) 

|---|---|---|

|---|---|---|

有9个按钮,当点击第一个按钮改为另一个视图时。

|---|---|---|
 a     b  c   
|---|---|---|
 e    f   g    
|---|---|---|
 i    j  k 

现在我很困惑如何点击按键盘之类的按钮可以生成char输出到另一个应用程序。我正在使用

System.Windows.Forms.SendKeys.SendWait(sendString);

但它不起作用。我知道sendString是正确的,因为我将其视为Console.WriteLine(sendString);

另一个问题是,单击按钮时焦点不会变回按钮。

任何人都有如何实现此键盘的解决方案吗?

谢谢!

感谢您的回复,实际上我已经添加了这些代码 当我多次点击按钮时,它也有一些问题。当我点击按钮它始终专注于按钮时,焦点也无法工作。在此示例中,它只包含2个按钮。你能帮忙看看那些代码发现错误吗?很多人认为!!

namespace WpfApplication5
{
    public partial class UserControl1 : UserControl
    {
        [DllImport("user32.dll")]
        public static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);

        private IInputElement focusedInputElement;
        private Window parentWindow;
        private List<Button> keyCollection = new List<Button>();

        public UserControl1(Window parent)
        {
           this.parentWindow = parent;
           this.setupKeyboardControl();
        }

        public UserControl1(IInputElement elementToFocusOn)
        {
            // set focus
            this.focusedInputElement = elementToFocusOn;
            // setup this control
            this.setupKeyboardControl();
        }

        private void setupKeyboardControl()
        {
            InitializeComponent();
            // add all keys to internal collection
            this.addAllKeysToInternalCollection();
            // install clicks
            this.installAllClickEventsForCollection(this.keyCollection);
        }

        private void addAllKeysToInternalCollection()
        {
            // itterate all panels
            // itterate all buttons
            // add to list
            Console.WriteLine("Run at here"); 
            this.keyCollection.Add(A);
            this.keyCollection.Add(B);
        }

        /// <summary>
        /// Install click events for all keys in a collection
        /// </summary>
        /// <param name="keysToInstall"></param>
        private void installAllClickEventsForCollection(List<Button> keysToInstall)
        {
            // itterate all
            foreach (Button buttonElement in keysToInstall)
            {
                // install click event
                buttonElement.Click += new RoutedEventHandler(buttonElement_Click);
            }
        }

        /* private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.A)
               A.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
            else if (e.Key == Key.B)
               B.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
        }*/

        void buttonElement_Click(object sender, RoutedEventArgs e)
        {
            // create variable for holding string
            String sendString = "";

            try
            {
                // stop all event handling
                e.Handled = true;

                // set sendstring to key
                sendString = ((Button)sender).CommandParameter.ToString();

                // if something to send
                if (!String.IsNullOrEmpty(sendString))
                {
                    // if sending a string
                    if (sendString.Length > 1)
                    {
                        // add {}
                        sendString = "{" + sendString + "}";
                    }

                    // if a focusable element has been specified
                    if (this.focusedInputElement != null)
                    {
                        Console.WriteLine("1",sendString);
                        // set keyboard focus
                        Keyboard.Focus(this.focusedInputElement);
                        // set normal focus
                        this.focusedInputElement.Focus();
                    }

                    // send key to simulate key press
                   // System.Windows.Forms.SendKeys.Send(sendString);

                   System.Windows.Forms.SendKeys.SendWait(sendString);
                    Console.WriteLine(sendString);

                }
            }
            catch (Exception)
            {
                // do nothing - not important for now
                Console.WriteLine("Could not send key press: {0}", sendString);
            }
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            // if we have specified a parent
            if (this.parentWindow != null)
            {
                // Get this window's handle
                IntPtr HWND = new WindowInteropHelper(this.parentWindow).Handle;
                Console.WriteLine("Run in UserControl load");
                // style of window?
                int GWL_EXSTYLE = (-20);
                // get - retrieves information about a specified window
                GetWindowLong(HWND, GWL_EXSTYLE);
                // set - changes the attribute of a specified window - I think this stops it being focused on
                SetWindowLong(HWND, GWL_EXSTYLE, (IntPtr)(0x8000000));
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

最可靠的方法是使用Win32 API

[DllImport("user32.dll")]
public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

[DllImport("user32.dll", EntryPoint = "SendInput")]
public static extern uint SendInput(uint nInputs, InputKeys[] inputs, int cbSize);

在CodePlex上使用工作应用程序完成了一个很好的例子

http://wosk.codeplex.com/