Сделать форму не фокусируемой в C#

Я хочу написать виртуальную клавиатуру, например, экранную клавиатуру Windows для сенсорных ПК. Но у меня проблема с тем, что моя виртуальная клавиатура крадет фокус у используемого приложения. Экранная клавиатура Windows поддерживает фокус на текущем приложении, даже когда пользователь нажимает на него. Есть ли способ сделать то же самое с окнами форм в C#?

Единственное, что я могу сейчас сделать, - это отправить событие клавиатуры в конкретное приложение, например блокнот в следующем коде. Если бы я мог сделать форму не фокусируемой, я мог бы получить текущее сфокусированное окно с помощью 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");
}

Есть ли способ сделать это? Какие-нибудь предложения о лучшем способе использования формы, отправляющей события клавиатуры в используемое приложение?

Спасибо!!

2 ответа

Решение

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

Посмотрите на эту статью. В конце автор кратко объясняет, как это можно сделать:

Как я могу предотвратить активацию и фокусировку моего окна при отображении?

В Windows Forms 2.0 есть новое свойство ShowWithoutActivation, которое вам необходимо переопределить в форме. В нативных приложениях вы можете использовать SetWindowPos с флагом SWP_NOACTIVATE или ShowWindow с флагом SW_SHOWNA.

Кроме того, в этой статье он предоставляет пример кода для Windows Forms:

Если вам нужна полная форма, вы можете переопределить свойство с именем ShowWithoutActivation:

открытый класс NoActivateForm: Form {  
    защищенное переопределение bool ShowWithoutActivation {  
        получить {  
            вернуть истину;  
        }  
    }  
}

Имейте в виду, что это не "предотвращает" активацию все время - вы все равно можете активировать, позвонив Activate(), Focus()... и т. Д. Методы. Если вы хотите, чтобы щелчки в области клиента не активировали окно, вы можете обработать WM_MOUSEACTIVATE сообщение.

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

защищенное переопределение void WndProc(ref Message m) {
    if (m.Msg == WM_MOUSEACTIVATE) {
         m.Result = (IntPtr)MA_NOACTIVATE;
         вернуть;
    }
    base.WndProc(ref m);
}

Это решено!

Я пробовал решение от gehho, но мне также нужно было переопределить метод CreateParams:

private const int WS_EX_NOACTIVATE = 0x08000000;
protected override CreateParams CreateParams
    {
        get
        {
            CreateParams createParams = base.CreateParams;
            createParams.ExStyle |= WS_EX_NOACTIVATE;
            return createParams;
        }
    }
Другие вопросы по тегам