Why Won't My MainForm Focus/Activate?
-
Hi, This is embarassing to ask, but I just can't figure it out. Why is it that when I run my application by double-clicking the .exe from windows explorer, it will load but it will stay behind the windows explorer window? I think the problem lies on the splash screen which I call from the Main Form's constructor. I am calling it here because the splash screen displays the progress of the application start-up ("Initializing components...", "Loading user settings...", etc.) at the bottom of the splash screen. After this closes, I then do a
this.Activate()
orthis.Focus()
in the Main Form's constructor. What is wrong? :-sRafferty
-
Hi, This is embarassing to ask, but I just can't figure it out. Why is it that when I run my application by double-clicking the .exe from windows explorer, it will load but it will stay behind the windows explorer window? I think the problem lies on the splash screen which I call from the Main Form's constructor. I am calling it here because the splash screen displays the progress of the application start-up ("Initializing components...", "Loading user settings...", etc.) at the bottom of the splash screen. After this closes, I then do a
this.Activate()
orthis.Focus()
in the Main Form's constructor. What is wrong? :-sRafferty
Post some more code. How are your loading, showing and closing your splash screen? What does the apps entry point look like? (The "static void Main()" bit in Program.cs. There should be a line that says something like "Application.Run(new YourForm());")
Simon
-
Hi, This is embarassing to ask, but I just can't figure it out. Why is it that when I run my application by double-clicking the .exe from windows explorer, it will load but it will stay behind the windows explorer window? I think the problem lies on the splash screen which I call from the Main Form's constructor. I am calling it here because the splash screen displays the progress of the application start-up ("Initializing components...", "Loading user settings...", etc.) at the bottom of the splash screen. After this closes, I then do a
this.Activate()
orthis.Focus()
in the Main Form's constructor. What is wrong? :-sRafferty
This is going to sound sarcastic but it's not meant to :) Have you tried the BringToFront method for the form?
-
Hi, This is embarassing to ask, but I just can't figure it out. Why is it that when I run my application by double-clicking the .exe from windows explorer, it will load but it will stay behind the windows explorer window? I think the problem lies on the splash screen which I call from the Main Form's constructor. I am calling it here because the splash screen displays the progress of the application start-up ("Initializing components...", "Loading user settings...", etc.) at the bottom of the splash screen. After this closes, I then do a
this.Activate()
orthis.Focus()
in the Main Form's constructor. What is wrong? :-sRafferty
Can you try with this.WindowState = FormWindowState.Normal
Software - Bundle of bugs covered with features.
-
Hi, This is embarassing to ask, but I just can't figure it out. Why is it that when I run my application by double-clicking the .exe from windows explorer, it will load but it will stay behind the windows explorer window? I think the problem lies on the splash screen which I call from the Main Form's constructor. I am calling it here because the splash screen displays the progress of the application start-up ("Initializing components...", "Loading user settings...", etc.) at the bottom of the splash screen. After this closes, I then do a
this.Activate()
orthis.Focus()
in the Main Form's constructor. What is wrong? :-sRafferty
Hi all, Thanks to everyone who replied. I tried calling
this.BringToFront()
in the MainForm's constructor and Load event but it still didn't work. Here are some code: Program.cs/// /// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}MainForm.cs
/// /// Initializes a new instance of the class.
///
public MainForm()
{
Splasher.Show(typeof (ProgressSplashForm));Splasher.Status = "Initializing components...";
InitializeComponent();Splasher.ProgressValue = 80;
ApplicationSession.Instance.PercentHoursBeforeAlert =
Properties.Settings.Default.PercentHoursBeforeAlert;
ApplicationSession.Instance.PercentHoursBeforeHighAlert =
Properties.Settings.Default.PercentHoursBeforeHighAlert;Splasher.ProgressValue = 85;
ApplicationSession.Instance.DbManager = new MsAccessDbManager(Application.StartupPath);
RefreshAvailableFunctions(false);Splasher.Status = "Initialization completed.";
Splasher.ProgressValue = 100;
Splasher.Close();this.BringToFront();
this.Activate();
}/// /// Handles the Load event of the MainForm control.
///
/// The source of the event.
/// The instance containing the event data.
private void MainForm_Load(object sender, EventArgs e)
{
this.BringToFront();
this.Activate();
}I also noticed that the
this.IsHandleCreated
andthis.CanFocus
properties arefalse
in both the constructor and the load event. *Note: The Splasher class is inspired by cncx's article[^] about splash screens. Sufficed to say, theSplasher.Show()
method displays the splash screen by running a new application (Application.Run(_splashForm)
). Any ideas?Rafferty
-
Hi all, Thanks to everyone who replied. I tried calling
this.BringToFront()
in the MainForm's constructor and Load event but it still didn't work. Here are some code: Program.cs/// /// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}MainForm.cs
/// /// Initializes a new instance of the class.
///
public MainForm()
{
Splasher.Show(typeof (ProgressSplashForm));Splasher.Status = "Initializing components...";
InitializeComponent();Splasher.ProgressValue = 80;
ApplicationSession.Instance.PercentHoursBeforeAlert =
Properties.Settings.Default.PercentHoursBeforeAlert;
ApplicationSession.Instance.PercentHoursBeforeHighAlert =
Properties.Settings.Default.PercentHoursBeforeHighAlert;Splasher.ProgressValue = 85;
ApplicationSession.Instance.DbManager = new MsAccessDbManager(Application.StartupPath);
RefreshAvailableFunctions(false);Splasher.Status = "Initialization completed.";
Splasher.ProgressValue = 100;
Splasher.Close();this.BringToFront();
this.Activate();
}/// /// Handles the Load event of the MainForm control.
///
/// The source of the event.
/// The instance containing the event data.
private void MainForm_Load(object sender, EventArgs e)
{
this.BringToFront();
this.Activate();
}I also noticed that the
this.IsHandleCreated
andthis.CanFocus
properties arefalse
in both the constructor and the load event. *Note: The Splasher class is inspired by cncx's article[^] about splash screens. Sufficed to say, theSplasher.Show()
method displays the splash screen by running a new application (Application.Run(_splashForm)
). Any ideas?Rafferty
I forgot, this is the sequence of events: 1. (Window explorer on top) Double-clicks the app.exe file. 2. Splash screen displays on top of windows explorer 3. Splash screen closes 4. Windows explorer activates ?! 5. Main form loads BEHIND the windows explorer, Main form does not activate (the focus is still on windows explorer).
Rafferty
-
Hi all, Thanks to everyone who replied. I tried calling
this.BringToFront()
in the MainForm's constructor and Load event but it still didn't work. Here are some code: Program.cs/// /// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}MainForm.cs
/// /// Initializes a new instance of the class.
///
public MainForm()
{
Splasher.Show(typeof (ProgressSplashForm));Splasher.Status = "Initializing components...";
InitializeComponent();Splasher.ProgressValue = 80;
ApplicationSession.Instance.PercentHoursBeforeAlert =
Properties.Settings.Default.PercentHoursBeforeAlert;
ApplicationSession.Instance.PercentHoursBeforeHighAlert =
Properties.Settings.Default.PercentHoursBeforeHighAlert;Splasher.ProgressValue = 85;
ApplicationSession.Instance.DbManager = new MsAccessDbManager(Application.StartupPath);
RefreshAvailableFunctions(false);Splasher.Status = "Initialization completed.";
Splasher.ProgressValue = 100;
Splasher.Close();this.BringToFront();
this.Activate();
}/// /// Handles the Load event of the MainForm control.
///
/// The source of the event.
/// The instance containing the event data.
private void MainForm_Load(object sender, EventArgs e)
{
this.BringToFront();
this.Activate();
}I also noticed that the
this.IsHandleCreated
andthis.CanFocus
properties arefalse
in both the constructor and the load event. *Note: The Splasher class is inspired by cncx's article[^] about splash screens. Sufficed to say, theSplasher.Show()
method displays the splash screen by running a new application (Application.Run(_splashForm)
). Any ideas?Rafferty
There doesn't seem to be anything unusual in your code. There are some odd bits in that splasher article though. 1) In the close method the code just totally swallows up all exceptions. This is very bad. something maybe going wrong and you won't know about it. Put some code in here to do something. (At the very very least, write to a log file so you know something went wrong. Ideally, Display an error message and shutdown the application) 2) The article uses Application.Run to start a new message pump from inside a separate thread. Seems a bit weird, not sure what impact this will have. .ShowDialog may have been a better way of doing it. This creates a nested message pump. (Maybe there is no difference, I'm not sure about this) 3) It uses reflection to manage the splash screen. Again, bit weird, he knows it's a form, why not just use a form object. Don't think this has any real problems though, it's just a bit of an odd way of doing things. Let me try the Splasher stuff out and I'll get back to you in a bit. [Edit: Yes, I get exactly the same issue with that splasher article code...Hang on...] [Edit 2: Think you just need to abandon this article's method. The problem is something to do with having two message pumps running. When the first closes, the focus returns to the explorer window, even if you ensure the main form is fully loaded and displayed before letting the first message pump stop. I played around with it a bit, but it always causes exactly the same issue. The reason that all those active/bring to front methods don't work is because they all rely on an api call that was changed with windows XP. It was decided that applications should not be allowed to steal focus because it annoys the user if they are working on something else. I would suggest reading this[^] article. It describes a technique of using a ApplicationContext object to load two forms. Ignore all the stuff in there about reading/writing the window state to disk. Just use the appcontext to show your splash screen, do your initialising, show your main form and close your splash screen.]
Simon
modified on Thursday, June 19, 2008 4:56 AM
-
There doesn't seem to be anything unusual in your code. There are some odd bits in that splasher article though. 1) In the close method the code just totally swallows up all exceptions. This is very bad. something maybe going wrong and you won't know about it. Put some code in here to do something. (At the very very least, write to a log file so you know something went wrong. Ideally, Display an error message and shutdown the application) 2) The article uses Application.Run to start a new message pump from inside a separate thread. Seems a bit weird, not sure what impact this will have. .ShowDialog may have been a better way of doing it. This creates a nested message pump. (Maybe there is no difference, I'm not sure about this) 3) It uses reflection to manage the splash screen. Again, bit weird, he knows it's a form, why not just use a form object. Don't think this has any real problems though, it's just a bit of an odd way of doing things. Let me try the Splasher stuff out and I'll get back to you in a bit. [Edit: Yes, I get exactly the same issue with that splasher article code...Hang on...] [Edit 2: Think you just need to abandon this article's method. The problem is something to do with having two message pumps running. When the first closes, the focus returns to the explorer window, even if you ensure the main form is fully loaded and displayed before letting the first message pump stop. I played around with it a bit, but it always causes exactly the same issue. The reason that all those active/bring to front methods don't work is because they all rely on an api call that was changed with windows XP. It was decided that applications should not be allowed to steal focus because it annoys the user if they are working on something else. I would suggest reading this[^] article. It describes a technique of using a ApplicationContext object to load two forms. Ignore all the stuff in there about reading/writing the window state to disk. Just use the appcontext to show your splash screen, do your initialising, show your main form and close your splash screen.]
Simon
modified on Thursday, June 19, 2008 4:56 AM
Hi Simon, Thank you for the effort that you put into this. At least now I know why, I'll really have to fix this, but in the meantime I stopped showing the splash screen altogether :)
Rafferty
-
Hi Simon, Thank you for the effort that you put into this. At least now I know why, I'll really have to fix this, but in the meantime I stopped showing the splash screen altogether :)
Rafferty
No prob. It wasn't entirely selfless. One of our apps uses a similar technique for showing a message pumping splash screen, and has a similar issue. We'd never noticed it before because the app auto runs at start up, fullscreen and on a dedicated PC that is only used via a touch screen (no keyboard/mouse), but at some point we are going to convert it to a desktop user version so things like that will start to cause problems then.
Simon