Bring a window to the top

  • Thread starter Thread starter Sebastien Lange
  • Start date Start date
S

Sebastien Lange

Hi,

Try the code below, and become crazy with me!!! (I have WinXP)
My main window call another process (another window that the user must fill
in) and wait until the process is finished.
I have to deal with thread, otherwise the main window could not be
updated/refreshed.

So when the process is finished, the main window should be activated.
Sometimes it is, sometimes not.
Everyting was working fine, until I set Enabled=false before the call, and
set to true after. (I need it)

So I tried to bring it to the top (not topmost) using SetForegroundWindow
and/or SetWindowPos. If the SetForegroundWindow is called and the main
window was not at foreground, then it highlight the item in the taskbar, but
does not show it!
SetWindowPos with HWND_TOP has not effect!

I even tried Activate()! and it first brings to the top the last window
opened (probably VS.NET in this case), and then yes it brings to the top!
So, that's not good enough.

So I'd like to have the same behavior than without Enabled=false, and then
true.
1) If you close the process (notepad here) and the main window was just
behind, it should be activated, without seing another window appearing (even
1 ms)
2) If the main window was not behind, it should also be activated.
Any idea? Hope I'm clear!

Sebastien


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

namespace WindowsApplication2
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;

public Form1()
{
this.button1 = new System.Windows.Forms.Button();
this.button1.Location = new System.Drawing.Point(10, 10);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(72, 48);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
this.Controls.Add(this.button1);
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
}

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

Process process;
private void button1_Click(object sender, System.EventArgs e)
{
process = Process.Start("notepad.exe");
Thread t = new Thread(new ThreadStart(WaitForExit));
t.IsBackground = true;
t.Name = "WaitForExit";
t.Start();
Enabled = false;
while(t.IsAlive)
{
Thread.Sleep(100);
Application.DoEvents();//Allow the main GUI to be refreshed!!!
}
Enabled = true;
//Activate();
}

private void WaitForExit()
{
while (!process.HasExited)
Thread.Sleep(100);
}
}
}
 
Hi Sebastien,
Thanks for your post!
To my understanding, you want to make your applicaton modal when it calls
another application.
When an application exits, Window manager will activate the next window in
the alt-tab list, but if you disable the window, window manager will remove
it from the alt-tab list, so when the application called in the program
exits, the focus will not change to your program but to the next window in
the alt-tab order list.It's a by design behavior, we can't change it.

It's not easy to implement the modal mechanism from group up. But you may
try this way. Show a modal minimized size(1,1) form after starting the
process and close it when the process exits. Here is an small sample.
<code>
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace WindowsApplication2
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;

public Form1()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(10, 10);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(72, 48);
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(192, 109);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.ResumeLayout(false);

}

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

Process process;
Form2 f;
private void button1_Click(object sender, System.EventArgs e)
{
process = Process.Start("notepad.exe");
Debug.WriteLine(process.Id);
Thread t = new Thread(new ThreadStart(WaitForExit));
t.IsBackground = true;
t.Name = "WaitForExit";
t.Start();
f = new Form2();
//set a proper place to "hide" it :)
f.ShowDialog();
}

private void WaitForExit()
{
while (!process.HasExited)
Thread.Sleep(100);
f.Close();
}
}

public class Form2 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;

public Form2()
{
InitializeComponent();
}

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()
{
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(1, 1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Form2";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Form2";
this.WindowState = System.Windows.Forms.FormWindowState.Minimized;

}
#endregion
}
}
</code>
Does it solve your problem?
If you still have problem on this issue, please be free to reply to this
group to let me know.
Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
You should not reply this mail directly, "Online" should be removed before
sending, Thanks!
 
Thanks a lot, that did the trick.

Sebastien

Ying-Shen Yu said:
Hi Sebastien,
Thanks for your post!
To my understanding, you want to make your applicaton modal when it calls
another application.
When an application exits, Window manager will activate the next window in
the alt-tab list, but if you disable the window, window manager will remove
it from the alt-tab list, so when the application called in the program
exits, the focus will not change to your program but to the next window in
the alt-tab order list.It's a by design behavior, we can't change it.

It's not easy to implement the modal mechanism from group up. But you may
try this way. Show a modal minimized size(1,1) form after starting the
process and close it when the process exits. Here is an small sample.
<code>
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace WindowsApplication2
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;

public Form1()
{
InitializeComponent();
}

private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(10, 10);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(72, 48);
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(192, 109);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.ResumeLayout(false);

}

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

Process process;
Form2 f;
private void button1_Click(object sender, System.EventArgs e)
{
process = Process.Start("notepad.exe");
Debug.WriteLine(process.Id);
Thread t = new Thread(new ThreadStart(WaitForExit));
t.IsBackground = true;
t.Name = "WaitForExit";
t.Start();
f = new Form2();
//set a proper place to "hide" it :)
f.ShowDialog();
}

private void WaitForExit()
{
while (!process.HasExited)
Thread.Sleep(100);
f.Close();
}
}

public class Form2 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;

public Form2()
{
InitializeComponent();
}

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()
{
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(1, 1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Form2";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Form2";
this.WindowState = System.Windows.Forms.FormWindowState.Minimized;

}
#endregion
}
}
</code>
Does it solve your problem?
If you still have problem on this issue, please be free to reply to this
group to let me know.
Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
You should not reply this mail directly, "Online" should be removed before
sending, Thanks!
 
Back
Top