By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,272 Members | 1,358 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,272 IT Pros & Developers. It's quick & easy.

Windows Forms and Peek-a-boo!

P: n/a
Excetremely annoying problem, I've an application with a long startup time.
So I created another form with my logo in it to as a splash screen.
The splash screen is run from another thread and is communicated solely
through static method and Invoke()'s
However, when I close my second form, the first one (main window) is hiding
under all the windows on the desktop.
If I don't close the splash screen, then everything is fine.

I tried everything, but it's just not working.

//Form1.cs - the main window of my app

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Drawing.Printing;

namespace PrintTest

{

/// <summary>

/// Summary description for Form1.

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null;

private System.Windows.Forms.Button button1;

public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();
}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(96, 56);

this.button1.Name = "button1";

this.button1.Size = new System.Drawing.Size(152, 104);

this.button1.TabIndex = 0;

this.button1.Text = "button1";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 266);

this.Controls.AddRange(new System.Windows.Forms.Control[] {

this.button1});

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Form2.Dispaly();

System.Threading.Thread.Sleep(5000);

Form2.Vanish();

Application.Run(new Form1());

}

private void button1_Click(object sender, System.EventArgs e)

{
}
}

}

// Form2.cs - the splash screen

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;

namespace PrintTest
{
/// <summary>
/// Summary description for Form2.
/// </summary>
public class Form2 : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components;
private static Form2 That;
private static bool Open;
private System.Windows.Forms.Timer Timer1;
public Form2()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
Timer1.Enabled=true;

}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Timer1 = new System.Windows.Forms.Timer(this.components);
//
// Timer1
//
this.Timer1.Tick += new System.EventHandler(this.Timer1_Tick);
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "Form2";
this.Opacity = 0;
this.Text = "Form2";
this.TopMost = true;

}
#endregion

public static void Start()
{
That=new Form2();
//That.Show();//doesn't work
//That.ShowDialog();//works, but hide the main window when exiting
Application.Run(That);//works, but hide the main window when exiting
}

public static void Dispaly()
{
if(Open)
return;
Open=true;
Thread t = new Thread(new ThreadStart(new MethodInvoker(Start)));
t.Start();
}
public static void Vanish()
{
That.Invoke(new MethodInvoker(VanishInvoked));
}
private static void VanishInvoked()
{
Open = false;
That.Timer1.Enabled = true;
}

private void Timer1_Tick(object sender, System.EventArgs e)
{
if(Open)
{
this.Opacity+=0.1;
if(That.Opacity>=100)
Timer1.Enabled=false;
}
else
{
if(this.Opacity>25)
this.Opacity-=0.1;
else
{
this.Close();
That = null;//free resources
}
}
}
}
}

Nov 15 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Hi,

You are messing with visual controls in non UI thread (method Start) which
is usually a very bad thing to do.
IOW that's your main problem.
Plus, I hope that you are aware that the line
System.Threading.Thread.Sleep(5000);
stops your thread for 5 seconds thus your app start time is 5 second longer.

--
Miha Markic - RightHand .NET consulting & software development
miha at rthand com

"Ayende Rahien" <Ay****@no.spam> wrote in message
news:eQ*************@TK2MSFTNGP09.phx.gbl...
Excetremely annoying problem, I've an application with a long startup time. So I created another form with my logo in it to as a splash screen.
The splash screen is run from another thread and is communicated solely
through static method and Invoke()'s
However, when I close my second form, the first one (main window) is hiding under all the windows on the desktop.
If I don't close the splash screen, then everything is fine.

Nov 15 '05 #2

P: n/a
Ayende,

Have you tried to call Dispose on the Form2 instance before you are done
with it?

Also, I think that you should have two application loops (i.e. call the
static Run method on the Application class). One to handle your splash
screen (which would then start the thread), and then when that is done, call
Run again, with your new form.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Ayende Rahien" <Ay****@no.spam> wrote in message
news:eQ*************@TK2MSFTNGP09.phx.gbl...
Excetremely annoying problem, I've an application with a long startup time. So I created another form with my logo in it to as a splash screen.
The splash screen is run from another thread and is communicated solely
through static method and Invoke()'s
However, when I close my second form, the first one (main window) is hiding under all the windows on the desktop.
If I don't close the splash screen, then everything is fine.

I tried everything, but it's just not working.

