Please have a look at the following code:
var splashForm = new SplashForm();
m_Thread = new Thread( () => System.Windows.Forms.Application.Run( splashForm ) )
m_Thread.Start();
// Do some initialization
// ...
// the following method just invokes `Close()` on the right thread
splashForm.Shutdown();
// Loop until the thread is no longer alive
// ...
System.Windows.Forms.Application.Run( mainForm );
It looks as if all works fine: first I see the splashscreen, later the mainform gets started. But somehow I get strange errors, like: graphical elements (a endless ProgressBar) are not showing up correctly.
EDIT: I have two progressbars, one on the splashscreen, on on the mainform. They both show the same (wrong) behaviour in endlessmode: no progress, just the pure background./EDIT
In my opinion this is due to the call of Application.Run()
on different threads. This errors can be eliminated by calling any function/property of the mainForm before starting the splashscreen - like, for instance
mainForm.Text = mainForm.Text;
Can anyone please confirm that this code can cause problems - or that it should behave alright and I have to look for the error somewhere else?
I already looked for splashscreen implementations and I know that it can be done differently. But I am interested in understanding this implementation and its possible problems. Thanks!
The thread on which your SplashForm displays needs to have a Windows message pump in order to process messages that each window/control produces consumes. To do that you need to make the thread an STA thread. Try calling SetApartmentState
before starting the thread
I would create the form on the thread where the Application.Run()
executes.
SplashForm splashForm = null;
m_Thread = new Thread(delegate { splashForm = new SplashForm(); System.Windows.Forms.Application.Run(splashForm); });
m_Thread.Start();
But what really needs to be done is access it via the InvokeRequired and BeginInvoke technique. Check here.
OMG, I found the answer:Application.EnableVisualStyles();
was called in the ctor if my mainForm (WHY?). It has to be called before any controls are created. Moving it to the static Main()
did the trick. The visual styles are required for endless (ProgressBarStyle.Marquee) progressbars.
Now this splashscreen solution works as it should.
There is nothing principally wrong with what you are doing. I found the approach interesting enough to whip up a demo, and it works fine. I can also say that kek444's answer isn't the problem. Creating the SplahForm on the main thread made no difference.
So I'm guessing it is in the way you control the Progressbar, or more generally how you communicate between the 2 threads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With