Сделайте форму, не настраиваемую на С#
Я хочу написать виртуальную клавиатуру, такую как окна на экранной клавиатуре для сенсорного экрана.
Но у меня проблема с моей виртуальной клавиатурой, крадущей фокус из используемого приложения. Окна на экранной клавиатуре фокусируются на текущем приложении, даже когда пользователь нажимает на него. Есть ли способ сделать то же самое с окнами в С#?
Единственное, что я могу сделать сейчас, - отправить событие клавиатуры в конкретное приложение, например блокнот в следующем коде. Если бы я мог сделать форму неактивной, я мог бы получить текущее сфокусированное окно с помощью 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");
}
Есть ли способ сделать это? Любые предложения лучшего способа иметь форму отправки событий клавиатуры в используемое приложение?
Спасибо!!
Ответы
Ответ 1
Вместо того, чтобы пытаться reset открыть активное окно после того, как ваш клик был нажат, я скорее попытаюсь запретить вашему окну получать фокус/быть активированным.
Посмотрите в этой статье. В конце автор кратко объясняет, как это можно сделать:
Как я могу предотвратить, чтобы мое окно не получало активацию и фокус при показе?
В Windows Forms 2.0 появилось новое свойство ShowWithoutActivation - что вам нужно переопределить в форме. В собственных приложениях вы можете использовать SetWindowPos с SWP_NOACTIVATE или ShowWindow с флагом SW_SHOWNA.
Кроме того, в в этой статье он предоставляет пример кода для Windows Forms:
Если вы хотите использовать полную форму, теперь вы можете переопределить свойство, называемое ShowWithoutActivation
:
public class NoActivateForm : Form {
protected override bool ShowWithoutActivation {
get {
return true;
}
}
}
Помните, что это не "предотвращает" активацию все время - вы можете все еще активируются, вызывая методы Activate()
, Focus()
... и т.д. Если вы хотите запретить кликам на клиентской области активировать окна, вы можете обрабатывать сообщение WM_MOUSEACTIVATE
.
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
Решено!
Я пробовал решение от 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;
}
}