locked
How to prevent a form from being activated/gaining focus. RRS feed

  • Question

  • I'm working on a project where I want to be able to click on a form but not have the form keep focus. Although not what I'm working on at the moment but the Windows On Screen Keyboard is a good example. The OSK when clicked on doesn't take focus, but keeps the focus on the control that had the focus before. It does this but still is able to proccess an onclick event and send the keystroke over to the control that has focus.
    I'm needing to do something similar. I've tried overriding the onActivate method but it seems by then the form has already taken focus.
    Any help is appreciated.

    Saturday, May 13, 2006 8:31 PM

Answers

  • I'm finally starting to make headway on this. I was able to get the form to not be activated when clicking on other windows except for two exceptions. I did this by setting the CreateParams with WS_EX_NOACTIVATE. That works perfectly except when:
    -I create a form and call show() from the form I don't want to be activated.
    -There are other Windows that have the TopMost property set to true.

    I'm mainly concerned with the first one. I have another form that I'm creating from the main form that has some buttons on it. I want this to never loose focus from clicking on the main form.

    I'm getting really close, I can feel it. Can anyone shed some light on this last problem?

    Thanks everyone for the help thus far.
    Wednesday, May 17, 2006 6:42 AM

All replies

  • You might be able to do something like this by overridding the WndProc method in the Form.

    The message you care about is WM_ACTIVATEAPP (0x001C)  The WParam property in the Message is either 0 or 1 indicating deactivation or activation respectively.  The LParam property contains the IntPtr identifier for the thread of the window being deactivated.

    The problem is that I think this occurs at activation and you cannot stop it from activating.  However, you can use the value from LParam to reactivate the original window.  I'm not exactly sure how to do that, but the SetActiveWindow API comes to mind.

    Subclassing using Windows hooks also comes to mind as a possibility.  I hope this gives you enough information at least to find the answer you want.

    Saturday, May 13, 2006 10:18 PM
  • I tried your suggestion with the following code:

            [DllImport("user32.dll")]
            static extern IntPtr SetActiveWindow(IntPtr hWnd);

            protected override void WndProc(ref System.Windows.Forms.Message m)
            {
                if (m.Msg == 0x001C && m.WParam.ToInt32() == 1)
                {
                    SetActiveWindow(m.LParam);
                }
                else
                {
                    base.WndProc(ref m);
                }
            }


    But the window isn't being reactivated. I've stepped through the code and it is getting to the SetActiveWindow call but the other form is never reactivated. Any ideas as to what I might be doing wrong?

    I'm not at all familiar with subclassing using Windows hooks any additional info would be great.

    Is there some way to override the mouse down event?
    Sunday, May 14, 2006 6:33 PM
  • Try this:


    [DllImport("user32.dll")][DllImport("user32.dll")]
    private extern static IntPtr SetActiveWindow(IntPtr handle);
    private const int WM_ACTIVATE = 6;
    private const int WA_INACTIVE = 0;


    protected override void WndProc(ref Message m)
    {
        if(m.Msg == WM_ACTIVATE)
        {
            if(((int)m.WParam & 0xFFFF) != WA_INACTIVE)
            {
                if(m.LParam != IntPtr.Zero)
                {
                    SetActiveWindow(m.LParam);
                }
                else
                {
                    // Could not find sender, just in-activate it.
                    SetActiveWindow( IntPtr.Zero );
                }
            }
        }

        base.WndProc(ref m);
    }

     

    Monday, May 15, 2006 11:43 AM
  • Thank you for the correction on my code. That did indeed work as was intended. The only problem is that it is giving the same affect as when I overrid OnActivate. This does work but I get a flickering on the other form every time I click on my window. It looks as if it is still bringing my window to the front and then immediatly bringing the other one back up in front of mine. This works but I would prefer to not have the flickering. I was reading in another forum about the same type of issue and someone said that the OSK that Windows uses does something with the mouse click events. I'll try and find the quote again.

    Also, PJ. van de Sande, could you please explain how this line works:
    if(((int)m.WParam & 0xFFFF) != WA_INACTIVE)

    I'd like to know how that works.

    Thanks
    Monday, May 15, 2006 9:20 PM
  • I found the forum that had posted a similar question. This was one of the responses:

    http://www.dotnet247.com/247reference/msgs/29/147917.aspx
      wrote:

    Dr Woo,

    I did a quick test and looked at the messages recieved by the OSK with
    Spy++. It looks like it prevents gaining focus by handling
    WM_MOUSEACTIVATE and returning MA_NOACTIVATE. Then it posts
    WM_LBUTTONDOWN and WM_LBUTTONUP messages to itself to simulate that a
    click took place.

    Mattias


    Anyone familiar with what he is talking about?
    Monday, May 15, 2006 11:57 PM
  • You can use the ShowWindow API.It takes a parameter called SW_SHOWNOACTIVATE which will actually show the form/window, but it will not steal focus from the active form.
    Tuesday, May 16, 2006 1:37 PM
  •  Panagiotis Kefalidis wrote:
    You can use the ShowWindow API.It takes a parameter called SW_SHOWNOACTIVATE which will actually show the form/window, but it will not steal focus from the active form.

    That only helps if you are displaying the window, that doesn't prevent the form from being activated when you click on it.
    Tuesday, May 16, 2006 2:27 PM
  •  xbrady wrote:
    Panagiotis Kefalidis wrote:
    You can use the ShowWindow API.It takes a parameter called SW_SHOWNOACTIVATE which will actually show the form/window, but it will not steal focus from the active form.

    That only helps if you are displaying the window, that doesn't prevent the form from being activated when you click on it.

    Oh sorry, i guess i missed the part mention that you don't want to get it activated when you click on it..
    Tuesday, May 16, 2006 5:49 PM
  • I'm finally starting to make headway on this. I was able to get the form to not be activated when clicking on other windows except for two exceptions. I did this by setting the CreateParams with WS_EX_NOACTIVATE. That works perfectly except when:
    -I create a form and call show() from the form I don't want to be activated.
    -There are other Windows that have the TopMost property set to true.

    I'm mainly concerned with the first one. I have another form that I'm creating from the main form that has some buttons on it. I want this to never loose focus from clicking on the main form.

    I'm getting really close, I can feel it. Can anyone shed some light on this last problem?

    Thanks everyone for the help thus far.
    Wednesday, May 17, 2006 6:42 AM
  • Hello,

    Maybe this article can help you:

    Use .NET Forms as Popup Windows
    http://www.vbaccelerator.com/home/NET/Code/Controls/Popup_Windows/Popup_Windows/article.asp

    John.

    Thursday, October 5, 2006 7:15 AM
  • I know this is a somewhat old post but could you provide the code for this?

    Monday, December 29, 2008 3:38 PM
  • Does any one has sample code to instantiate a form that never gets the focus?

    Thanks
    Friday, April 3, 2009 6:10 PM
  • Just instantiate it.  Never show it, and it'll never have focus.  There's no way to completely avoid a form from getting focus other than showing another form in front of it that you can't close.  Why would you want to do that anyways?
    David Morton - http://blog.davemorton.net/
    Friday, April 3, 2009 7:21 PM
  • As original poster indicated, there are cases when you want show a form but never loose focus from the owner form. For example, if you are using tablet PC, you may want to show customized virtual key board to the users. when user selects keys from the virtual key board, it actually doesn't take the focus from the owner form.
    Friday, April 3, 2009 7:51 PM
  • In WPF I use this:


    [

    DllImport("user32.dll")]

     

    public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [

    DllImport("user32.dll")]

     

    public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

     

    private const int GWL_EXSTYLE = -20;

     

    private const int WS_EX_NOACTIVATE = 0x08000000;


     

    protected override void OnActivated(EventArgs e) {

     

    base.OnActivated(e);

     

    //Set the window style to noactivate.

     

    WindowInteropHelper helper = new WindowInteropHelper(this);

    SetWindowLong(helper.Handle, GWL_EXSTYLE,

    GetWindowLong(helper.Handle, GWL_EXSTYLE) | WS_EX_NOACTIVATE);

    }

    Sunday, September 27, 2009 7:18 PM
  • I'm finally starting to make headway on this. I was able to get the form to not be activated when clicking on other windows except for two exceptions. I did this by setting the CreateParams with WS_EX_NOACTIVATE. That works perfectly except when:
    -I create a form and call show() from the form I don't want to be activated.


    I know this is 8 years old.  I apologize for the necro, but I found this on web search trying to find a solution to my own problem.

    I have a similar situation as the OP, and ran into the same thing I quoted above.  I was able to solve this by having a WndProc and handling both the events (not letting the default handler get these):

    WM_ACTIVATE

    WM_NCACTIVATE

    Activate is not enough, you need the NCACTIVATE as well.

    Friday, May 9, 2014 6:29 PM
  • Excellent Brandon, just came across this myself, and while I handled those messages to print debug text to see what's happening, I was accidentally passing them to DefWindowProc().  Returning 0 avoids the auto-activation at app start.


    • Edited by a2B Saturday, February 28, 2015 9:12 AM
    Saturday, February 28, 2015 9:12 AM