2008年1月10日木曜日

C#で常駐アプリ






C#で常駐アプリを作ってみよう。


まずは、フォームデザイナを表示させる。

"ツールボックス"から"NotifyIcon"をドラッグし、フォーム(デフォルトは"Form1")にドロップ。
この時、フォーム上には置かれませんが、それは気にしない。











NotifyIconの名前()、アイコン、テキスト(マウスオーバーした際に表示されるバルーンの内容)を設定。

次に、Form1のイベントプロパティの"FormClosed"をクリックしてメソッドを作成し、
フォームを閉じた時の処理(アイコンを非表示にする)を書く。

/*** Form1.cs ***/
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
  // アイコンを非表示にする
  this.notifyIcon1.Visible = false;
}

次に、Form1が呼び出された時の処理(Form1を非表示にする)を記述する。
"FormClosed"と同様に、"Load"をクリック。

/*** Form1.cs ***/
private void Form1_Load(object sender, EventArgs e)
{
  new Thread(new ThreadStart(HideForm)).Start();
}

private void HideForm()
{
  this.Hide();
}

実行してみる。








"InvalidOperationException"が返ってきた。

色々調べてみると、これはVisual C# 2005から実装されたExceptionのようだ。
スレッドセーフでない実装に対して投げられるらしい。

今回の場合、メインスレッドで生成されたForm1に対して、
メインスレッドから派生した別スレッドからコントロールしようとして、怒られたわけですね。
スレッド間を跨いでますからね。

C#では、別スレッドからコントロールに対して操作を行う場合には、デリゲートを挿まないといけない。
デリゲートを挿むことで操作を"委譲"した形となり、スレッドセーフになる。

と言うわけで、上のソースを改編。

/*** Form1.cs ***/
private void Form1_Load(object sender, EventArgs e)
{
  new Thread(new ThreadStart(HideForm)).Start();
}

private delegate void HideFormDelegate();

private void HideForm()
{
  if (InvokeRequired)
  {
    Invoke(new HideFormDelegate(HideForm));
    return;
  }
  this.Hide();
}

これでOK。

実行すると、タスクトレイにアイコンが生成され、フォーム(Form1)が消える。

ただ、フォームがチラッと一瞬だけ表示される(^^;)
フォームが表示されないようにするには、Form1のプロパティを開いて、以下のように設定する。
"ShowInTaskbar"を"False"に。
"WindowState"を"Minimized"に。
ただし、これだとフォームの右上にある3つのボタンが押せなくなるので、要注意。


参照:
緑のバイク ★ 初めてのC#

0 件のコメント: