Folks,
Please does anyone know how to show a Form from an otherwise invisible application, and have it get the focus (i.e. appear on top of other windows)?
Application.Run
. Why don't you want to use Application.Run
, then?BringToFront()
from OnLoad
or OnShown
?I've hacked this from an application I've been working on. We have a large application that loads a series of modules written by different teams. We have written one of these modules, and needed to have a login dialog open during this initialization. It was set to '.TopMost=true', but that didn't work.
It uses the WindowsFormsSynchronizationContext to open a dialog box, and then get the result of the dialog box back.
I rarely do GUI coding, and suspect this may be overkill, but it might help someone if they get stuck. I had problems with understanding how state is passed to the SendOrPostCallback, as all the examples I could find didn't use it.
Also this is taken from a working application, but I've removed several bits of code, and changed some of the details. Apologies if it doesn't compile.
public bool Dummy()
{
// create the login dialog
DummyDialogForm myDialog = new DummyDialogForm();
// How we show it depends on where we are. We might be in the main thread, or in a background thread
// (There may be better ways of doing this??)
if (SynchronizationContext.Current == null)
{
// We are in the main thread. Just display the dialog
DialogResult result = myDialog.ShowDialog();
return result == DialogResult.OK;
}
else
{
// Get the window handle of the main window of the calling process
IntPtr windowHandle = Process.GetCurrentProcess().MainWindowHandle;
if (windowHandle == IntPtr.Zero)
{
// No window displayed yet
DialogResult result = myDialog.ShowDialog();
return result == DialogResult.OK;
}
else
{
// Parent window exists on separate thread
// We want the dialog box to appear in front of the main window in the calling program
// We would like to be able to do 'myDialog.ShowDialog(windowHandleWrapper)', but that means doing something on the UI thread
object resultState = null;
WindowsFormsSynchronizationContext.Current.Send(
new SendOrPostCallback(delegate(object state) { resultState = myDialog.ShowDialog(); }), resultState);
if (resultState is DialogResult)
{
DialogResult result = (DialogResult) resultState;
return result == DialogResult.OK;
}
else
return false;
}
}
}
It would appear that is behaviour is specific to XP... Hence I can't reproduce it on Vista.
http://www.gamedev.net/community/forums/topic.asp?topic_id=218484
EDIT: PS: It's past my bedtime (2 AM;-).
Thanx all for your responses... there's a "few things" I can try... I might even go into the office tomorrow to try them... Yeah, yeah... I had a life once, but I traded it for a haircut and a job ;-)
Cheers all. Keith.
This did the job perfectly :
formxx.WindowState = FormWindowState.Normal;
formxx.BringToFront();
formxx.Topmost=true;
formxx.Focus();
I got a code in the project.
private static extern bool SetForegroundWindow(
IntPtr hWnd);
public static void ShowToFront(Form form)
{
FormWindowState oldState = form.WindowState;
form.WindowState = FormWindowState.Minimized;
form.Show();
form.Activate();
form.TopLevel = false;
form.TopLevel = true;
form.SelectNextControl(form.ActiveControl, true, true, true, true);
SetForegroundWindow(form.Handle);
form.Focus();
form.WindowState = oldState;
}