single.php

C# スクリーンロック操作から復帰後に修飾キーのイベントが正しく取得できない場合の原因

C#のWinFormsプロジェクトで、キーボードのキーの押されたイベントを検出するアプリで、スクリーンロック操作後に[Ctrl]などの修飾キーの取得が正しく処理されない場合の原因についてハマったので備忘録的に投稿します。

Ctrl+Alt+Deleteの組合せは特殊

例えば、WindowsHookを利用して検出して修飾キーとの組み合わせに利用するキーの[ダウン]と[アップ]などの状態を何かの変数で管理しているような場合に発生します。

私の場合は、スクリーンロック操作から復帰すると[Ctrl]キーが押された状態になりました。

原因は、Windowsでは[Ctrl+Alt+Delete]は特殊で、この組み合わせでキーが操作された場合にOS側がキーのイベントを横取りしてしまいます。

これは、ソフトが勝手にスクリーンロックやログオフをさせないために[Secure Attention Sequence]と呼ばれるセキュリティです。

グループポリシーエディターで無効化することも可能ですが、セキュリティを下げてしまうデメリットが生まれます。

スクリーンロックからの復帰で変数をクリア

最も効果的なのは、スクリーンロックから復帰のイベントを追加して、保持している変数を初期化します。

SystemEvents.SessionSwitch += (s, e) =>
{
    if (e.Reason == SessionSwitchReason.SessionLock ||
        e.Reason == SessionSwitchReason.SessionUnlock)
    {
        //変数の初期化
    }
};

[Secure Attention Sequence]が原因以外でもスクリーンロックから復帰した場合に変数を初期化すればスクリーンロック操作前の状態に戻るはずです。

スクリーンロック操作のキャンセルの場合

[Ctrl+Alt+Delete]で[ロック]操作を行わずにキャンセルした場合にはスクリーンロックからの復帰のイベントが発生しないため、変数が初期化されません。

キャンセルした場合を想定して、修飾キーを検出するルーチンをキーのダウンとアップの双方に追加することで、私は対処出来ました。

まとめ

今回は短い記事ですが、WinFormsプロジェクトで、キーボードのキーの押されたイベントを検出するアプリで、スクリーンロック操作後に[Ctrl]などの修飾キーの取得が正しく処理されない場合の原因について書きました。

Windowsでは、[Ctrl+Alt+Delete]は特殊で、この組み合わせでキーが操作された場合にOS側がキーのイベントを横取りしてしまいます。

そのため、スクリーンロックなどの操作をした場合、[Ctrl]や[Alt]キーのアップが検出できない可能性があります。

WinFormsプロジェクトでスクリーンロックからの復帰後にキーイベントが正しく検出できない人の参考になれば幸いです。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です