Entry

プログラミングメモ - スクリーンセーバーをプログラムから解除する

2009年12月25日

あんまりネタもないので,小ネタをば。

個人ではあまり作ることもないと思うんですけれど,Windows で指紋認証の読み取りソフトなんかを作るとき,指紋センサ以外の入力デバイスを設置したくないことがあります。余計な入力デバイスを置くと,ユーザさんがこれを使っちゃう可能性があって,セキュリティ等々の関係で問題があるからです。

一方で,こういう場合にも,しばらく操作しないときはスクリーンセーバーを起動したかったりもします。別に画面出しっぱなしでもいいんですけどね。なんとなく雰囲気で起動させたくなる。しかし,キーボードのような入力デバイスがないと,物理的なデバイスからこのスクリーンセーバーを解除する手段がなくなってしまう。そこで,こいつをどうやって解除しよう,というのがここでのお題です。

この点でひとつ考えられるのは,今動いているプロセスのリストを取得して,実行モジュールのイメージの拡張子が"scr"であるプロセスを強制的に KILL する方法です。指紋認証のドライバからもらう入力のシグナルをトリガにして,無理矢理プロセスを殺します。かなり乱暴だけれども,これでも動くし,実際にこの方法を勧めているところもあります。

しかし,こゆのはさすがにアレなので,別の方法を考える。考えてみると,これって単純にキーボードを押下するように,プログラムからエミュレートしちゃえばいいんですよね。こんな感じで。

#include <windows.h>
#include <winuser.h>
#include <tchar.h>

/**
 * Sleep for 10 seconds and simulate a key press.
 * NOTE: for compilation
 *   cl -GX keybd.cpp user32.lib
 */
int
_tmain(int argc, TCHAR* argv[]) {
    // sleep for 10 seconds.
    ::Sleep(10000);
    // push down a shift-key.
    ::keybd_event(VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
    // push up a shift-key.
    ::keybd_event(VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
    return 0;
}

上のプログラムを動かした直後に,スクリーンセーバーを起動します。プログラムを動かしてから,10秒後にスクリーンセーバーが解除されれば成功。あとは,Sleep 関数をトリガとなるイベントと置き換えれば,一丁上がりです。

やってることは単純で,プログラムから Shift キーを押してるだけ。ここでは,keybd_event 関数を使っているけれど,キーボードやマウスのエミュレートには,SendInput 関数を使うのがお作法らしいです。今手元にあるコンパイラが VC6 なもんで,SendInput を使えなかったのでした(INPUT 構造体がないと怒られる)。よい子は SendInput 関数を使うように。

ま,ただそれだけ。

Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN