C#プログラミングの覚え書き。
C#に慣れることを兼ねて、つぎのようなアプリを作成する。
- グローバルフックを実装する。
- フォームを表示させずにタスクトレイにアイコンを表示する。
C#に慣れることを兼ねて、つぎのようなアプリを作成する。
- テンキーから入力すると押したキーの数字が発声される。
- そこそこの速さで入力しても反応よく音声が再生される。
- タスクトレイ常駐型。
これを実現するには、グローバルフックを実装する必要があるようだ。
自力では難しいので検索。海外のサイトでライブラリにしてあるのを発見。
RamGec Tools collection
コード内コメント行に記載してあるコピーライトと利用要件を書いておけば
自由に使ってよいとある。
使い方は簡単
キーダウンイベントを捉えたいのでkeyboardHook.csをプロジェクトに追加する。
ライブラリのインスタンスを生成してソメッドでイベントとコールバック関数を
定義したらキーボードイベントをキャプチャできる。
その部分の記述は
終了時に keyboardHook.Uninstall(); で解放する。
あとは
自力では難しいので検索。海外のサイトでライブラリにしてあるのを発見。
RamGec Tools collection
コード内コメント行に記載してあるコピーライトと利用要件を書いておけば
自由に使ってよいとある。
使い方は簡単
キーダウンイベントを捉えたいのでkeyboardHook.csをプロジェクトに追加する。
ライブラリのインスタンスを生成してソメッドでイベントとコールバック関数を
定義したらキーボードイベントをキャプチャできる。
その部分の記述は
RamGecTools.KeyboardHook keyboardHook = new RamGecTools.KeyboardHook(); keyboardHook.KeyDown += new RamGecTools.KeyboardHook.KeyboardHookCallback(keyboardHook_KeyDown); keyboardHook.Install();これだけ、たったの3行で完了、すばらしく便利です。
終了時に keyboardHook.Uninstall(); で解放する。
あとは
private void keyboardHook_KeyDown(RamGecTools.KeyboardHook.VKeys key) { // ライブラリに列挙されたキーコードがkeyで受け取れる。 }MouseHook.csを使えばマウスイベントをキャプチャできる。
DOBON.NET パラメータを指定せずにApplication.Runを呼び出す方法を参考にした。
C#のWindowsフォームアプリケーションのテンプレートでは
Program.cs の Main()で下記のように記述されている。
Application.Run(new Form1()); フォームを表示してアプリケーション開始する。
ここを Application.Run に Form1 を渡さないようにすると
new Form1();
Application.Run();
これでフォームを表示しないでアプリケーション開始できる。
C#のWindowsフォームアプリケーションのテンプレートでは
Program.cs の Main()で下記のように記述されている。
Application.Run(new Form1()); フォームを表示してアプリケーション開始する。
ここを Application.Run に Form1 を渡さないようにすると
new Form1();
Application.Run();
これでフォームを表示しないでアプリケーション開始できる。
NotifyIconとContextMenuStripツールを使う。
NotifyIconにアイコンを設定
当然だがアイコンを設定しないとタスクトレイには表示されない。
フォームもタスクバーも表示されていないので終了操作にも困る。
NotifyIconにContextMenuStripを設定
タスクトレイにアイコンが表示されていてもContextMenuStripを設定しないと
アイコンを右クリックしてもイベントが発生しない。
終了イベントでの処理
NotifyIconのVisibleプロパティをfalseにしてタスクトレイから消す。
Application.Exit(); で終了。
ここまでがポイント。
あとは特筆するテクニックなどはないです。手順をまとめると
テンキーでの発声(CheckedをTrueに)
アプリ終了
3項目ともダブルクリックしてイベントハンドラーを生成
Application.Run();
Microsoft.DirectX.DirectSound
(ついでにいらない参照を削除した。)
ビルド -> プラットホームターゲットを'x86'に設定
NotifyIconにアイコンを設定
当然だがアイコンを設定しないとタスクトレイには表示されない。
フォームもタスクバーも表示されていないので終了操作にも困る。
NotifyIconにContextMenuStripを設定
タスクトレイにアイコンが表示されていてもContextMenuStripを設定しないと
アイコンを右クリックしてもイベントが発生しない。
終了イベントでの処理
NotifyIconのVisibleプロパティをfalseにしてタスクトレイから消す。
Application.Exit(); で終了。
ここまでがポイント。
あとは特筆するテクニックなどはないです。手順をまとめると
- Windowsフォームアプリケーションのテンプレートでプロジェクトをつくる。
- keyboardHook.csをプロジェクトに追加
- 音声リソースを準備
- アイコンリソースを準備
- NotifyIconとContextMenuStripをForm1に配置
- NotifyIcon1にアイコンとContextMenuStrip1を設定
- ContextMenuStrip1の設定
テンキーでの発声(CheckedをTrueに)
アプリ終了
3項目ともダブルクリックしてイベントハンドラーを生成
- Program.csの編集
Application.Run();
- 参照設定の追加
Microsoft.DirectX.DirectSound
(ついでにいらない参照を削除した。)
- プロジェクトのプロパティ設定
ビルド -> プラットホームターゲットを'x86'に設定
- フォームのコーディング
using System; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.DirectSound; namespace NumKeyVoice { public partial class Form1 : Form { private RamGecTools.KeyboardHook keyboardHook = new RamGecTools.KeyboardHook(); BufferDescription desc = new BufferDescription(); Device dev = null; SecondaryBuffer[] sBuf; public Form1() { InitializeComponent(); DirectSoundSetting(); keyboardHook.KeyDown += new RamGecTools.KeyboardHook.KeyboardHookCallback(keyboardHook_KeyDown); keyboardHook.Install(); } private void DirectSoundSetting() { dev = new Device(); dev.SetCooperativeLevel(this, CooperativeLevel.Normal); sBuf = new SecondaryBuffer[15]; WaveFormat wf = new WaveFormat(); desc.BufferBytes = wf.AverageBytesPerSecond; desc.GlobalFocus = true; desc.ControlVolume = true; sBuf[0] = new SecondaryBuffer(Properties.Resources._0, desc, dev); sBuf[1] = new SecondaryBuffer(Properties.Resources._1, desc, dev); sBuf[2] = new SecondaryBuffer(Properties.Resources._2, desc, dev); sBuf[3] = new SecondaryBuffer(Properties.Resources._3, desc, dev); sBuf[4] = new SecondaryBuffer(Properties.Resources._4, desc, dev); sBuf[5] = new SecondaryBuffer(Properties.Resources._5, desc, dev); sBuf[6] = new SecondaryBuffer(Properties.Resources._6, desc, dev); sBuf[7] = new SecondaryBuffer(Properties.Resources._7, desc, dev); sBuf[8] = new SecondaryBuffer(Properties.Resources._8, desc, dev); sBuf[9] = new SecondaryBuffer(Properties.Resources._9, desc, dev); sBuf[10] = new SecondaryBuffer(Properties.Resources.SLASH, desc, dev); sBuf[11] = new SecondaryBuffer(Properties.Resources.ASTERISK, desc, dev); sBuf[12] = new SecondaryBuffer(Properties.Resources.NO, desc, dev); sBuf[13] = new SecondaryBuffer(Properties.Resources.PLUS, desc, dev); sBuf[14] = new SecondaryBuffer(Properties.Resources.DOT, desc, dev); } private void keyboardHook_KeyDown(RamGecTools.KeyboardHook.VKeys key) { bool flag = TenKeyToolStripMenuItem.Checked; string keyName = key.ToString(); SecondaryBuffer buf = null; int num = 0; /* テンキーの判定 */ if (flag) { if (keyName.IndexOf("NUMP") >= 0) { num = Int32.Parse(keyName.Substring(6)); } else { switch (keyName) { case "DECIMAL": num = 14; break; case "ADD": num = 13; break; case "SUBTRACT": num = 12; break; case "MULTIPLY": num = 11; break; case "DIVIDE": num = 10; break; default: flag = false; break; } } } /* メインキーの判定 */ if (!flag) { if (MainKeyToolStripMenuItem.Checked) { string[] splitK = keyName.Split('_'); if (splitK[0].Equals("KEY")) { if (Int32.TryParse(splitK[1], out num)) flag = true; } } } /* オーディオ再生 */ if (flag) { buf = sBuf[num]; buf.SetCurrentPosition(0); buf.Play(0, BufferPlayFlags.Default); //buf = null; } } private void MainKeyToolStripMenuItem_Click(object sender, EventArgs e) { MainKeyToolStripMenuItem.Checked = !MainKeyToolStripMenuItem.Checked; } private void TenKeyToolStripMenuItem_Click(object sender, EventArgs e) { TenKeyToolStripMenuItem.Checked = !TenKeyToolStripMenuItem.Checked; } private void CloseToolStripMenuItem_Click(object sender, EventArgs e) { keyboardHook.Uninstall(); sBuf = null; desc.Dispose(); dev.Dispose(); notifyIcon1.Visible = false; Application.Exit(); } }//End of Form1 }
エクセルに小数点以下を含む数値データーをかなりの量を入力することになった。
手書きの数字で入力ミスのリスクが高く、縦横合計みたいなものはないので
あとからチェックサムはできない。
ディスプレイを見ないで、手書きの数字だけ目で追いながらミスタイプは音声で
同時に確認できると作業の効率アップとエラーを減らせると思うのだけど...
と相談を受けたのがきっかけで「数字キーの入力を発声してくれる」みたいな
ツールきっと誰かフリーで公開しているだろうと、さらっと検索した範囲では
なかなか良いものがみつからなかった。
ポイントの情報収集に時間はかからなかったし、
主要部分はコピペコード(プログラミングの勉強にならない)なのでデバグなし。
すぐにコーディングは完了した。
入力作業の効率はかなりアップしたと喜んでもらえた。
手書きの数字で入力ミスのリスクが高く、縦横合計みたいなものはないので
あとからチェックサムはできない。
ディスプレイを見ないで、手書きの数字だけ目で追いながらミスタイプは音声で
同時に確認できると作業の効率アップとエラーを減らせると思うのだけど...
と相談を受けたのがきっかけで「数字キーの入力を発声してくれる」みたいな
ツールきっと誰かフリーで公開しているだろうと、さらっと検索した範囲では
なかなか良いものがみつからなかった。
ポイントの情報収集に時間はかからなかったし、
主要部分はコピペコード(プログラミングの勉強にならない)なのでデバグなし。
すぐにコーディングは完了した。
入力作業の効率はかなりアップしたと喜んでもらえた。
コメントをかく