Splash screen

  • Thread starter Thread starter Juan Ignacio Gelos
  • Start date Start date
J

Juan Ignacio Gelos

Hi,

I'm trying to 'hide' the main form of an application until all the
layout work is done and all the controls have their final sizes and
locations (once the form is displayed you can see the several toolbars,
panels and docking sections being resized, drawn for the first time, etc,
and makes it looks really unprofessional). What I'm looking for is to only
display the form when everything is ready and the form can be displayed
instantaneously, just like when a window is restored after being minimized.
I've tried the following in Main but yields the same result:
MainForm frm = new MainForm();
frm.CreateControl();
frm.PerformLayout();
Application.Run(frm);

I'm guessing I need to go deeper and set some window styles or play with
double buffering, but maybe there's an easier way. Anyone has any pointers
on this or (much better) any sample code?

Thanks in advance,
Juan
 
Hi Tom,

I'm not doing the layout myself (I'm not setting any properties or
calling any methods), rather it's the standard way the controls behave when
shown the first time that bothers me. e.g. I see a panel resizing to fill
where they are docked to Fill, another panel that paints the background a
few seconds after it's shown, etc... looks like the form is being drawn part
by part. I realize this is just ~1.5 secs. but it really doesn't make the
application look solid.
Maybe this is because I'm using the whidbey beta1 version of the
framework, but a way to 'hide' the form should be common to .net 1.1 I
think... or maybe its the other custom controls I'm using (divil.co.uk's),
but none of this should really matter if there's a way to hide the form from
the user while this layout work is being done for the first time...
Apparently these controls (Panel, ToolStrip+RaftinContainer, etc.) only
resize and paint the background once they've been made visible, and I can't
make them do it with Form.PerformLayout() or Form.Refresh(), etc... it's
only the first time the form is made visible that they start resizing +
painting... After that, when I minimize the form and restore it any of this
things happen, as the controls have their sizes already, and neither does
this happen when I resize the form.
What I'm looking for is a way to show the form for the first time
instantaneously, like it was a bitmap... and I'm starting to think for that
I'd need a way to double buffer the entire form... if that's even possible.
BTW, this is the application's main form, so it'd be frm.Show();... or
maybe there is a reason I'd want to use ShowDialog regarding this?

Thanks for your help,
Juan
 
I turns out I *was* actually doing some work setting up a control (the
larger one <g>) in a base form class after InitializeComponent(), and doing
SuspendLayout() ResumeLayout() on my own. It's been a couple of months I
designed that base class and had forgotten about this little method...

I was forced to do this because the control wouldn't work in the windows
form designer. So now I found the workaround to make it work with the
designer, moved the initialization code inside InitializeComponent... added
a couple Application.DoEvents() before doing some heavy work (calling
webservices to load global data, etc), and finally the form looks like it
comes up as a whole the first time its displayed...

In any case, regarding my initial question... it would be nice to have a way
for us to plug into InitializeComponent before it does all those
..ResumeLayout() and .EndInit() 's, or some way of doing a double-buffer on
the entire form (I did try Form.DoubleBuffered but didn't seem to have any
apparent effect). Any pointers on that?

Juan

PS. the Remarks for DoubleBuffered state that (emphasis mine) "Buffered
graphics can reduce or eliminate flicker that is caused by *progressive
redrawing of parts* of a displayed surface. Buffered graphics require that
the updated graphics data is first written to a buffer. The data in the
graphics buffer is then quickly written to displayed surface memory. The
relatively quick switch of the displayed graphics memory typically reduces
the flicker that can otherwise occur."... however it didn't seem to do the
trick for me at Form.... I'm xposting this to the whidbey ngs.
 
The DoubleBuffering does not work completely in Whidbey Beta 1. I beleive
the solution for now is setting SetStyle(ControlStyles.AllPaintingInWmPaint,
true). I believe in Beta 2, the DoubleBuffering property will do this.

Did you acutally get the flickering to stop by putting the code in
InitializeComponent?

--
Tom Krueger

My Blog - http://weblogs.asp.net/tom_krueger
Smart Client DevCenter - http://msdn.microsoft.com/smartclient/
Mobile DevCenter - http://msdn.microsoft.com/mobility

This posting is provided "as is" with no warranties and confers no rights.
 
Hi Tom,

Yes, I had something like this:

... override ... OnLoad(...)
{
Setup();
}

private DocumentContainer docs;
void Setup()
{
this.SuspendLayout();
docs = new DocumentContainer();
docs.Size =
docs.Dock =
docs.Name =
etc. etc. etc.
panelThat.Controls.Add(docs);
this.ResumeLayout();
}

I only moved this into InitializeComponent in the way the designer would
put it (moving each line to the area of the method the designer would put
them), installed the control's assembly into the GAC (which is the
workaround for the divil.co.uk controls to work ok with the whidbey
designer), et voilà. I can really see the difference.
So, this is the equivalent to two things: moving my control creation
code to the constructor *and* moving it to the same block that creates its
parent controls and the rest of the controls that affect its layout before
doing the first layout and displaying them all.

Cheers,
Juan
 
Yes, moving it to the constructor or called from the constructor is was my
first thought. You may have problems seeing it in the designer though. I
forget, but I believe the constructor doesn't get called from the designer
just InitializeComponent. If this is the case and is a problem, I believe
you can work around this by from a base form, because the base forms
constructor gets called.

You know what, this might not be correct. I thought this is how it worked,
however, it just doesn't seem to make sense. I'm going to have to test it,
but I don't have time right now. If you still are having a problem, let me
know and I will look into it further.

Take care,

--
Tom Krueger

My Blog - http://weblogs.asp.net/tom_krueger
Smart Client DevCenter - http://msdn.microsoft.com/smartclient/
Mobile DevCenter - http://msdn.microsoft.com/mobility

This posting is provided "as is" with no warranties and confers no rights.
 
Hi Tom,

Yes, you're correct, the designer only serializes the contents of
InitializeComponent() on the derived form through CodeDom.
In case someone reaches this thread looking for more information, here's
a nice explanation of the designer behavior:
http://blogs.msdn.com/rprabhu/archive/2004/12/12/280823.aspx
As to my initial problem, it's been solved entirely. Thanks for your
help!

Regards,
Juan
 
Back
Top