2019年1月7日月曜日

Windowsキーを無効にする方法

幼児用のお遊びアプリを作ってみたのですが、なにせメチャクチャにキーをたたくので、Windowsキーなどシステムが優先的にイベントを扱うキーが押されるとスタートメニューが表示されたり、Print Scrで画面がキャプチャーされたりしてしまいます。

そこで、こうしたキーを無効にする方法を調べてみました。

まずはMicorosoftのページ。
Disabling Shortcut Keys in Games

ゲームなどで誤って Windows key を押してしまっても、好ましくない動作をしないようにする方法を紹介しています。しかし、C++なので C# のプロジェクトにはそのままでは導入できません。

こちらからはC#のサンプルがダウンロードできます。
A Simple C# Global Low Level Keyboard Hook (StomySpike / Code Project)

そのままソースを取り込んでも動作可能ですが、このソースのままだと次のようなエラーが発生します。

マネージ デバッグ アシスタント 'CallbackOnCollectedDelegate'  が発生しました
…コールバックが、型 '...+keyboardHookProc::Invoke' のガベージ コレクションされたデリゲートで行われました。…デリゲートをアンマネージ コードに渡すとき、デリゲートは 2 度と呼び出されないことが確実になるまでマネージ アプリケーションによって維持されなければなりません。'

これの解決策が次の Stack Overflow のQ&Aにありました。私は、これに従って若干変更して使っています。

C++のアンマネージドの環境ではdelegateがガベージ コレクションされなかったが、C#のマネージドの環境ではガベージ コレクションされてしまい、その結果上記のエラーが発生します。

同様の内容のページがあります。
CallbackOnCollectedDelegate が発生しました。(Cafe's Room)

callbackOnCollectedDelegateについてのMicrosoftの解説です。
callbackOnCollectedDelegate MDA

このソースで使われている関数については、次のページの説明が参考になります。
EternalWindows / Windows 開発 / メッセージ管理 / メッセージフック