(vb.net)快速的方法,用于winforms的简单飞溅屏幕

发布于 2025-02-08 18:11:25 字数 204 浏览 0 评论 0原文

我的程序花费了约5-10秒的加载,有时使用它的人最终会再次尝试打开它,这引起了问题。我找到了一种快速简便的方法来制作“飞溅屏幕”(从某种意义上说),该方法在执行时立即弹出了一定的时间。我发现Winform Exe加载中的第一阶事件是句柄创建的。答案不是 true splashscreen,而是可以轻松添加到项目中的几行代码,我认为有些人会喜欢它。

My program took ~5-10 seconds to load and sometimes people using it would end up trying to open it again, which caused problems. I found a quick and easy way to make a "splashscreen" (in a sense) that pops up for a set amount of time immediately on execution. I found that the first order of events in a WinForm EXE loading was Handle Created. The answer is not a true splashscreen, but for a couple lines of code that can be easily added to a project, I think some people will like it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

骑趴 2025-02-15 18:11:25

以下代码将在运行EXE时立即显示一个消息框,并在10秒后关闭。

Imports System.Threading

Private Sub Control1_HandleCreated(ByVal sender As Object, ByVal e As EventArgs) Handles Me.HandleCreated
    Dim SplashScreen As New Thread(
        Sub()
            CreateObject("WScript.Shell").Popup("Program Initializing, Please Wait...",10, "Setup Tool")
        End Sub)
    SplashScreen.Start()
End Sub

我使用线程,以使消息框不会冻结代码,并且程序将打开,无论是否按下确定按钮。执行常规MessageBox.Show()将阻止更多代码运行,直到我发现用户单击“确定”为止。

The below code will show a MessageBox immediately on running the EXE and closes after 10 seconds.

Imports System.Threading

Private Sub Control1_HandleCreated(ByVal sender As Object, ByVal e As EventArgs) Handles Me.HandleCreated
    Dim SplashScreen As New Thread(
        Sub()
            CreateObject("WScript.Shell").Popup("Program Initializing, Please Wait...",10, "Setup Tool")
        End Sub)
    SplashScreen.Start()
End Sub

I use Threading so that the MessageBox will not freeze the code and the program will open with or without the OK button being pressed. Doing a regular MessageBox.Show() will prevent any more code from running until the user clicks OK I have found.

预谋 2025-02-15 18:11:25

我发现实现飞溅屏幕的最佳方法是通过消息和/或进度栏或动画轮通知用户。

具有一个启动表单,例如EG Form1,并执行所有乏味的启动过程,这些过程可能会导致任何动画或进度栏图形图形在事件队列中停滞不前。从工具箱中添加一个“背景工人”对象,而在我的情况下,我只是将其命名为BackgroundWorker1。

通常在form1_load事件中启动这些例程之前,请致电背景工作人员。

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        
        CallBackgroundWork()

        StartRoutines() 'this is the heavy lifting routines to get the app working. Set the LoadingStatusflag (declared as a Global Variable"
to various values to tell the splashscreen to display different messages

        Loadingstatus = 10 'triggers splashform to exit
        CancelBackgroundWork()

    End Sub

这些是支持这一点的另一个潜艇,

Sub CallBackgroundWork()

        BackgroundWorker1.WorkerSupportsCancellation = True
        BackgroundWorker1.WorkerReportsProgress = True

        ' call this method to start your asynchronous Task.
        BackgroundWorker1.RunWorkerAsync()

    End Sub

    Sub CancelBackgroundWork()

        ' to cancel the task, just call the BackgroundWorker1.CancelAsync method.

        BackgroundWorker1.CancelAsync()

    End Sub

    Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        '' The asynchronous task we want to perform goes here
        FormSplash.Show()

    End Sub

我的SplashScreen具有一些标签控件和图像框,而FormsPlash_load事件运行了40ms的秒表环,并加载了一系列旋转轮的图像(24张)。在飞溅屏幕活动时,这会保持运行。通过将全局变量加载量设置为在Form1中加载序列的不同部分内的各个值,它可以触发循环例程以显示所示的不同消息示例。在线程之间进行通信的一种简单方法,因为您无法直接访问线程之间的对象,无论form1中的form1中的载荷程序多么密集,而在另一个线程中运行。我使用了秒表循环,因为启动计时器对我不起作用 - 也许以飞溅形式的事件队列问题。

Private Sub FormSplash_Load(sender As Object, e As EventArgs) Handles MyBase.Load


        Me.Show()

        Me.Opacity = 1  'show this form

        'now start a loop that gets ended by other thread through variable Loadingstatus flag
        Dim ggtimer As New Stopwatch, lastvalue As Integer, FProgPosition as integer

        ggtimer.Start()
        lastvalue = ggtimer.ElapsedMilliseconds

