Windows11 .net framework 4.7.2のフォームアプリでWebView2を使用するとタッチパネルの場合はControlStyles.Selectableをfalseにしたコントロールにフォーカスが当たってしまう

MTO 20 評価のポイント
2025-10-20T02:57:24.2033333+00:00

次の環境でテスト用プログラムを作成しました。

OS:Windows11(24H2)

開発環境:VisualStudio 2022

言語:C#

アプリ:Windows フォームアプリケーション(.NET Framework)

.net ver.:.net framework4.7.2

画面上にはButton、Label、WebView2のコントロールをそれぞれ1個ずつ配置しました。

WebView2はNuGetしてそこに"https://www.google.com/"を埋め込みました。

Buttonはフォーカスが当たらないようにControlStyles.SelectableをfalseにしてButtonを継承しました。Buttonをクリックするとkeybd_event関数でキーボード押下の情報をOSに送ります。

LabelにはデバッグのためにButtonをクリックしたときのコントロール名を表示しました。

このプログラムを立ち上げるとフォーカスはWebView2に当たり、埋め込んだgoogleの画面の入力フィールドにカーソルが現れます。そこでマウスを使用してButtonをクリックするとgoogleの入力フィールドに対応する文字が現れます。LabelにはWebView2のコントロール名が表示されます。

ところが、タッチパネルでButtonをタップするとカーソルが消えてラベルにButtonのコントロール名が表示されます。ということはButtonはSelectableがfalseであるにもかかわらずフォーカスが当たってしまったということでしょうか。

実はこのプログラムはWindows10(22H2)ではタッチパネルを操作してもマウスと同じ結果でした。Windows10のEOLのためにWindows11にアップグレードしたところ動かなくなってしまったのです。

Windows11の環境でどのようにしたらタッチパネルでもマウスと同じ結果にすることが出来るのでしょうか。どなたかお教え頂けると助かります。

次に90行ほどですがプログラムのソースを添付します。

using Microsoft.Web.WebView2.Core;

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Runtime.InteropServices;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace TestTouchPanel

{

public partial class Form1 : Form

{

    public class win32api

    {

        [DllImport("user32.dll")]

        public static extern uint keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);

        [DllImport("user32.dll")]

        [return: MarshalAs(UnmanagedType.Bool)]

        public static extern bool SetForegroundWindow(IntPtr hWnd);

    }

    public Form1()

    {

        InitializeComponent();

        webView21.CoreWebView2InitializationCompleted += WebView21InitializationCompleted;

        webView21.EnsureCoreWebView2Async(null);

    }

    private void WebView21InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)

    {

        if (e.IsSuccess)

        {

            webView21.CoreWebView2.Settings.IsGeneralAutofillEnabled = false;

            webView21.CoreWebView2.Navigate("https://www.google.com/");

        }

        else

        {

            MessageBox.Show(e.ToString());

        }

    }

    private void notSelectableButton1_Click(object sender, EventArgs e)

    {

        label1.Text = this.ActiveControl.Name;

        input_data(0x31, 0x00, 0x00, 0x00);

    }

    private void input_data(byte pi1, byte pi2, byte pi3, byte pi4)

    {

        win32api.keybd_event(pi1, 0, 0, (UIntPtr)0);

        win32api.keybd_event(pi1, 0, 2/*KEYEVENTF_KEYUP*/, (UIntPtr)0);

        if (pi2 != 0x00)

        {

            win32api.keybd_event(pi2, 0, 0, (UIntPtr)0);

            win32api.keybd_event(pi2, 0, 2/*KEYEVENTF_KEYUP*/, (UIntPtr)0);

        }

        if (pi3 != 0x00)

        {

            win32api.keybd_event(pi3, 0, 0, (UIntPtr)0);

            win32api.keybd_event(pi3, 0, 2/*KEYEVENTF_KEYUP*/, (UIntPtr)0);

        }

        if (pi4 != 0x00)

        {

            win32api.keybd_event(pi4, 0, 0, (UIntPtr)0);

            win32api.keybd_event(pi4, 0, 2/*KEYEVENTF_KEYUP*/, (UIntPtr)0);

        }

    }

    private void Form1_Load(object sender, EventArgs e)

    {

        this.WindowState = FormWindowState.Maximized;

        webView21.Size = new Size(1000, 500);

    }

}

class NotSelectableButton : System.Windows.Forms.Button

{

   public NotSelectableButton()

   {

       this.SetStyle(ControlStyles.Selectable, false);

   }

}

}

開発者テクノロジ | C#
開発者テクノロジ | C#

C 言語ファミリをルーツとし、コンポーネント指向プログラミングのサポートを含む、オブジェクト指向およびタイプセーフのプログラミング言語。


質問作成者が受け入れた回答
Danny Nguyen (WICLOUD CORPORATION) 8,725 評価のポイント Microsoft 外部スタッフ モデレーター
2025-10-30T09:01:11.0666667+00:00

Windows 11 では想定された動作です:タッチ(ポインター)でのタップは、SetStyle(ControlStyles.Selectable, false) を呼び出していても Button にフォーカスを移します。このスタイルはキーボード(Tab/ショートカット)による選択を無効化するだけで、ポインターによるフォーカスはブロックしません。Windows 10 では WebView2 がフォーカスを保持しているように見えましたが、それは偶然で保証された動作ではありません。

Button がフォーカスを取ると、WebView2 はキャレットを失い、合成キーイベント(keybd_event 経由)がページに届かなくなります。

重要なポイント:

  • ControlStyles.Selectable = false はマウスやタッチクリックによるフォーカスを防ぎません。
  • Windows 11 のタッチ入力は、タップされたコントロールにより一貫してフォーカスを移します。
  • keybd_event は非推奨です。WebView2 のスクリプトを使えば完全に回避できます。

推奨解決策(ニーズに合う最も簡単なものを選択):


1. Button のクリックハンドラで WebView2 に再フォーカスしてから入力を送信(最も簡単)

private async void notSelectableButton1_Click(object sender, EventArgs e)
{
    webView21.Focus();  // ページにフォーカス/キャレットを戻す
    // 低レベルのキーイベントではなく文字を直接挿入:
    await webView21.CoreWebView2.ExecuteScriptAsync(
        "document.activeElement && (document.activeElement.value += '1');");
}

(OSレベルのキー入力が本当に必要なら、webView21.Focus() を先に呼び、keybd_event ではなく SendInput を使用してください。)


2. Button の代わりに非フォーカスな代替コントロールを使用

Button を Label や PictureBox に置き換え、ボタン風にスタイル設定(BackColor、BorderStyle、Cursor)。これらのコントロールは通常タッチでフォーカスを取らないため、WebView2 はキャレットを保持します。


3. Button を使い続けるが、すぐにフォーカスを戻す

class NotSelectableButton : Button
{
    protected override void OnGotFocus(EventArgs e)
    {
        base.OnGotFocus(e);
        var web = FindForm()?.Controls
            .OfType<Microsoft.Web.WebView2.WinForms.WebView2>()
            .FirstOrDefault();
        web?.Focus();
    }
}

これにより、Button のアクセシビリティを維持しつつ、タップ後にフォーカスを「保持」しないようにできます。


お役に立てれば幸いです

この回答は役に立ちましたか?

1 人がこの回答が役に立ったと思いました。

0 件の追加の回答

並べ替え方法: 最も役に立つ

お客様の回答

質問作成者は回答に "承認済み"、モデレーターは "推奨" とマークできます。これにより、ユーザーは作成者の問題が回答によって解決したことを把握できます。