2

Hans Passant 在这里给了我一个很好的答案,所以我想询问更多细节以尝试了解其工作方式Application.Run()

据我从文档中了解到,似乎Application.Run()在当前线程上启动了一个消息循环,这反过来又使它能够处理用户输入(对吗?)。重载的版本 Application.Run(Form)基本一样,只是在窗体关闭时存在,并且默认显示窗体。

这就提出了几个问题:

  • 如何简单地从Main()sub 调用一个可以与用户通信的函数(消息框等)并等待它退出?
  • 当消息循环在没有表单的情况下启动时,如何从这个循环中启动一个新表单,并等待它退出?ShowDialog可以工作,除非您不希望表单在启动时立即显示(例如,如果您有一个已启动的 for 最小化到系统托盘)
    • 基本上,情况如下: sub `Main` 有一个要在 20mn 内执行的任务列表,系统托盘图标告诉用户程序将在 20mn 内运行。一个计时器在 20 毫秒后滴答作响,并且必须执行大约。15个任务一个一个,每次创建一个进度对话框的实例,最初隐藏在任务栏中。
    • `ShowDialog` 会显示不需要的表单;所以我这样做的方法是将进度对话框传递给启动下一个任务的函数的回调。但这不会在第二个进度表退出之前退出第一个进度表,对吗?这意味着最终将打开 15 个表格...
    • 所以解决方案可能是在主应用程序循环上调用(begininvoke?)回调......只是,我不知道该怎么做,因为我没有与循环关联的表单来调用回调...

    我希望我的问题很清楚(我可能会混淆很多东西,对不起),
    谢谢,
    CFP。

    4

    1 回答 1

    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
    

    使用计时器开始工作。设置其 Interval 和 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 运行时禁用它。或者实施一种彻底停止工作的方法。

    于 2010-11-04T20:09:43.540 回答