public bool OnKeyEvent(CefSharp.IWebBrowser chromiumWebBrowser, CefSharp.IBrowser browser, CefSharp.KeyType type, int windowsKeyCode, int nativeKeyCode, CefSharp.CefEventFlags modifiers, bool isSystemKey) { Debug.WriteLine("OnKeyEvent: KeyType: {0} 0x{1:X} Modifiers: {2}", type, windowsKeyCode, modifiers); return(false); }
public bool OnPreKeyEvent(CefSharp.IWebBrowser chromiumWebBrowser, CefSharp.IBrowser browser, CefSharp.KeyType type, int windowsKeyCode, int nativeKeyCode, CefSharp.CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut) { const int WM_SYSKEYDOWN = 0x104; const int WM_KEYDOWN = 0x100; const int WM_KEYUP = 0x101; const int WM_SYSKEYUP = 0x105; const int WM_CHAR = 0x102; const int WM_SYSCHAR = 0x106; const int VK_TAB = 0x9; const int VK_LEFT = 0x25; const int VK_UP = 0x26; const int VK_RIGHT = 0x27; const int VK_DOWN = 0x28; isKeyboardShortcut = false; // Don't deal with TABs by default: // TODO: Are there any additional ones we need to be careful of? // i.e. Escape, Return, etc...? if (windowsKeyCode == VK_TAB || windowsKeyCode == VK_LEFT || windowsKeyCode == VK_UP || windowsKeyCode == VK_DOWN || windowsKeyCode == VK_RIGHT) { return(false); } var result = false; var control = chromiumWebBrowser as System.Windows.Forms.Control; var msgType = 0; switch (type) { case KeyType.RawKeyDown: if (isSystemKey) { msgType = WM_SYSKEYDOWN; } else { msgType = WM_KEYDOWN; } break; case KeyType.KeyUp: if (isSystemKey) { msgType = WM_SYSKEYUP; } else { msgType = WM_KEYUP; } break; case KeyType.Char: if (isSystemKey) { msgType = WM_SYSCHAR; } else { msgType = WM_CHAR; } break; default: Trace.Assert(false); break; } // We have to adapt from CEF's UI thread message loop to our fronting WinForm control here. // So, we have to make some calls that Application.Run usually ends up handling for us: var state = PreProcessControlState.MessageNotNeeded; // We can't use BeginInvoke here, because we need the results for the return value // and isKeyboardShortcut. In theory this shouldn't deadlock, because // atm this is the only synchronous operation between the two threads. control.Invoke(new Action(() => { var msg = new Message { HWnd = control.Handle, Msg = msgType, WParam = new IntPtr(windowsKeyCode), LParam = new IntPtr(nativeKeyCode) }; // First comes Application.AddMessageFilter related processing: // 99.9% of the time in WinForms this doesn't do anything interesting. var processed = Application.FilterMessage(ref msg); if (processed) { state = PreProcessControlState.MessageProcessed; } else { // Next we see if our control (or one of its parents) // wants first crack at the message via several possible Control methods. // This includes things like Mnemonics/Accelerators/Menu Shortcuts/etc... state = control.PreProcessControlMessage(ref msg); } })); if (state == PreProcessControlState.MessageNeeded) { // TODO: Determine how to track MessageNeeded for OnKeyEvent. isKeyboardShortcut = true; } else if (state == PreProcessControlState.MessageProcessed) { // Most of the interesting cases get processed by PreProcessControlMessage. result = true; } Debug.WriteLine("OnPreKeyEvent: KeyType: {0} 0x{1:X} Modifiers: {2}", type, windowsKeyCode, modifiers); Debug.WriteLine("OnPreKeyEvent PreProcessControlState: {0}", state); return(result); }