nextimage:
        FProgPosition += 1
        If FProgPosition = 24 Then FProgPosition = 1 'has 24 frames in the animated image

        Do  'loop for 40 ms
            If ggtimer.ElapsedMilliseconds - lastvalue > 40 Then
                lastvalue = ggtimer.ElapsedMilliseconds
                Exit Do
            End If
        Loop

        PictureBoxProgress1.Image = FProgIMG(FProgPosition)
        PictureBoxProgress1.Refresh()

        If Loadingstatus = 10 Then GoTo endsplash

        If Loadingstatus = 1 Then

            If CoreTempRunning = False Then
                Me.LabelCoreTemp.Text = "CoreTemp is NOT Running"
                Me.LabelCoreTemp.ForeColor = Color.White
                'insert cross picturebox
                PictureBoxCoreTemp.Image = My.Resources.ResourceManager.GetObject("Cross24x24")
                loaderrorflag2 = True
            Else
                Me.LabelCoreTemp.Text = "CoreTemp is Running"
                Me.LabelCoreTemp.ForeColor = Color.White
                'insert tick picturebox
                PictureBoxCoreTemp.Image = My.Resources.ResourceManager.GetObject("Tick24x24")
                loaderrorflag2 = False
            End If
            Me.PictureBoxCoreTemp.Visible = True
            Me.PictureBoxCoreTemp.Refresh()

            Me.LabelCoreTemp.Left = Me.Width * 2 / 3 - Me.LabelCoreTemp.Width
            Me.LabelCoreTemp.Refresh()


        GoTo nextimage
endsplash:

        ggtimer.Stop()
        Me.Opacity = 0.01
        Me.Hide()

    End Sub

The best way I have found to implement a splash screen which keeps the user informed via messages and/or a progress bar or animated wheel is the following.

Have a startup form eg Form1, and have it carry out all the tedious startup procedures which might cause any animated or progress bar graphic to get stalled in the event queue. Add a "BackgroundWorker" object to Form1 from the Toolbox and in my case I just named it BackgroundWorker1.

Before starting these routines, usually in the Form1_Load event, make a call to the BackgroundWorker.

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        
        CallBackgroundWork()

        StartRoutines() 'this is the heavy lifting routines to get the app working. Set the LoadingStatusflag (declared as a Global Variable"
to various values to tell the splashscreen to display different messages

        Loadingstatus = 10 'triggers splashform to exit
        CancelBackgroundWork()

    End Sub

These are the other subs to support this

Sub CallBackgroundWork()

        BackgroundWorker1.WorkerSupportsCancellation = True
        BackgroundWorker1.WorkerReportsProgress = True

        ' call this method to start your asynchronous Task.
        BackgroundWorker1.RunWorkerAsync()

    End Sub

    Sub CancelBackgroundWork()

        ' to cancel the task, just call the BackgroundWorker1.CancelAsync method.

        BackgroundWorker1.CancelAsync()

    End Sub

    Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        '' The asynchronous task we want to perform goes here
        FormSplash.Show()

    End Sub

My splashscreen has some label controls and pictureboxes and the FormSplash_Load event runs a stopwatch loop of 40ms and loads a series of images (24 in total) of a spinning wheel. This keeps running while the splashscreen is active. By setting the global variable Loadingstatus to various values within different part of the loading sequence in Form1 it can trigger the loop routine to display different messages example shown. An easy way to communicate between threads as you can't directly access objects between threads The wheel keeps spinning no matter how intensive the load routine in Form1 as it is running in another thread. I used a stopwatch loop as starting a timer doesn't work for me - maybe an event queue issue in splash form.

Private Sub FormSplash_Load(sender As Object, e As EventArgs) Handles MyBase.Load


        Me.Show()

        Me.Opacity = 1  'show this form

        'now start a loop that gets ended by other thread through variable Loadingstatus flag
        Dim ggtimer As New Stopwatch, lastvalue As Integer, FProgPosition as integer

        ggtimer.Start()
        lastvalue = ggtimer.ElapsedMilliseconds

nextimage:
        FProgPosition += 1
        If FProgPosition = 24 Then FProgPosition = 1 'has 24 frames in the animated image

        Do  'loop for 40 ms
            If ggtimer.ElapsedMilliseconds - lastvalue > 40 Then
                lastvalue = ggtimer.ElapsedMilliseconds
                Exit Do
            End If
        Loop

        PictureBoxProgress1.Image = FProgIMG(FProgPosition)
        PictureBoxProgress1.Refresh()

        If Loadingstatus = 10 Then GoTo endsplash

        If Loadingstatus = 1 Then

            If CoreTempRunning = False Then
                Me.LabelCoreTemp.Text = "CoreTemp is NOT Running"
                Me.LabelCoreTemp.ForeColor = Color.White
                'insert cross picturebox
                PictureBoxCoreTemp.Image = My.Resources.ResourceManager.GetObject("Cross24x24")
                loaderrorflag2 = True
            Else
                Me.LabelCoreTemp.Text = "CoreTemp is Running"
                Me.LabelCoreTemp.ForeColor = Color.White
                'insert tick picturebox
                PictureBoxCoreTemp.Image = My.Resources.ResourceManager.GetObject("Tick24x24")
                loaderrorflag2 = False
            End If
            Me.PictureBoxCoreTemp.Visible = True
            Me.PictureBoxCoreTemp.Refresh()

            Me.LabelCoreTemp.Left = Me.Width * 2 / 3 - Me.LabelCoreTemp.Width
            Me.LabelCoreTemp.Refresh()


        GoTo nextimage
endsplash:

        ggtimer.Stop()
        Me.Opacity = 0.01
        Me.Hide()

    End Sub
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文