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 件のコメント:
コメントを投稿