Сделать форму не фокусируемой в 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;
}
}