14

タッチスクリーン PC 用の Windows オンスクリーン キーボードのような仮想キーボードを作成したいと考えています。しかし、仮想キーボードが使用中のアプリケーションからフォーカスを奪うという問題があります。Windows のオンスクリーン キーボードは、ユーザーが現在のアプリケーションをクリックしても、現在のアプリケーションにフォーカスを維持します。C# の Windows フォームで同じことを行う方法はありますか?

今のところできることは、次のコードのメモ帳のような特定のアプリケーションにキーボード イベントを送信することだけです。フォームをフォーカス不可にできれば、現在フォーカスされているウィンドウを 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");
}

これを行う方法はありますか?フォームが使用中のアプリケーションにキーボード イベントを送信するためのより良い方法の提案はありますか?

ありがとう!!

4

2 に答える 2

16

その解決!

私はgehhoの解決策を試しましたが、CreateParamsメソッドをオーバーライドする必要もありました:

private const int WS_EX_NOACTIVATE = 0x08000000;
protected override CreateParams CreateParams
{
    get
    {
        var createParams = base.CreateParams;

        createParams.ExStyle |= WS_EX_NOACTIVATE;
        return createParams;
    }
}
于 2010-03-11T19:42:58.067 に答える
9

アクティブなウィンドウがクリックされた後にアクティブなウィンドウをリセットしようとする代わりに、ウィンドウがフォーカスを受けたりアクティブ化されたりするのを防ぎたいと思います。

この記事をご覧ください。最後に、著者はこれを行う方法を簡単に説明します。

ウィンドウが表示されているときにアクティブ化とフォーカスを取得できないようにするにはどうすればよいですか?

Windows Forms 2.0 には、ShowWithoutActivation という新しいプロパティがあります。これは、フォームでオーバーライドする必要があります。ネイティブ アプリケーションでは、SWP_NOACTIVATE フラグを指定して SetWindowPos を使用するか、SW_SHOWNA フラグを指定して ShowWindow を使用できます。

さらに、この記事では、Windows フォームのコード例を提供しています。

完全なフォームが必要な場合は、次のプロパティをオーバーライドできます ShowWithoutActivation

public class NoActivateForm : フォーム
{
    protected override bool ShowWithoutActivation => true;  
}

これは常にアクティブ化を「防止」するわけではないことに注意してください – Activate()Focus()…などのメソッドを呼び出してアクティブ化することはできます。クライアント領域をクリックしてもウィンドウがアクティブにならないようにする場合は、WM_MOUSEACTIVATEメッセージを処理できます。

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

protected override void WndProc(ref Message m)
{
    もし (m.Msg == WM_MOUSEACTIVATE)
    {
         m.Result = (IntPtr)MA_NOACTIVATE;
         戻る;
    }
    base.WndProc(ref m);
}
于 2010-03-11T07:40:54.410 に答える