2010-11-04 93 views
2

Hans Passant給了我一個很好的回答here,所以我想請求更多的細節來試圖瞭解Application.Run()的工作方式。VB.Net:瞭解Application.Run()的工作方式

據我所知,從文檔看來,Application.Run()似乎在當前線程上啓動了一個消息循環,這反過來又使它能夠處理用戶輸入(是嗎?)。重載版本Application.Run(Form)基本上是一樣的,只有當表單關閉時才存在,並且默認顯示錶單。

這就提出了幾個問題:

  • 一個人怎麼會做簡單的從Main()子調用可以與用戶(消息框等)進行通信,並等待它退出的功能?
  • 當消息循環在沒有窗體的情況下啓動時,如何從這個循環啓動一個新窗體並等待它退出? ShowDialog可以工作,除非你不想要的形式立即顯示在啓動時
    • 基本上,這種情況將如下(例如,如果你有一個爲發射了最小化到系統托盤。):分`Main`有20mn的任務執行列表,系統托盤圖標告訴用戶程序將在20mn內運行。一個計時器在20mns後打勾,並且必須執行約。每次創建15個任務,每次創建一個進度對話框的實例,最初隱藏在任務欄中。
    • `ShowDialog`會顯示不需要的表單;所以我會這樣做的方式是將進度對話框的回調傳遞給開始下一個任務的函數。但是,在第二個退出之前,這不會退出第一個進度表,是嗎?這意味着15種形式最終會被打開...
    • 因此,解決方案可能是調用(begininvoke?)主應用程序循環上的回調...只是,我不知道該怎麼做,因爲我沒有與循環來調用回調函數相關的形式...

    我希望我的問題是明確的(我可能會迷惑很多事情,對不起),
    謝謝,
    CFP。

    回答

    3

    在窗體上放置一個Timer,ProgressBar和BackgroundWorker。首先你要做的是防止程序啓動時窗體變得可見。將此代碼粘貼到表單類中:

    Protected Overrides Sub SetVisibleCore(ByVal value As Boolean) 
        If Not Me.IsHandleCreated Then 
         value = False 
         Me.CreateHandle 
        End If 
        MyBase.SetVisibleCore(value) 
    End Sub 
    

    使用計時器來啓動作業。設置它的間隔和Enabled屬性,添加Tick事件處理程序:

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick 
        Me.Show() 
        ProgressBar1.Visible = True 
        Me.Enabled = False 
        BackgroundWorker1.RunWorkerAsync() 
    End Sub 
    

    這使得表格可見,當作業開始並啓動後臺工作。該BGW的WorkerReportsProgress屬性設置爲True,並添加3事件處理程序:

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
        '' Do stuff here, call BackgroundWorker1.ReportProgress to update the PB 
    End Sub 
    
    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged 
        ProgressBar1.Value = e.ProgressPercentage 
    End Sub 
    
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted 
        ProgressBar1.Visible = False 
        Me.Enabled = True 
        Me.Hide() 
    End Sub 
    

    它是由您填寫的DoWork的事件處理程序代碼。讓它做15個工作,一定要調用BackgroundWorker1.ReportProgess,以便進度條得到更新。這是ProgressChanged事件處理程序的功能。 RunWorkerCompleted事件處理程序再次隱藏窗體。

    您可以在NotifyIcon的上下文菜單項事件中調用Show()方法,以便用戶可以使表單再次可見。在允許用戶退出應用程序的上下文菜單項中調用Application.Exit()。確保在BGW運行時禁用該功能。或者實施一種乾淨地停止工作的方式。

    +0

    漢斯,你絕對搖滾=)感謝您的詳細和完整的答案。榮譽給你:) – 2010-11-04 21:43:07