WindowsマシンをKIOSK端末のように使う想定で、アプリが常に入力フォーカスを持つようにしたいというニーズあり。すなわち、バックグラウンドで動いているアプリがメッセージを表示してもフォーカスを移すことなく、メインのアプリが常に前面かつ入力フォーカスを持つようにしたい。
まず思いついたのは、アプリのメインフォームにTopMost(常に最前面に表示)の属性をセットすること。試してみると、確かにフォームは常に最前面に表示されるけど、キーボードの入力フォーカスは他のアプリに移ってしまうことがあった。入力フォーカスをアプリに取り戻すためには、マウスでフォームをクリックしてやる必要がある。これでは要件が満足されない。
それじゃと思いついたのは、キーボードをグローバルフックすること。ネットを検索してみたら同じような事例が見つかる。だけどWin32 APIを呼んでやらないといけないのでちょっと面倒かな。もっと手軽にできる方法は無いだろうか。
C# フォームが非アクティブな状態でもキー判定を行いたい – Yahoo!知恵袋
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1080106570
ぬるり。: グローバルフック・ザ・キーボード
http://hongliang.seesaa.net/article/7539988.html
そこで思いついたのは以下の方法。タイマーを使って周期的に自分をアクティブ化することで、常にこのフォームがキーボードフォーカスを得る。インターバルを短くし過ぎるとタイマー処理のオーバーヘッドが大きくなるので注意が必要かも。あまりマナーの良い方法じゃないので自慢できたものじゃないが、手軽に実装したければこういう方法もありということで。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Timer timer = new Timer(); public Form1() { InitializeComponent(); this.TopMost = true; timer.Interval = 500; timer.Tick += new EventHandler(timer_Tick); timer.Start(); } void timer_Tick(object sender, EventArgs e) { this.Activate(); } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); Console.Beep(); // to make sure } |