やりたい事

  • 起動時にフォームをタスクトレイに収納する。
  • タスクトレイをダブルクリックするとフォームが表示される。
  • 但し、タスクバーには表示されない。
最初、WindowState=Minimizedを使ってやってみたんだけど…ShowInTaskBar=Trueの状態だと、左下に最小化表示されてしまった。
色々触ってみたところ、WindowState+ShowInTaskbarでは、どうしても表示されてしまう為、Hide()を使う必要がある。
ただ、ResizeイベントやDeactivateイベント等で処理をしてしまうと、Show()時に上手く復元されないなど、やはり色々問題あり。
結局はこちらを利用せずに、WndProcを使う方法が一番良さげ。

まずは、FormのWndProcを書き換え。MinimizedをフックしてHide()するように変更。

Const WM_SYSCOMMAND As Integer = &H112
Const SC_MINIMIZE As Integer = &HF020
Protected Overrides Sub WndProc(ByRef aMsg As Message)
    If (aMsg.Msg = WM_SYSCOMMAND) AndAlso (aMsg.WParam.ToInt32() = SC_MINIMIZE) Then
        Me.Hide()
    Else
        MyBase.WndProc(aMsg)
    End If
End Sub
次に、NotifyIcon(=mTaskTray)のダブルクリックでShow()するように

Private Sub mTaskTray_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles mTaskTray.MouseDoubleClick
     Me.Show()
End Sub

ここまでで、それなりに動きはするんだけど。どうしても起動時にフォームが表示されてしまう。起動時もタスクトレイに収納状態にしたかったので…
エントリポイントを変更して、以下のように(但し、VB.NETの場合は「アプリケーションフレームワークを有効にする」のチェックを外さないと変更出来ない。)

Module Program
     _
    Sub Main()
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)

        Dim tForm As New Form1()
        Application.Run()
    End Sub
End Module

Form1を表示して、Show()せずにApplication.Run()を呼んでしまう。
ただ、これだと、FormをCloseしてもアプリケーションが終了しないので。

Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
    Application.Exit()
End Sub

とした。一応、動きはしたんだけど…やりたい事はシンプルなのに気持ち悪いなぁ…。
あと、Form_Loadは初回表示時に呼ばれるので注意。監視等を行う場合は、何かパブリックメソッド作るなりして、Main内で呼ぶ必要あり。

Application.Run()から読んでない場合は、スレッドにバインドされてない為、マルチスレッドプログラミングだと色々問題が出るよう。。一度表示さえしちゃえば、バインドされるので問題ないんだけど。手動でバインドする方法ないのかな。

カテゴリー: 技術情報

1件のコメント

koreyasu · 2011-10-20 09:28

SyntaxHighlightが一部効いてないや…
ProtectedとModuleがダメっぽい

現在コメントは受け付けていません。