Meetingsをはじめとするビデオ・コミュニケーションが、日常利用において何も例外的な存在ではない時代となった。それはオンライン・ミーティングに限らず、大人数が出席する、いわゆるカンファレンスでも用いられている。このような時、あると便利なのが画面キャプチャ、スクリーンショットのためのツールだ。プレゼンテーション資料が配布されない場合、今まさに移っている画面をメモ代わりにキャプチャする。Windows標準の操作では、スクリーンショットを取り、画像編集ソフトにコピーし、画像ファイルとして保存する、という手順を経る必要がある。これをボタン一つで、ファイル出力まで完結させたいと思い、とあるフリーウェアを使っていた。これが気づかないうちに無反応になるときがあるのだ。この現象があまりに頻発するので、ツールを自作することにした。作業をしているうちに気付くのだ。API呼び出しが避けられないことに。それは次の場面で必要とされる。Window(最前面のWindow)を検出する。特定キー押下のタイミングを検出する。この投稿では、2の話題を含めた、イベントフックのコードを紹介する。ソースコード全体は投稿末尾に掲載している。Snap参照MicrosoftソースコードHook(フック)システムを監視し、特定のイベントが発生したときに処理を横取りすることをHook(フック)と言う。イベントドリブンなプログラムにおいて、発生したイベントに対応するプログラムをイベントハンドラと呼ぶ。Studioなどでは、これが部品として提供されているものの、それが動作する範囲外で同じことを実現しようと思えば、期待するイベントを独自に監視し、フックする仕組みを実装しなければならない。SetWindowsHookExWindows上のイベントを監視しHookする手順は、イベントの種類に限らず共通だ。APIの「SetWindowsHookEx」を呼び出す。Learnそれぞれの引数は次のように定義されている。Hook対象となるスレッドidHook引用元にあらかじめ定義されている定数一覧が収録されている。キーボード・イベントなら「WH_KEYBOARD_LL」、マウス・イベントなら「WH_MOUSE_LL」と言った具合だ。lpfnHookしたときの実行処理を含むメソッド名を引き渡す。後述するプログラムでは、キーボード・イベント発生の度に、メソッド「HookCallback」を呼び出している。hmodHook処理(lpfn)が収録されているモジュール名を引き渡す。Hookプログラムと、メソッドが同一クラスに存在する場合、自分自身を引き渡すことになる。この場合は、次のように指定する。GetModuleHandle(Process.GetCurrentProcess().MainModule);dwThreadIdHook対象となるスレッドIDを引き渡す。既存の全スレッドをHook対象とする場合は「0」を指定する。次のサイトに掲載されている「全てのキー入力を捨てる」のプログラムが、まさに典型例だ。1;}例えば、あらかじめプロジェクトの設定として、対象となるキーと押下イベントを指定しているものとする。Properties.Settings.Default.trigger_key;目的のキーで、目的の押下イベントが発生したときに、スクリーンショットを取得するプログラム*1を呼び出そうと思えば、メソッド「HookCallback」を次のように書き換えると良い。Snapは、windowキャプチャからファイル保存までを1ボタンの操作に集約したツールだ。ここで紹介しているコードと画面キャプチャ*2を組み合わせて作成した。この開発のために、まさかキー・ロガー的な仕組みを実装しなければならないとは、想像もしていなかった。別解的なアプローチも存在した。PrintScn押下イベントを独自に生成し、クリップボードから画像を取得する方法だ。個人的にはキー・ロガー的な仕組みの方が自然に感じたので、こちらを採用した。GitHubでコードを公開しているので、関心があれば参照してほしい。TOGAFTumblrはてなブログをはじめよう!espio999さんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。