Виртуальная клавиатура в WPF: эмулировать реальное устройство ввода?

Я хочу создать простую виртуальную клавиатуру в 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));
            }
        }
    }
}

person 思哲 Ф    schedule 12.04.2012    source источник
comment
Вы должны использовать KeyEvents из аргументов, которые вы можете передать ключевой символ   -  person Prabhavith    schedule 12.04.2012


Ответы (1)


Самый надежный способ сделать это — использовать 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/

person MarkDaniel    schedule 12.04.2012