[英]How can I get keyboard input when WebView visible in C++/XAML/UWP App?
I have a game app that is rendered on a Canvas, with an interface rendered in a WebView.我有一个在 Canvas 上呈现的游戏应用程序,其界面呈现在 WebView 中。
All the pre-game menus happen in the WebView.所有的赛前菜单都出现在 WebView 中。 When the game starts I switch the WebView to a page with a transparent background so you can see the game Canvas through it, but I can still overlay some interface elements.当游戏开始时,我将 WebView 切换到具有透明背景的页面,以便您可以通过它看到游戏 Canvas,但我仍然可以覆盖一些界面元素。
This all works fine graphically, and I can see my game clearly with the WebView interface overlayed.这一切都以图形方式运行良好,我可以通过覆盖的 WebView 界面清楚地看到我的游戏。 I can communicate between the game and the interface quite happily.我可以很愉快地在游戏和界面之间进行交流。
The problem I have is getting the WebView to give up the keyboard, so I can use the keys to control the game.我遇到的问题是让 WebView 放弃键盘,所以我可以使用按键来控制游戏。
My keyboard listener is triggered on the (theoretically) global event Window.Current.CoreWindow.KeyDown, so it should get keyboard events whatever has the focus.我的键盘侦听器是在(理论上)全局事件 Window.Current.CoreWindow.KeyDown 上触发的,因此它应该获取具有焦点的键盘事件。
If I hide the WebView everything works fine, the keyboard events are picked up and the game is controllable.如果我隐藏 WebView 一切正常,键盘事件被拾取并且游戏是可控的。 Obviously though I can't see the overlayed elements.显然,虽然我看不到重叠的元素。
Is there some way to let me receive the keyboard events when the WebView is visible?有什么方法可以让我在 WebView 可见时接收键盘事件?
This is a Win 10/UWP app written in XAML/C++.这是一个用 XAML/C++ 编写的 Win 10/UWP 应用程序。 Target platform is Win 10 10.0.14393.0/ minimum 10.0.10586.0 Tested on Surface Book running Windows 10 v1703 15063.674目标平台为 Win 10 10.0.14393.0/ 最低 10.0.10586.0 在运行 Windows 10 v1703 15063.674 的 Surface Book 上测试
It is possible to release the focus from the WebView by hiding and then showing it again immediately.可以通过隐藏然后立即再次显示来释放 WebView 的焦点。
webView->Visibility = Visibility::Collapsed;
webView->Visibility = Visibility::Visible;
Even if there's nowhere else for the focus to go - after this operation, FocusManager::GetFocusedElement()
will return null.即使焦点无处可去 - 在此操作之后, FocusManager::GetFocusedElement()
将返回 null。
The webview will remain visible, but keyboard events can now be received via Window.Current.CoreWindow.KeyDown
. webview 将保持可见,但现在可以通过Window.Current.CoreWindow.KeyDown
接收键盘事件。
Note however that any interaction with the webview (eg. touch, navigation) will cause it to regain focus and you will stop receiving keyboard events.但是请注意,与 webview 的任何交互(例如触摸、导航)都会使其重新获得焦点,并且您将停止接收键盘事件。
This isn't a very satisfactory solution, but it sort-of fulfills the requirement to see the webview but also receive keyboard events.这不是一个非常令人满意的解决方案,但它在某种程度上满足了查看 webview 和接收键盘事件的要求。
Had a similar problem but managed to fix it with this trick based on Andy's answer:有一个类似的问题,但根据安迪的回答设法用这个技巧解决了它:
DispatcherTimer timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(100)
};
timer.Tick += (s, e) =>
{
if (FocusManager.GetFocusedElement() is WebView webView)
{
webView.Visibility = Visibility.Collapsed;
webView.Visibility = Visibility.Visible;
}
};
timer.Start();
We have a Webview that must be interactive in our game at all times.我们有一个 Webview,它必须始终在我们的游戏中进行交互。 The least ugly workaround that I have found so far is injecting a global event listener into the javascript to hook keyboard input, and relaying this back to the app via notify()到目前为止,我发现的最不丑陋的解决方法是将全局事件侦听器注入 javascript 以挂钩键盘输入,并通过 notify() 将其转发回应用程序
function onKeyDown(ev: KeyboardEvent) {
let wrapper = { keyDown: ev }
window['external']['notify'](JSON.stringify(wrapper));
}
function onKeyUp(ev: KeyboardEvent) {
let wrapper = { keyUp: ev }
window['external']['notify'](JSON.stringify(wrapper));
}
...
let options: AddEventListenerOptions = { capture: true, passive:true,once:false }
document.addEventListener("keydown", onKeyDown, options);
document.addEventListener("keyup", onKeyUp, options);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.