views:

189

answers:

6

I have some long processes in my app, so I've created a WAIT PLEASE form and I call on another thread like this:

public void ShowWait()
    {
        continueWait = true;
        ThreadPool.QueueUserWorkItem((x) =>
            {
                using (frmWait espera = new frmWait())
                {
                    espera.ShowInTaskbar = false;
                    espera.Show();
                    while (continueWait)
                        Application.DoEvents();
                    espera.Close();
                }
            });
    }

And to close the form I use:

public void HideWait()
    {
        continueWait = false;
    }

It works fine, but I have a problem, when the wait form is shown, the main form losses the focus and any other application running (Excel, Word, etc) at the same time goes to the top and my app goes to the back of all applications. I tried to use Activate() and Focus() but only the frame on the taskbar activates, but the app remains on the back of all applications.

Any light on this?

Thanks in advance

A: 

I hope I understand your problem correctly. So you want to set the WaitForm always on top? If so, have you set the

espera.TopMost = true;

property?

Simon Linder
Yes I have set the property, the wait form displays correctly, the problem is with the main form.
Argons
A: 

I think you want a modal form, try

espera.ShowDialog();

OTOH i don't really understand what you want so i might be wrong.

dbemerlin
The wait form has the TopMost = true, so ShowDialog() is not necesary
Argons
ShowDialog might be what you want, because when the task is done the main form will then get the focus when the wait form is closed. (I think)
Matt Ellen
I tried to use ShowDialog but the wait form goes to the upper right corner and still the main form is not having the focus.
Argons
+1  A: 

Your code snippet doesn't repro the problem for me. What really matters is what is going on with the main form. What you see happening is not that unusual. When your wait form closes, Windows goes hunting for another window in your app to give the focus to. If it cannot find one, it will pick another window from another process and bring it to the foreground. In effect, your main form will disappear behind that window.

This is guaranteed to happen when your main form is disabled, perhaps you set its Enabled property to false? I imagine it can also happen when your main form is still unresponsive to Windows messages, that part is murky.

Avoid these kind of problems (and the incorrect threading apartment you use for the wait form) by executing the time consuming code on a background thread instead of the UI thread. BackgroundWorker was designed to make that easy.

Hans Passant
A: 

I can't reproduce other apps going to top but, related to Fredrik's suggestion to drop the while loop, this works for me:

AutoResetEvent processing = new AutoResetEvent(false);

private void HideWait()
{
    processing.Set();
}

private void ShowWait()
{           
    ThreadPool.QueueUserWorkItem((x) =>
    {
        using (frmWait espera = new frmWait())
        {
            espera.ShowInTaskbar = false;
            espera.Show();
            processing.WaitOne();
            espera.Close();
        }
    });
}

EDIT:

To avoid the main form losing focus:

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

static readonly int SW_SHOWNOACTIVATE = 4;

AutoResetEvent processing = new AutoResetEvent(false);

private void HideWait()
{
    processing.Set();
}

private void ShowWait()
{
    ThreadPool.QueueUserWorkItem(c =>
    {
        using (frmWait espera = new frmWait())
        {
            espera.ShowInTaskbar = false;
            ShowWindow(espera.Handle, SW_SHOWNOACTIVATE);
            processing.WaitOne();
            }
        });
    }
}
Sorin Comanescu
A: 

Did you try using the overload of Show which accepts an owner window, and pass a null reference to it? I have experienced similar issues in the past which have been solved that way:

espera.Show(null);

There seem to be some difference in the behavior of calling Show() (which is implemented in the type Control and that simply sets Visible = true, which in turn triggers code in the type Form in this case), and calling Show(owner).

Fredrik Mörk