none
richTextbox获取键盘焦点后首次输入无效(出现“噔”的提示音) RRS feed

  • 问题

  • 想做一个:热键(Alt+S)呼出一个窗口,窗口内有一个Richtextbox,呼出后直接输入(假定英文输入法),要求能够输入到Richtextbox里。

     private IntPtr MainWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) //系统消息回调
            {
                switch (msg)
                {
                    case HotKey.WM_HOTKEY:
                        {
                            int sid = wParam.ToInt32();
                            if (sid == alts) //输入Alt+S热键
                            {
    
                              this.WindowState = WindowState.Normal;
                                this.Topmost = true;
                               
                              
                                Keyboard.Focus(richTextBox);
                               
    ;                         
                            }
                            else if (sid == altd) //试图使用Alt+D隐藏
                            {
                                this.WindowState = WindowState.Minimized;
                            }
                            handled = true;
                            break;
                        }
                }
    
                return IntPtr.Zero;
            }

    目前采用这样的代码进行控制通过这样的编码后,尽管能够热键呼出窗口,呼出后键盘输入光标也在Richtextbox中闪,但是第一个键压下去的时候会出现噔的一声,有一种感觉当前窗口没被激活的样子。 紧接着输入就正常了。  不懂为什么会发生这样的问题。  想做到呼出、直接输入这样的流畅的功能。  恳请大家帮助。

    2016年10月20日 5:03

全部回复

  • Hi vinaJc,

    根据你想要实现的功能,我使用键盘钩子做了一个Demo。它可以实现呼出、直接正常输入的功能。 你可以试试下面的代码。

     keyevent Form:

     /// <summary>
        /// Interaction logic for keyevent.xaml
        /// </summary>
        public partial class keyevent : Window
        {
            private struct KBDLLHOOKSTRUCT
            {
                public int vkCode;
                int scanCode;
                public int flags;
                int time;
                int dwExtraInfo;
            }
    
            private delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
    
            [DllImport("user32.dll")]
            private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId);
    
            [DllImport("user32.dll")]
            private static extern bool UnhookWindowsHookEx(IntPtr hHook);
    
            [DllImport("user32.dll")]
            private static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
    
            [DllImport("kernel32.dll")]
            private static extern IntPtr GetModuleHandle(IntPtr path);
    
            private IntPtr hHook;
            LowLevelKeyboardProcDelegate hookProc; // prevent gc
            const int WH_KEYBOARD_LL = 13;
    
            public keyevent()
            {
                InitializeComponent();
                // hook keyboard
                IntPtr hModule = GetModuleHandle(IntPtr.Zero);
                hookProc = new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc);
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hModule, 0);
                if (hHook == IntPtr.Zero)
                {
                    MessageBox.Show("Failed to set hook, error = " + Marshal.GetLastWin32Error());
                }
    
            }
    
            private static int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam)
            {
                if (nCode >= 0)
                    switch (wParam)
                    {
                        case 256: // WM_KEYDOWN
                        case 257: // WM_KEYUP
                        case 260: // WM_SYSKEYDOWN
                        case 261: // M_SYSKEYUP
                            if (lParam.vkCode == 83 && lParam.flags == 32)
                            {
                                Showmessage showmess = new Showmessage();
                                showmess.Show();
                                showmess.Focus();
                                 return CallNextHookEx(1, nCode, wParam, ref lParam);
                            }
                            break;
                    }
                return CallNextHookEx(0, nCode, wParam, ref lParam);
            }
            private void Window_Closed(object sender, EventArgs e)
            {
                UnhookWindowsHookEx(hHook); // release keyboard hook
            }
        }

    Showmessage Form: 使用下面代码,指定第一焦点是一个文本框。

    FocusManager.FocusedElement="{Binding ElementName=inputtext}"


    Best Regards,

    Yohann Lu

    2016年10月21日 4:24
    版主