AcceleratorKeyActivated 事件参数 KeyStatus.WasKeyDown 键按下时字段始终为 false
AcceleratorKeyActivated event args KeyStatus.WasKeyDown field is always false when key is down
当按下并按住一个键时 CoreDispatcher::AcceleratorKeyActivated 事件被触发并且 KeyStatus.WasKeyDown 字段始终为 false。 CoreWindow::KeyDown 事件已正确设置 WasKeyDown。实际上,最近似乎行为发生了变化。以前按住一个键会导致 KeyDown / KeyUp 事件,但现在它只会导致 KeyDown。有人可以证实这一点吗?
这里有一些例子:
// IFrameworkView::SetWindow implementation
public: virtual void
SetWindow(::Windows::UI::Core::CoreWindow ^ h_window)
{
h_window->Dispatcher->AcceleratorKeyActivated += ref new ::Windows::Foundation::TypedEventHandler
<
::Windows::UI::Core::CoreDispatcher ^
, ::Windows::UI::Core::AcceleratorKeyEventArgs ^
>
(this, &CView::On_Key);
h_window->KeyDown += ref new ::Windows::Foundation::TypedEventHandler
<
::Windows::UI::Core::CoreWindow ^
, ::Windows::UI::Core::KeyEventArgs ^
>
(this, &CView::On_KeyDown);
h_window->KeyUp += ref new ::Windows::Foundation::TypedEventHandler
<
::Windows::UI::Core::CoreWindow ^
, ::Windows::UI::Core::KeyEventArgs ^
>
(this, &CView::On_KeyUp);
}
private: static void
Trace_InputEvent
(
wchar_t const * psz_description
, ::Windows::System::VirtualKey const virtual_key
, bool const was_down
, bool const is_released
, unsigned int const repeats_count
)
{
::std::wstringstream ss;
ss << psz_description;
ss << L" " << static_cast< int >(virtual_key);
if(was_down)
{
ss << L" was down";
}
if(is_released)
{
ss << L" is released";
}
if(1 < repeats_count)
{
ss << L" repeats for " << repeats_count;
}
ss << L"\n";
ss.flush();
::OutputDebugStringW(ss.str().c_str());
}
private: void
On_Key
(
::Windows::UI::Core::CoreDispatcher ^ h_dispatcher
, ::Windows::UI::Core::AcceleratorKeyEventArgs ^ h_args
)
{
auto const key_down
{
(::Windows::UI::Core::CoreAcceleratorKeyEventType::SystemKeyDown == h_args->EventType)
||
(::Windows::UI::Core::CoreAcceleratorKeyEventType::KeyDown == h_args->EventType)
};
auto const key_up
{
(::Windows::UI::Core::CoreAcceleratorKeyEventType::SystemKeyUp == h_args->EventType)
||
(::Windows::UI::Core::CoreAcceleratorKeyEventType::KeyUp == h_args->EventType)
};
if(key_down || key_up)
{
Trace_InputEvent
(
(key_down ? L"On_Key(Down)" : L"On_Key(Up)")
, h_args->VirtualKey
, h_args->KeyStatus.WasKeyDown
, h_args->KeyStatus.IsKeyReleased
, h_args->KeyStatus.RepeatCount
);
}
//h_args->Handled = true; // Marking event as handled prevents On_KeyDown / On_KeyUp events from being emmitted.
}
private: void
On_KeyDown
(
::Windows::UI::Core::CoreWindow ^ h_dispatcher
, ::Windows::UI::Core::KeyEventArgs ^ h_args
)
{
Trace_InputEvent
(
L"On_KeyDown"
, h_args->VirtualKey
, h_args->KeyStatus.WasKeyDown
, h_args->KeyStatus.IsKeyReleased
, h_args->KeyStatus.RepeatCount
);
}
private: void
On_KeyUp
(
::Windows::UI::Core::CoreWindow ^ h_dispatcher
, ::Windows::UI::Core::KeyEventArgs ^ h_args
)
{
Trace_InputEvent
(
L"On_KeyUp"
, h_args->VirtualKey
, h_args->KeyStatus.WasKeyDown
, h_args->KeyStatus.IsKeyReleased
, h_args->KeyStatus.RepeatCount
);
}
按住空格键输出:
On_Key(Down) 32
On_KeyDown 32
On_Key(Down) 32
On_KeyDown 32 was down
On_Key(Down) 32
On_KeyDown 32 was down
...
On_Key(Down) 32
On_KeyDown 32 was down
On_Key(Up) 32 was down is released
On_KeyUp 32 was down is released
RS1 中存在一个已知问题。 MSDN论坛也有报道:CoreDispatcher.AcceleratorKeyActivated event: WasKeyDown property behaves differently on 10586.753 and 14393.693 (anniversary edition)
在使用XAML的过程中,AcceleratorKeyEventArgs里面的KeyStatus
被忽略了,所以WasKeyDown
不正确。
作为解决方法,请改用 GetKeyState(VirtualKey)
方法。
private void Dispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
{
var corewindow = CoreWindow.GetForCurrentThread();
System.Diagnostics.Debug.WriteLine("AcceleratorKeyActivated-VirtualKey: " +
args.VirtualKey
+ " -- KeyState: " +
corewindow.GetKeyState(VirtualKey.Space));//Here
}
输出:
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Locked
当按下并按住一个键时 CoreDispatcher::AcceleratorKeyActivated 事件被触发并且 KeyStatus.WasKeyDown 字段始终为 false。 CoreWindow::KeyDown 事件已正确设置 WasKeyDown。实际上,最近似乎行为发生了变化。以前按住一个键会导致 KeyDown / KeyUp 事件,但现在它只会导致 KeyDown。有人可以证实这一点吗?
这里有一些例子:
// IFrameworkView::SetWindow implementation
public: virtual void
SetWindow(::Windows::UI::Core::CoreWindow ^ h_window)
{
h_window->Dispatcher->AcceleratorKeyActivated += ref new ::Windows::Foundation::TypedEventHandler
<
::Windows::UI::Core::CoreDispatcher ^
, ::Windows::UI::Core::AcceleratorKeyEventArgs ^
>
(this, &CView::On_Key);
h_window->KeyDown += ref new ::Windows::Foundation::TypedEventHandler
<
::Windows::UI::Core::CoreWindow ^
, ::Windows::UI::Core::KeyEventArgs ^
>
(this, &CView::On_KeyDown);
h_window->KeyUp += ref new ::Windows::Foundation::TypedEventHandler
<
::Windows::UI::Core::CoreWindow ^
, ::Windows::UI::Core::KeyEventArgs ^
>
(this, &CView::On_KeyUp);
}
private: static void
Trace_InputEvent
(
wchar_t const * psz_description
, ::Windows::System::VirtualKey const virtual_key
, bool const was_down
, bool const is_released
, unsigned int const repeats_count
)
{
::std::wstringstream ss;
ss << psz_description;
ss << L" " << static_cast< int >(virtual_key);
if(was_down)
{
ss << L" was down";
}
if(is_released)
{
ss << L" is released";
}
if(1 < repeats_count)
{
ss << L" repeats for " << repeats_count;
}
ss << L"\n";
ss.flush();
::OutputDebugStringW(ss.str().c_str());
}
private: void
On_Key
(
::Windows::UI::Core::CoreDispatcher ^ h_dispatcher
, ::Windows::UI::Core::AcceleratorKeyEventArgs ^ h_args
)
{
auto const key_down
{
(::Windows::UI::Core::CoreAcceleratorKeyEventType::SystemKeyDown == h_args->EventType)
||
(::Windows::UI::Core::CoreAcceleratorKeyEventType::KeyDown == h_args->EventType)
};
auto const key_up
{
(::Windows::UI::Core::CoreAcceleratorKeyEventType::SystemKeyUp == h_args->EventType)
||
(::Windows::UI::Core::CoreAcceleratorKeyEventType::KeyUp == h_args->EventType)
};
if(key_down || key_up)
{
Trace_InputEvent
(
(key_down ? L"On_Key(Down)" : L"On_Key(Up)")
, h_args->VirtualKey
, h_args->KeyStatus.WasKeyDown
, h_args->KeyStatus.IsKeyReleased
, h_args->KeyStatus.RepeatCount
);
}
//h_args->Handled = true; // Marking event as handled prevents On_KeyDown / On_KeyUp events from being emmitted.
}
private: void
On_KeyDown
(
::Windows::UI::Core::CoreWindow ^ h_dispatcher
, ::Windows::UI::Core::KeyEventArgs ^ h_args
)
{
Trace_InputEvent
(
L"On_KeyDown"
, h_args->VirtualKey
, h_args->KeyStatus.WasKeyDown
, h_args->KeyStatus.IsKeyReleased
, h_args->KeyStatus.RepeatCount
);
}
private: void
On_KeyUp
(
::Windows::UI::Core::CoreWindow ^ h_dispatcher
, ::Windows::UI::Core::KeyEventArgs ^ h_args
)
{
Trace_InputEvent
(
L"On_KeyUp"
, h_args->VirtualKey
, h_args->KeyStatus.WasKeyDown
, h_args->KeyStatus.IsKeyReleased
, h_args->KeyStatus.RepeatCount
);
}
按住空格键输出:
On_Key(Down) 32
On_KeyDown 32
On_Key(Down) 32
On_KeyDown 32 was down
On_Key(Down) 32
On_KeyDown 32 was down
...
On_Key(Down) 32
On_KeyDown 32 was down
On_Key(Up) 32 was down is released
On_KeyUp 32 was down is released
RS1 中存在一个已知问题。 MSDN论坛也有报道:CoreDispatcher.AcceleratorKeyActivated event: WasKeyDown property behaves differently on 10586.753 and 14393.693 (anniversary edition)
在使用XAML的过程中,AcceleratorKeyEventArgs里面的KeyStatus
被忽略了,所以WasKeyDown
不正确。
作为解决方法,请改用 GetKeyState(VirtualKey)
方法。
private void Dispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
{
var corewindow = CoreWindow.GetForCurrentThread();
System.Diagnostics.Debug.WriteLine("AcceleratorKeyActivated-VirtualKey: " +
args.VirtualKey
+ " -- KeyState: " +
corewindow.GetKeyState(VirtualKey.Space));//Here
}
输出:
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Down, Locked
AcceleratorKeyActivated-VirtualKey: Space -- KeyState: Locked