C# によるキーボードのグローバルフック

The Code Project Global Hook

 リリースしたシステムのプログラミングについて、先週の水曜日あたりからずっと悩んでいて、先週は非常に不機嫌でした。自分はVisual Studio 2005のC#で開発しているんですけど、「フォームがアクティブでないとキーボード入力の割り込みを受け付けないのでバックグラウンドでもキーボード入力を拾うようにして欲しい」という顧客からの要望が挙がってきました。ネットで調べて見ると「グローバルフック」とかのキーワードでいろいろ出てくるんですけど、ドットNETだとdllじゃないとだめだとか、参照の設定が面倒で名前空間に見つからないとか、デバッグ時にホスティングプロセスを有効にするチェックを外さなければいけないとか、いろいろあってまともに動くサンプルプログラムが見つかりませんでした。まあへぼプログラマだから仕方ないんですけどね。
 昨日夜半過ぎまでネットで調べていたら“The Code Project”の中で“Global Hook”というキーワードで調べてみたらサンプルプログラムがわんさか出てきました。なんだ最初っからここで調べれば良かったんジャン!と思いつつ、サンプルプログラムをダウンロードして動かしてみたらちゃんと動きました。ちなみに会員登録しないとダウンロード出来ない仕組みになってるし、英語サイトになっています。会員になっててヨカッタァ。
 
ソフトウェア開発の素直研究所です。お仕事のご依頼はこちらからどうぞ!

より高速にサムネイル画像(縮小画像)を作成するには?


クリックで@ITの
「より高速にサムネイル画像(縮小画像)を作成するには?」へ

 栃木県内の某カメラ量販店さんの店舗受付機のカスタマイズのお仕事をさせてもらっていて、以前からなかなか解決できていなかったことがあった。それは「より高速にサムネイル画像(縮小画像)を作成するには?」ということである。しかも今回は、サムネイルだけでなくExif情報内の他の情報(例えば撮影日時など)の情報も取得しなければならないので、それだけ処理に手間が掛かると思っていた。
 ネットで調べて見るとより「高速にサムネイル画像(縮小画像)を作成するには?」と題して、「アットマーク・アイティ」というIT技術系情報サイトで解説をしていた。正に福音だった。
 ポイントとなる点は2点。
 一つはFromStreamメソッドを使うことにより、大きなサイズのファイルでもファイル全体を一度に読み込まないで済むということ
 もう一つは、JPEGファイルのExif情報に格納されているサムネイル画像のデータ(タグ番号は0x501b)をバイト配列のデータとして取り出し、そこからサムネイル画像の画像オブジェクトを作成するということである。
 このことによりDVDやSDメディアに入った膨大な量の画像ファイルも、飛躍的に高速に読み取ってくれるようになった。ちなみに自分のシステムで、1枚当り3~4MBほどある4000×3000の179枚の画像を4.56秒で全て読み込んでサムネイル画像を作成して保存してくれた
 勿論撮影日時の情報を取得したり、Exif情報のないJPEGファイルの場合は、元の画像からサムネイルを作成するなどの工夫をしなければならないのだが、とりあえず店舗受付機から注文してくれるお客さんが、全然ストレスを感じないほどに速くなったことに、お店の方から感謝のメールを頂いたのにはちょっと嬉しかった。こういう仕事をして良かったと思う瞬間である。


実はこれはまだ高速サムネイル処理が未実装の版

ソフトウェア開発の素直研究所です。お仕事のご依頼はこちらからどうぞ!

C#でDataGridViewに配置したチェックボックスの状態取得


 DataGridView のカラムにチェックボックスを入れて、チェックボックスをクリックしたときにリアルタイムにDataGridViewの同一行等に対してスタイルを変更したり、カラムに書き込んだりする方法がやっとわかった。
 要するにDataGridViewのCurrentCellDirtyStateChangedイベントで、チェックボックスを配置しているカラムのイベントを捉えて、コミットさせて、そのカラムの値を判定してチェックボックスの状態を取得すればいいわけねぇ。

private void Form1_Load(object sender, EventArgs e)
{
    string[] strItem = {"Desktop PC", "Note PC", "Tablet" };

    for (int i = 0; i < strItem.Length; i++)
    {
        dataGridView1.Rows.Add();
        dataGridView1["Column2", i].Value = strItem[i];
    }
}

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dataGridView1.CurrentCellAddress.X == 0 && dataGridView1.IsCurrentCellDirty)
    {
        // --- Commit!
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        if (dataGridView1["Column1", dataGridView1.CurrentCellAddress.Y].Value.ToString() == "True")
        {
            for (int i = 0; i < dataGridView1.Columns.Count; i++)
            {
                dataGridView1[i, dataGridView1.CurrentCellAddress.Y].Style.BackColor = Color.Red;
            }
            dataGridView1["Column3", dataGridView1.CurrentCellAddress.Y].Value = "購入";
        }
        else
        {
            for (int i = 0; i < dataGridView1.Columns.Count; i++)
            {
                dataGridView1[i, dataGridView1.CurrentCellAddress.Y].Style.BackColor = Color.White;
            }
            dataGridView1["Column3", dataGridView1.CurrentCellAddress.Y].Value = null;
        }
    }
}

ソフトウェア開発の素直研究所です。お仕事のご依頼はこちらからどうぞ!