Сделать форму не фокусируемой в C # - PullRequest
13 голосов
/ 11 марта 2010

Я хочу написать виртуальную клавиатуру, например экранную клавиатуру 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 ]

13 голосов
/ 11 марта 2010

Это решено!

Я пробовал решение от 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;
        }
    }
9 голосов
/ 11 марта 2010

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

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

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

В 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);
}
...