気楽なソフト工房

プログラミングについていろいろな記事を書いています。



mykonos2008

Author:mykonos2008
システムエンジニアとして働いている30代の会社員です。
仕事や趣味でプログラムを書いている方の役に立つ記事を書いていきたいと思っています。
ご意見、ご感想はこちらまで
If you are an english speaker,Please visit my english blog.

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
WPFではタスクトレイ(システムトレイ)にアイコンを表示させるためのコンポーネントが提供されていません。
でも、ご心配なく。System.Windows.FormsのNotifyIconを使う方法があります。

タスクトレイにアイコンを表示し、一度、WPFウィンドウを閉じても、タスクトレイアイコンを
クリックすることで再表示させるアプリケーションを作ってみました。

まず、WPFアプリケーションのメインウィンドウクラスにSystem.Windows.FormsのNotifyIconのインスタンス変数を宣言します。

    public partial class MainWindow : Window
    {
        private System.Windows.Forms.NotifyIcon _notifyIcon;
///省略

そしてメインウィンドウのコンストラクタでNotifyIconを初期化し、タスクトレイに表示されるようにします。

    public MainWindow()
    {
        InitializeComponent();

        //タスクバーに表示されないようにする
        ShowInTaskbar = false;

        //タスクトレイアイコンを初期化する
        _notifyIcon = new NotifyIcon();
        _notifyIcon.Text = "タスクトレイサンプル";
        _notifyIcon.Icon = new System.Drawing.Icon("app.ico");

         //タスクトレイに表示する
        _notifyIcon.Visible = true;

         //アイコンにコンテキストメニュー「終了」を追加する
         ContextMenuStrip menuStrip = new ContextMenuStrip();

         ToolStripMenuItem exitItem = new ToolStripMenuItem();
         exitItem.Text = "終了";
         menuStrip.Items.Add(exitItem);
         exitItem.Click += new EventHandler(exitItem_Click);

         _notifyIcon.ContextMenuStrip = menuStrip;

         //タスクトレイアイコンのクリックイベントハンドラを登録する
         _notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(_notifyIcon_MouseClick);
    }

NotifyIconのIconに設定するアイコン画像は、プロジェクトに追加し、プロパティを修正して
ビルドアクションを「なし」に、「出力ディレクトリにコピー」を「新しい場合はコピーする」に設定しました。

こうすることでICONファイルがアセンブリに埋め込まれず、ビルド時に、exeファイルと同じディレクトリに
出力されるようになります。そして、System.Drawing.Iconクラスのコンストラクタには、exeファイルからの
相対パスを指定しています。

リソースとして埋め込むことができない(と思います)ので、こうしました。

そして、タスクトレイのアイコンに、コンテキストメニューを設定し、アプリケーションを終了させるための
「終了」メニューを追加しています。

次にウィンドウが閉じられても、アプリケーションが終了しないように、ウィンドウのClosingイベントを処理します。

    //ウィンドウが閉じられる前に発生するイベントのハンドラ
    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        try
        {
            //閉じるのをキャンセルする
            e.Cancel = true;

            //ウィンドウを非可視にする
            Visibility = System.Windows.Visibility.Collapsed;
        }
        catch { }
    }

実際には閉じられる際に、閉じる処理をキャンセルし、ウィンドウを見えなくするようにしています。

そして、NotifyIconがクリックされると、ウィンドウを再表示するようにしています。

    //NotifyIconのクリックイベントのハンドラ
    private void _notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        try
        {
            if (e.Button == MouseButtons.Left)
            {
                //ウィンドウを可視化
                Visibility = System.Windows.Visibility.Visible;
                WindowState = System.Windows.WindowState.Normal;
            }
        }
        catch { }
    }

NotifyIconに設定したコンテキストメニューの終了メニューがクリックされるとアプリケーションを終了させます。

    //終了メニューのイベントハンドラ
    private void exitItem_Click(object sender, EventArgs e)
    {
        try
        {
            _notifyIcon.Dispose();
            System.Windows.Application.Current.Shutdown();
        }
        catch { }
    }

意外と簡単にできました。

それにしても何故、WPFで提供しないのか不思議です。何度もリクエストが挙っているみたいですが、
「WPFはあくまでもプレゼンテーションライブラリなので」という理由で却下されているようです。。。。

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://csfun.blog49.fc2.com/tb.php/93-567607a2

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。