views:

378

answers:

3

Is there a way to keep a window inactive looking, even if it contains focus? I have two forms (A and B). After the user interacts with A, I transfer focus back to B. The result of the focus transfers (the user clicking on the A, then focus being transferred back to B) is that form A blinks from active to inactive. This looks ugly (especially on Vista where A momentarily gets a bigger shadow). How can I make A stay inactive looking so this blinking will not happen?

A: 

You are talking about changing a default behavior of a gui model. I would not advise to do so. If the user is doing something on A then moving back to B shouldn't A disappear? Why is it 'blinking'? It should be a single switch when the focus change happens.

Couldn't tell from what you describe is the focus switching like:

A->B
B->A->user click->B
B->A

?

jim
I am trying to mimic VisualStudio's intellisense. A is the suggestion window and B is where the user types text. After the user clicks A (changing selected suggestion, etc), I automatically set focus back to B so the user can keep typing without having to manually set focus back. The focus transfer is like this: focus is set on B, user clicks on A, on mouse up I set focus back to B. A momentarily gets focus, which results in the blinking (or flicker) of focus, which I want to stop.
Zach Johnson
A: 

Not sure if this helps, but Winforms supports the concept of owned forms. For instance, even though floating toolbars live outside a top-level window, they remain active even when the top-level window is active (and vice versa). Likewise, you want the user to be able to interact with your form A, without deactivating form B.

To achieve this, it sounds like you need to call b.AddOwnedForm(a) just before you show a.

Tim Robinson
I tried your suggestion, but unfortunately, focus switching between the owned and parent window still alternates the appearance of the windows from inactive to active.
Zach Johnson
+1  A: 

At last, I found the answer!

WARNING: DO NOT abuse this answer's technique. Doing so will confuse your users and will be harmful to the computing experience in general. The technique described below can be very useful under certain circumstances (e.g implementing IntelliSense-like behavior), but please be judicious in your usage of it.

The WM_NCACTIVATE message is sent to a window to change the state of its non-client area (i.e. border and titlebar) to inactive or active. The wParam of the message indicates whether the state will be inactive or active. If the wParam is true (a value of 1), the window will look active. If the wParam is false (a value of 0), the window will look inactive. To force a window to stay either inactive or active, override the wParam by setting it to the corresponding value (0 or 1), and you will be all set!

private const int WM_NCACTIVATE = 0x0086;

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_NCACTIVATE)
    {
        // Use this to make it always look inactive:
        m.WParam = (IntPtr)0;

        // Alternately, use this to make it always look active:
        m.WParam = (IntPtr)1;
    }

    base.WndProc(ref m);
}
Zach Johnson