I have an background WinForms application, which doesn't show any windows usually. But it shows a form on top most without activation, when occurred some app event. And I have a problem that when users clicks on the form and after this application closes this form and showes another instance of form, then last one shows without top most option (it shows under all opened windows). And I really don't understand why.
I noticed, that problem disappears when I run application with overloaded method:
Application.Run(new TestForm());
But my application is background and so I need to use follow overloaded method:
Application.Run();
And a problem appears again...
I maximally simplified my code to make my problem more clear. Here is code of my form:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace winscr
{
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
this.Load += Form_Load;
}
void Form_Load(object sender, EventArgs e)
{
//-1 HWND_BOTTOM Places the window at the bottom of the Z order
//0x0010 SWP_NOACTIVATE Does not activate the window.
//0x0002 SWP_NOMOVE Retains the current position (ignores X and Y parameters).
//0x0001 SWP_NOSIZE Retains the current size (ignores the cx and cy parameters).
//always returns true
bool result = SetWindowPos(this.Handle, new IntPtr(-1), 0, 0, 0, 0, 0x0010 | 0x0002 | 0x0001);
this.Text = result + " " + DateTime.Now.ToString();
}
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
protected static extern bool SetWindowPos(
IntPtr hWnd, // window handle
IntPtr hWndInsertAfter, // placement-order handle
int X, // horizontal position
int Y, // vertical position
int cx, // width
int cy, // height
uint uFlags); // window positioning flags
protected override bool ShowWithoutActivation { get { return true; } }
}
}
And code of Program class:
using System;
using System.Windows.Forms;
namespace winscr
{
static partial class Program
{
static TestForm frm;
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//I use timer only for example on stackoverflow. In my real program form appears after particular events
Timer tmr = new System.Windows.Forms.Timer();
tmr.Interval = 2000;
tmr.Tick += new EventHandler(tmr_Tick);
tmr.Enabled = true;
Application.Run();
//Application.Run(new TestForm()); //if I use this overloading, then all works without any bugs
}
static void tmr_Tick(object sender, EventArgs e)
{
if (frm != null)
{
//close previous instance of form
frm.Close();
}
//construct and show new form
frm = new TestForm();
frm.Show();
}
}
}
Here is direct link to the project with this code (you can just run project and try to reproduce problem): http://hidescreener.com/downloads/?r=form_top_most_tests.zip
And I recorded the video, in which I show this problem: http://youtu.be/mxJYZE-oMDI
Please, help me to solve this problem. I have trying to solve it for 2 days.
P.S. I found like problem Really annoying bug with TopMost property in Windows Forms but there is no answer...
Updated: Thanks for the Hans Passant's and King King's comments. It was found that this problem only occurs in Windows XP.