Make a form not focusable in C#

若如初见. 提交于 2019-11-26 23:21:59

问题


I'm wanting to write a virtual keyboard, like windows onscreen keyboard for touchscreen pcs. But I'm having problem with my virtual keyboard stealing the focus from the application being used. The windows onscreen keyboard mantains the focus on the current application even when the user clicks on it. Is there a way to do the same with windows forms in C#?

The only thing I can do for now is to send a keyboard event to an especific application, like notepad in the following code. If I could make the form not focusable, I could get the current focused window with GetForegroundWindow.

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName,string lpWindowName);


[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

private void button1_Click(object sender, EventArgs e)
{
    IntPtr calculatorHandle = FindWindow("notepad", null);
    SetForegroundWindow(calculatorHandle);
    SendKeys.SendWait("111");
}

Is there a way this can be done? Any suggestions of a better way to have the form sending keyboard events to the application being used?

Thanks!!


回答1:


Instead of trying to reset the active window after your one has been clicked, I would rather try to prevent your window from receiving focus/being activated.

Have a look at this article. At the end, the author briefly explains how this can be done:

How can I prevent my window from getting activation and focus when shown?

In Windows Forms 2.0 there is a new property called ShowWithoutActivation – which you would need to override on the Form. In native applications you can use SetWindowPos with the SWP_NOACTIVATE flag or the ShowWindow with the SW_SHOWNA flag.

Furthermore, in this article he provides a code example for Windows Forms:

If you want a full-on form, you can now override a property called ShowWithoutActivation:

public class NoActivateForm : Form {  
    protected override bool ShowWithoutActivation {  
        get {  
            return true;  
        }  
    }  
}

Keep in mind this does not “prevent” activation all the time – you can still activate by calling the Activate(), Focus()… etc methods. If you want to prevent clicks on the client area from activating the window, you can handle the WM_MOUSEACTIVATE message.

private const int WM_MOUSEACTIVATE = 0x0021, MA_NOACTIVATE = 0x0003;

protected override void WndProc(ref Message m) {
    if (m.Msg == WM_MOUSEACTIVATE) {
         m.Result = (IntPtr)MA_NOACTIVATE;
         return;
    }
    base.WndProc(ref m);
}



回答2:


Its solved!

I've tried the solution from gehho, but I also needed to override the CreateParams method:

private const int WS_EX_NOACTIVATE = 0x08000000;
protected override CreateParams CreateParams
    {
        get
        {
            CreateParams createParams = base.CreateParams;
            createParams.ExStyle |= WS_EX_NOACTIVATE;
            return createParams;
        }
    }


来源:https://stackoverflow.com/questions/2423234/make-a-form-not-focusable-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!