//Form1.cs - the main window of my app

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Drawing.Printing;

namespace PrintTest

{

/// <summary>

/// Summary description for Form1.

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null;

private System.Windows.Forms.Button button1;

public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();
}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(96, 56);

this.button1.Name = "button1";

this.button1.Size = new System.Drawing.Size(152, 104);

this.button1.TabIndex = 0;

this.button1.Text = "button1";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 266);

this.Controls.AddRange(new System.Windows.Forms.Control[] {

this.button1});

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Form2.Dispaly();

System.Threading.Thread.Sleep(5000);

Form2.Vanish();

Application.Run(new Form1());

}

private void button1_Click(object sender, System.EventArgs e)

{
}
}

}

// Form2.cs - the splash screen

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;

namespace PrintTest
{
/// <summary>
/// Summary description for Form2.
/// </summary>
public class Form2 : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components;
private static Form2 That;
private static bool Open;
private System.Windows.Forms.Timer Timer1;
public Form2()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
Timer1.Enabled=true;

}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Timer1 = new System.Windows.Forms.Timer(this.components);
//
// Timer1
//
this.Timer1.Tick += new System.EventHandler(this.Timer1_Tick);
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "Form2";
this.Opacity = 0;
this.Text = "Form2";
this.TopMost = true;

}
#endregion

public static void Start()
{
That=new Form2();
//That.Show();//doesn't work
//That.ShowDialog();//works, but hide the main window when exiting
Application.Run(That);//works, but hide the main window when exiting
}

public static void Dispaly()
{
if(Open)
return;
Open=true;
Thread t = new Thread(new ThreadStart(new MethodInvoker(Start)));
t.Start();
}
public static void Vanish()
{
That.Invoke(new MethodInvoker(VanishInvoked));
}
private static void VanishInvoked()
{
Open = false;
That.Timer1.Enabled = true;
}

private void Timer1_Tick(object sender, System.EventArgs e)
{
if(Open)
{
this.Opacity+=0.1;
if(That.Opacity>=100)
Timer1.Enabled=false;
}
else
{
if(this.Opacity>25)
this.Opacity-=0.1;
else
{
this.Close();
That = null;//free resources
}
}
}
}
}

Nov 15 '05 #3

P: n/a
I had this same problem, but I was able to find a pretty decent workaround
using the API. I use the following:

The splash form is handed the window handle of the main form just as the
main form completes its startup work (a public property on the splash form
accepts this).

Then, the splash form uses:
GetWindowThreadProcessId
followed by "AttachThreadInput" to hook the window message handlers together
Then is calls "SetActiveWindow", and then uses AttachThreadInput to put the
window message handlers back the way they were.

This has been working fine, and ends up with the main form active.

Jerry
"Ayende Rahien" <Ay****@no.spam> wrote in message
news:eQ*************@TK2MSFTNGP09.phx.gbl...
Excetremely annoying problem, I've an application with a long startup time. So I created another form with my logo in it to as a splash screen.
The splash screen is run from another thread and is communicated solely
through static method and Invoke()'s
However, when I close my second form, the first one (main window) is hiding under all the windows on the desktop.
If I don't close the splash screen, then everything is fine.

I tried everything, but it's just not working.

//Form1.cs - the main window of my app

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using System.Drawing.Printing;

namespace PrintTest

{

/// <summary>

/// Summary description for Form1.

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null;

private System.Windows.Forms.Button button1;

public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeComponent();
}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.button1 = new System.Windows.Forms.Button();

this.SuspendLayout();

//

// button1

//

this.button1.Location = new System.Drawing.Point(96, 56);

this.button1.Name = "button1";

this.button1.Size = new System.Drawing.Size(152, 104);

this.button1.TabIndex = 0;

this.button1.Text = "button1";

this.button1.Click += new System.EventHandler(this.button1_Click);

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

this.ClientSize = new System.Drawing.Size(292, 266);

this.Controls.AddRange(new System.Windows.Forms.Control[] {

this.button1});

this.Name = "Form1";

this.Text = "Form1";

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Form2.Dispaly();

System.Threading.Thread.Sleep(5000);

Form2.Vanish();

Application.Run(new Form1());

}

private void button1_Click(object sender, System.EventArgs e)

{
}
}

}

// Form2.cs - the splash screen

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;

