none
當 Form 是隱藏的時候,在程式被 Kill Process 時,如何讓右下角的 NotifyIcon 也跟著消失

    問題

  • Dear All

    如主題所言,有一個程式A,裏面就一個 Form,跟一個 NotifyIcon 控制項。

     

    在程式啟動的時候,我會將 Form 隱藏住,為了判別程式是否在 Run

     

    或通知 User 某些事情,我透過 NotifyIcon 控制項告知 User。

     

    在某個情況下 (比如程式更新或. . .) 我必須將這支程式殺掉。

     

    因此我用另一支程式 B 去執行底下的動作。

     

                  Process[] oProcList = Process.GetProcessesByName("程式 A");
                    foreach (Process oProc in oProcList)
                    {                   
                        IntPtr nhWnd = oProc.MainWindowHandle;
                        oProc.CloseMainWindow();    //當 Form 是可見的時候,此行是 OK 的
                        oProc.Kill();                               //較暴力
                    }

     

    當測試的時候,程式 A 在 Form 是可見時,

     

    oProc.CloseMainWindow();    這個動作會觸發 Form_Closing 的 Event ,

     

    所以 我可以讓 Form 下的 NotifyIcon.Visible = false; 右下角的圖示也就不見了。

     

    但如果 Form 是隱藏時,這一行好像就沒有作用。導致右下角的圖示就殘留了。

     

    我試過,

     

    1. 抓程式 A 的 WindowHandle 然後 SendMessage 給它,但它好像收不到。

    2.Call Win32API 的 ShowWindow(..) 也秀不出來。

     

    請問還有什麼方法可解嗎? 

     

    感謝各位。

     

    2007年4月3日 下午 07:11

解答

所有回覆

  • Hi,小弟一些想法供您參考

    之前有在MSDN看到一些表單關閉事件相關的程式碼,如下

    Code Snippet

    覆寫 WndProc 函式以在表單中截獲 WM_QUERYENDSESSION

    msdn上的範例

    Private Shared WM_QUERYENDSESSION As Integer = &H11
    Private Shared systemShutdown As Boolean = False

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = WM_QUERYENDSESSION Then
            MessageBox.Show("queryendsession: this is a logoff, shutdown, or reboot")
             systemShutdown = True
        End If
        ' If this is WM_QUERYENDSESSION, the closing event should be fired in the base WndProc
        MyBase.WndProc(m)
    End Sub 'WndProc

    Private Sub Form1_Closing(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        If (systemShutdown) Then
        ' reset the variable since they may cancel the shutdown
            systemShutdown = False
            If (DialogResult.Yes = _
                    MessageBox.Show("My application", "Would you care to save
    your work before logging off?", MessageBoxButtons.YesNo)) Then
                    e.Cancel = True
            Else
                    e.Cancel = False
            End If
        End If
    End Sub

     

    是VB的code,你可以搜尋一下C#的部份;小弟的想法是看看這樣是不是能夠攔截到其它地方(例如工作管理員)送來的關閉動作,然後做相關處理,您參考看看。

    2007年4月4日 上午 01:48
  •  

    非常感謝你的意見與建議~~

     

    但不幸的,我在 C# 上測試過了,正如一開始所說,在 Form Hide 的時候,它好像收不到任何訊息,

     

    (除非我的寫法有錯),因此 Override WndProc 的方法似乎不適用。

     

    還是感謝你提供的方法。謝謝

    2007年4月7日 上午 04:00
  • 看的花花的 有一個程式A,裏面就一個 Form,跟一個 NotifyIcon 控制項, 你這三支程式的關係為何?

    1.NotifyIcon 跟 Form 是怎麼關係, NotifyIcon 是不是 Form 裡面的 Control,如果是 Kill Form 就會將 Notifylcon 刪了,我知道會有殘影(bug) 所以再 Form_Closed 的 Event 前刪除.

    2.Form Closed 時 NotifyIcon 是要刪掉或影藏.

    3.如果顯現才能Kill,你就先顯現再Kill掉,因該很快的,這麼快的速度畫面會不會閃一下就有待你去測試

    .

    2007年4月7日 下午 02:36
  •  

    很抱歉,我的寫法讓大家誤解了

     

    其實只有二支程式,並沒有三支~~~

    且嚴格來說的話,就一個程式  A 而己。

    程式 B 可以用工作管理員模擬。

     

    程式的寫法就是一個 WinForm 裏面有一個 NotifyIcon 控制項。

    這支程式的功能是什麼,不是這個問題的重點,所以我略過不寫。

    如果你要更簡化程式碼的話,就兩行。

    一個是 Form.Visible = false;

    一個是 NotifyIcon.Visible = true;

     

    如此一來,程式啟動後,你會看不到程式本身,只會看到一個 Icon 在右下角。

    至於我說的程式 B ,你可以把它想成工作管理員

    直接在工作管理員裏找到程式 A 然後把它『殺掉』,你會發現程式 A 真的不見了。

    但右下角的 Icon 還在。這就是我說的問題,也是尋求幫助的地方。

     

    如果你測試的程式碼,能在工作管理員殺掉它的時候,還收得到 Form Closed 的 Event,

    請指導一下我,關於你的寫法  (必須是 Form.Visible = false 的情況下喔)

     

    謝謝你的意見

    2007年4月7日 下午 02:57
  • 建議您不要用程式 B 來強行結束程式 A,

    取而代之的方法,是讓程式 B 通知程式 A 自行結束,

    這樣就不會有殘留在右下角的 NotifyIcon 存在了。

     

    通知的方式有很多,比方:

     

    1. 直接使用執行緒間的 shared memory 讓程式 B 程式通知 A 程式關閉。

     http://www.codeproject.com/csharp/csthreadmsg.asp

     http://www.codeproject.com/dotnet/globalcache.asp

     

    2. 由程式 B 對某個檔案或 INI 寫入值,再透過程式 A 動態檢查檔案或 INI,

     讀到特定數值時程式 A 自動關閉。

     http://www.codeproject.com/cs/files/aejw_ini_class.asp

     

    3. 使用 TCP,UDP,Remoting 等等方式來讓程式 B 程式通知 A 程式關閉。

     http://www.codeproject.com/csharp/Net_Remoting.asp

    2007年4月10日 上午 07:02