【问题标题】:How do I create an "unfocusable" form in C#?如何在 C# 中创建“无法聚焦”的表单?
【发布时间】:2011-05-01 12:53:03
【问题描述】:

我希望在 C# 中创建一个无法接受焦点的表单,即当我单击表单上的按钮时,焦点不会从当前具有焦点的应用程序中窃取。

有关此示例,请参阅 Windows 屏幕键盘。请注意,当您单击按钮时,焦点不会来自您当前使用的应用程序。

如何实现这种行为?

更新:

原来它就像覆盖CreateParams 属性并将WS_EX_NOACTIVATE 添加到扩展窗口样式一样简单。感谢您为我指明正确的方向!

不幸的是,这有一个不受欢迎的副作用,它会干扰表单移动,即您仍然可以在屏幕周围拖放表单,但在拖动时不会显示窗口的边框,因此很难精确定位它。

如果有人知道如何解决这个问题,将不胜感激。

【问题讨论】:

标签: c# .net winforms


【解决方案1】:

禁用鼠标激活:

class NonFocusableForm : Form
{
    protected override void DefWndProc(ref Message m)
    {
        const int WM_MOUSEACTIVATE = 0x21;
        const int MA_NOACTIVATE = 0x0003;

        switch(m.Msg)
        {
            case WM_MOUSEACTIVATE:
                m.Result = (IntPtr)MA_NOACTIVATE;
                return;
        }
        base.DefWndProc(ref m);
    }
}

在不激活的情况下显示表单(在无边界表单的情况下唯一对我有用的方法):

    [DllImport("user32.dll")]
    public static extern bool ShowWindow(IntPtr handle, int flags);

    NativeMethods.ShowWindow(form.Handle, 8);

执行此操作的标准方法(似乎不适用于所有表单样式):

    protected override bool ShowWithoutActivation
    {
        get { return true; }
    }

如果有其他激活表单的方法,可以用类似的方式抑制它们。

【讨论】:

  • 不幸的是,虽然这会阻止表单在单击时聚焦,但它不会阻止最后一个应用程序失去焦点。感谢您为我指出正确的解决方案。
  • @jnm2 检查我对原始问题的编辑 - 你想要 WS_EX_NOACTIVATE 扩展窗口样式。 msdn.microsoft.com/en-us/library/windows/desktop/ff700543
  • 谢谢。事实证明,我需要在表单上的所有按钮上同时使用 SetStyle(ControlStyles.Selectable, false),以便在没有 .NET winform 决定使用 SetFocus 响应 WM_MOUSEDOWN 的情况下单击它们。
【解决方案2】:

这是我使用的“NoFocusForm”:

public class NoFocusForm : Form
{
    /// From MSDN <see cref="https://docs.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles"/>
    /// A top-level window created with this style does not become the 
    /// foreground window when the user clicks it. The system does not 
    /// bring this window to the foreground when the user minimizes or 
    /// closes the foreground window. The window should not be activated 
    /// through programmatic access or via keyboard navigation by accessible 
    /// technology, such as Narrator. To activate the window, use the 
    /// SetActiveWindow or SetForegroundWindow function. The window does not 
    /// appear on the taskbar by default. To force the window to appear on 
    /// the taskbar, use the WS_EX_APPWINDOW style.
    private const int WS_EX_NOACTIVATE = 0x08000000;

    public NoFocusForm()
    { 
        // my other initiate stuff
    }

    /// <summary>
    /// Prevent form from getting focus
    /// </summary>
    protected override CreateParams CreateParams
    {
        get
        {
            var createParams = base.CreateParams;

            createParams.ExStyle |= WS_EX_NOACTIVATE;
            return createParams;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    相关资源
    最近更新 更多