namespace PrintTest
{
/// <summary>
/// Summary description for Form2.
/// </summary>
public class Form2 : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components;
private static Form2 That;
private static bool Open;
private System.Windows.Forms.Timer Timer1;
public Form2()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
Timer1.Enabled=true;

}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Timer1 = new System.Windows.Forms.Timer(this.components);
//
// Timer1
//
this.Timer1.Tick += new System.EventHandler(this.Timer1_Tick);
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "Form2";
this.Opacity = 0;
this.Text = "Form2";
this.TopMost = true;

}
#endregion

public static void Start()
{
That=new Form2();
//That.Show();//doesn't work
//That.ShowDialog();//works, but hide the main window when exiting
Application.Run(That);//works, but hide the main window when exiting
}

public static void Dispaly()
{
if(Open)
return;
Open=true;
Thread t = new Thread(new ThreadStart(new MethodInvoker(Start)));
t.Start();
}
public static void Vanish()
{
That.Invoke(new MethodInvoker(VanishInvoked));
}
private static void VanishInvoked()
{
Open = false;
That.Timer1.Enabled = true;
}

private void Timer1_Tick(object sender, System.EventArgs e)
{
if(Open)
{
this.Opacity+=0.1;
if(That.Opacity>=100)
Timer1.Enabled=false;
}
else
{
if(this.Opacity>25)
this.Opacity-=0.1;
else
{
this.Close();
That = null;//free resources
}
}
}
}
}

Nov 15 '05 #4

P: n/a
"Miha Markic" <miha at rthand com> wrote in message
news:e7**************@TK2MSFTNGP11.phx.gbl...
Hi,

You are messing with visual controls in non UI thread (method Start) which
is usually a very bad thing to do.
IOW that's your main problem.
I fixed it so everything is Invoke()ed, but it doesn't help.
Plus, I hope that you are aware that the line
System.Threading.Thread.Sleep(5000);
stops your thread for 5 seconds thus your app start time is 5 second longer.

Yes, that is a test app to show the problem, I want a reasonable time frame
to show the splash and make it go away.
Miha Markic - RightHand .NET consulting & software development
miha at rthand com

"Ayende Rahien" <Ay****@no.spam> wrote in message
news:eQ*************@TK2MSFTNGP09.phx.gbl...
Excetremely annoying problem, I've an application with a long startup

time.
So I created another form with my logo in it to as a splash screen.
The splash screen is run from another thread and is communicated solely
through static method and Invoke()'s
However, when I close my second form, the first one (main window) is

hiding
under all the windows on the desktop.
If I don't close the splash screen, then everything is fine.


Nov 15 '05 #5

P: n/a
"Jerry Ham" <No*****@Somplace.net> wrote in message
news:Ot**************@TK2MSFTNGP11.phx.gbl...
I had this same problem, but I was able to find a pretty decent workaround
using the API. I use the following:

The splash form is handed the window handle of the main form just as the
main form completes its startup work (a public property on the splash form
accepts this).

Then, the splash form uses:
GetWindowThreadProcessId
followed by "AttachThreadInput" to hook the window message handlers together Then is calls "SetActiveWindow", and then uses AttachThreadInput to put the window message handlers back the way they were.

This has been working fine, and ends up with the main form active.


Thanks a lot!
It now works!!!
Actually, you got me thinking, and then I did a Form1.Activate() after
closing Form2, and it show the main form!
Nov 15 '05 #6

P: n/a
You might be interested in this article:

http://www.codeproject.com/csharp/Pr...lashScreen.asp

Tom Clement
Apptero, Inc.

"Ayende Rahien" <Ay****@no.spam> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
"Jerry Ham" <No*****@Somplace.net> wrote in message
news:Ot**************@TK2MSFTNGP11.phx.gbl...
I had this same problem, but I was able to find a pretty decent workaround using the API. I use the following:

The splash form is handed the window handle of the main form just as the
main form completes its startup work (a public property on the splash form accepts this).

Then, the splash form uses:
GetWindowThreadProcessId
followed by "AttachThreadInput" to hook the window message handlers

together
Then is calls "SetActiveWindow", and then uses AttachThreadInput to put

the
window message handlers back the way they were.

This has been working fine, and ends up with the main form active.


Thanks a lot!
It now works!!!
Actually, you got me thinking, and then I did a Form1.Activate() after
closing Form2, and it show the main form!

Nov 15 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.