Как мне создать "не сфокусированную" форму в C#?

Я пытаюсь создать форму в C#, которая не может принимать фокус, т.е. когда я нажимаю кнопку на форме, фокус не украден из приложения, которое в данный момент имеет фокус.

См. Пример экранной клавиатуры Windows. Обратите внимание, что при нажатии кнопки фокус не берется из приложения, которое вы используете в данный момент.

Как я могу реализовать это поведение?

Обновить:

Оказывается, это так же просто, как переопределение CreateParams собственность и добавление WS_EX_NOACTIVATE в расширенный стиль окна. Спасибо, что указал мне правильное направление!

К сожалению, это имеет нежелательный побочный эффект, который мешает движению формы, то есть вы все равно можете перетаскивать форму вокруг экрана, но при перетаскивании граница окна не отображается, поэтому ее трудно точно расположить.

Если кто-нибудь знает, как решить эту проблему, это будет оценено.

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; }
    }

Если есть другие способы активации формы, они могут быть подавлены аналогичным образом.

Я использую "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;
        }
    }
}
Другие вопросы по тегам