読者です 読者をやめる 読者になる 読者になる

モノトーンの伝説日記

OBS Studio と Blackmagic Design が大好き。

【C++/CX 向け Behavior】 KeyTriggerBehavior を実装しました。

 Behavior いいよね!

概要

  1. Windows 8.1 向け Native Blend SDK の悲しさ
  2. Blend SDK for WPF にある KeyTriggerBehavior
  3. C++/CX 版 KeyTriggerBehavior について
  4. 配布、検証、考えていること等

1. Windows 8.1 向け Native Blend SDK の悲しさ

 実は 2 つしか用意されていないんです。それは「EventTriggerBehavior」と「IncrementalUpdateBehavior」。これじゃあせっかくの Behavior が台無しじゃないですか…

 ということで、第一弾作りました (Action が使える Behavior ね)。

2. Blend SDK for WPF にある KeyTriggerBehavior

 まず懐かしき過去のテクノロジーである WPF さんですが、こいつで、KeyTrigger っていうのがあります。こいつがなかなかよくて (確かに xaml からは Ctrl+Alt とかできないですが)、使ってた記憶があります。

 とりあえずこれを模倣して作ろうということで、大学に行くまでの 1 時間ぐらいで書こうとしたのですが、まあ間に合わなかった。1 時間半ぐらいでコード自体はかけたかな、って感じのやつです。さほど大したことないのでね。

3. C++/CX 版 KeyTriggerBehavior について

 基本的に NavigationHelper とかいうデフォルトのテンプレートあったと思いますが、アレに倣ってキーボード入力を監視することにしました。

auto coreWindow = Window::Current->CoreWindow;
auto downState = CoreVirtualKeyStates::Down;
auto controlKey = ( coreWindow->GetKeyState( VirtualKey::Control ) & downState ) == downState;
auto menuKey = ( coreWindow->GetKeyState( VirtualKey::Menu ) & downState ) == downState;
auto shiftKey = ( coreWindow->GetKeyState( VirtualKey::Shift ) & downState ) == downState;
auto leftWindowsKey = ( coreWindow->GetKeyState( VirtualKey::LeftWindows ) & downState ) == downState;
auto rightWindowsKey = ( coreWindow->GetKeyState( VirtualKey::RightWindows ) & downState ) == downState;
auto windowsKey = leftWindowsKey || rightWindowsKey;

 ちなみに LeftControl, RightControl などを用いることで左右別々に取れることも確認しました。

 現行ではこんな感じのコードで KeyModefiers を監視していて、例えば Alt+X とかなら Ctrl でも Win でも Shift でも押されていたら NG なコードになるようにしてあります。

 API ついてですが、

public extern VirtualKey Key { get; set; }
public extern VirtualKeyModifiers KeyModifiers  { get; set; }
public extern KeyTriggerFiredOn FiredOn { get; set; }
public extern ActionCollection Actions { get; set; }
public extern DependencyObject AssociatedObject  { get; }

といった感じ。VirtualKey とかは Windows::System にあるのをそのまま使っているので無効な指定もあることに注意はしてほしい感じ。

4. 配布、検証、考えていること等

 実はまだ NuGet 版 の更新はしていません。API 周りが完全にこれだ! っていうのが決まっていないので。

 現行では xaml だと Alt+Ctrl っていう表現が不可能だと思うんですね。これだとわざわざコードビハインドとかで KeyModifiers = VirtualKeyModifiers::Menu | VirtualKeyModifiers::Control; とか書かないといけないんですよね。これ、厄介だと思うし、専用の Enum でも用意しようかな、とか、あと左右 Alt/Control/Shift/Win 使えるようにしようか、とかいろいろ悩んでたりします。そういう意見あるとありがたいんですが、まあこのあたりはしばらく使ってみてから決めることにします。

 とりあえず GitHub 版 は更新しているので、git clone でもして使ってみるといいかもしれません。