[Windows] support English characters input

This commit is contained in:
Prome
2022-09-14 22:26:06 +08:00
parent b1c9d8b149
commit 343d986d0c
5 changed files with 142 additions and 6 deletions

View File

@@ -39,6 +39,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
while (::GetMessage(&msg, nullptr, 0, 0)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
//add this line to enable cef keybord input
processKeyEventForCEF(msg.message, msg.wParam, msg.lParam);
}
::CoUninitialize();

View File

@@ -18,6 +18,8 @@ FLUTTER_PLUGIN_EXPORT void WebviewCefPluginCApiRegisterWithRegistrar(
FLUTTER_PLUGIN_EXPORT void initCEFProcesses();
FLUTTER_PLUGIN_EXPORT void processKeyEventForCEF(unsigned int message, unsigned __int64 wParam, __int64 lParam);
#if defined(__cplusplus)
} // extern "C"
#endif

View File

@@ -15,7 +15,6 @@
#include<iostream>
#include <mutex>
#include "include/cef_app.h"
#include "simple_app.h"
namespace webview_cef {
@@ -151,6 +150,11 @@ namespace webview_cef {
registrar->AddPlugin(std::move(plugin));
}
void WebviewCefPlugin::sendKeyEvent(CefKeyEvent ev)
{
handler.get()->sendKeyEvent(ev);
}
WebviewCefPlugin::WebviewCefPlugin() {}
WebviewCefPlugin::~WebviewCefPlugin() {}

View File

@@ -6,11 +6,14 @@
#include <memory>
#include "include/cef_app.h"
namespace webview_cef {
class WebviewCefPlugin : public flutter::Plugin {
public:
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);
static void sendKeyEvent(CefKeyEvent ev);
WebviewCefPlugin();

View File

@@ -6,13 +6,137 @@
#include "include/cef_app.h"
void WebviewCefPluginCApiRegisterWithRegistrar(
FlutterDesktopPluginRegistrarRef registrar) {
webview_cef::WebviewCefPlugin::RegisterWithRegistrar(
flutter::PluginRegistrarManager::GetInstance()
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
FlutterDesktopPluginRegistrarRef registrar) {
webview_cef::WebviewCefPlugin::RegisterWithRegistrar(
flutter::PluginRegistrarManager::GetInstance()
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
}
FLUTTER_PLUGIN_EXPORT void initCEFProcesses() {
CefMainArgs mainArgs;
CefExecuteProcess(mainArgs, nullptr, nullptr);
}
}
bool IsKeyDown(WPARAM wparam) {
return (GetKeyState((int)wparam) & 0x8000) != 0;
}
int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam) {
int modifiers = 0;
if (IsKeyDown(VK_SHIFT))
modifiers |= EVENTFLAG_SHIFT_DOWN;
if (IsKeyDown(VK_CONTROL))
modifiers |= EVENTFLAG_CONTROL_DOWN;
if (IsKeyDown(VK_MENU))
modifiers |= EVENTFLAG_ALT_DOWN;
// Low bit set from GetKeyState indicates "toggled".
if (::GetKeyState(VK_NUMLOCK) & 1)
modifiers |= EVENTFLAG_NUM_LOCK_ON;
if (::GetKeyState(VK_CAPITAL) & 1)
modifiers |= EVENTFLAG_CAPS_LOCK_ON;
switch (wparam) {
case VK_RETURN:
if ((lparam >> 16) & KF_EXTENDED)
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_INSERT:
case VK_DELETE:
case VK_HOME:
case VK_END:
case VK_PRIOR:
case VK_NEXT:
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
if (!((lparam >> 16) & KF_EXTENDED))
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_NUMLOCK:
case VK_NUMPAD0:
case VK_NUMPAD1:
case VK_NUMPAD2:
case VK_NUMPAD3:
case VK_NUMPAD4:
case VK_NUMPAD5:
case VK_NUMPAD6:
case VK_NUMPAD7:
case VK_NUMPAD8:
case VK_NUMPAD9:
case VK_DIVIDE:
case VK_MULTIPLY:
case VK_SUBTRACT:
case VK_ADD:
case VK_DECIMAL:
case VK_CLEAR:
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_SHIFT:
if (IsKeyDown(VK_LSHIFT))
modifiers |= EVENTFLAG_IS_LEFT;
else if (IsKeyDown(VK_RSHIFT))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_CONTROL:
if (IsKeyDown(VK_LCONTROL))
modifiers |= EVENTFLAG_IS_LEFT;
else if (IsKeyDown(VK_RCONTROL))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_MENU:
if (IsKeyDown(VK_LMENU))
modifiers |= EVENTFLAG_IS_LEFT;
else if (IsKeyDown(VK_RMENU))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_LWIN:
modifiers |= EVENTFLAG_IS_LEFT;
break;
case VK_RWIN:
modifiers |= EVENTFLAG_IS_RIGHT;
break;
}
return modifiers;
}
FLUTTER_PLUGIN_EXPORT void processKeyEventForCEF(unsigned int message, unsigned __int64 wParam, __int64 lParam)
{
if (message != WM_SYSCHAR && message != WM_SYSKEYDOWN && message != WM_SYSKEYUP && message != WM_KEYDOWN && message != WM_KEYUP && message != WM_CHAR) return;
CefKeyEvent event;
event.windows_key_code = (int)wParam;
event.native_key_code = (int)lParam;
event.is_system_key = message == WM_SYSCHAR || message == WM_SYSKEYDOWN ||
message == WM_SYSKEYUP;
if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
event.type = KEYEVENT_RAWKEYDOWN;
else if (message == WM_KEYUP || message == WM_SYSKEYUP)
event.type = KEYEVENT_KEYUP;
else
event.type = KEYEVENT_CHAR;
event.modifiers = GetCefKeyboardModifiers(wParam, lParam);
// mimic alt-gr check behaviour from
// src/ui/events/win/events_win_utils.cc: GetModifiersFromKeyState
if ((event.type == KEYEVENT_CHAR) && IsKeyDown(VK_RMENU)) {
// reverse AltGr detection taken from PlatformKeyMap::UsesAltGraph
// instead of checking all combination for ctrl-alt, just check current char
HKL current_layout = ::GetKeyboardLayout(0);
// https://docs.microsoft.com/en-gb/windows/win32/api/winuser/nf-winuser-vkkeyscanexw
// ... high-order byte contains the shift state,
// which can be a combination of the following flag bits.
// 1 Either SHIFT key is pressed.
// 2 Either CTRL key is pressed.
// 4 Either ALT key is pressed.
SHORT scan_res = ::VkKeyScanExW((WCHAR)wParam, current_layout);
constexpr auto ctrlAlt = (2 | 4);
if (((scan_res >> 8) & ctrlAlt) == ctrlAlt) { // ctrl-alt pressed
event.modifiers &= ~(EVENTFLAG_CONTROL_DOWN | EVENTFLAG_ALT_DOWN);
event.modifiers |= EVENTFLAG_ALTGR_DOWN;
}
}
webview_cef::WebviewCefPlugin::sendKeyEvent(event);
}