次の方法で共有


WPF アプリケーションでのクリックイベントについて

こんにちは、Visual Studio サポート チームです。

今回は、WPF アプリケーションでのクリック イベントについてご紹介します。

Win32 アプリケーションや WinForms アプリケーションでタッチ イベントを処理する場合、WM_TOUCH メッセージを処理します。
しかし、WPF アプリケーションでは、WPF ランタイム内で独自にタッチ メッセージを処理しているので、WM_TOUCH は無効になっており、独自に TouchDown などのイベントを呼び出しています。
そのため、何か問題が発生したときに、WPF アプリケーションだけタッチできないといったご質問をいただくことがあります。

このような場合には、以下のドキュメントに従い、WPF の独自処理を無効にすることで問題を回避できる場合があります。

  WPF アプリケーションのリアルタイムなスタイラス入力を無効にする
<https://msdn.microsoft.com/ja-jp/library/vstudio/ee230087.aspx>

上記の対応方法を適用した場合には、独自の処理が無効になり、TouchDown のタッチやスタイラスに関するイベントは呼ばれなくなりますが、WM_TOUCH メッセージは有効となります。

このような制限はありますが、アプリケーションの実装次第で問題を解決できる可能性がありますので、ボタンをクリックしても反応しないというような問題が発生した場合には、せひ一度お試しいただくことをお勧めします。

[補足]
リアルタイムなスタイラス入力を無効にするためのサンプル プログラムは既に公開されていますが、有効にする方法についてはありませんでした。
そのため、参考に有効/無効を切り替えるためのサンプル プログラムを以下に公開します。

----------

    private ObservableCollection<TabletDevice> tabletDevicesObservable = new ObservableCollection<TabletDevice>();

    public void UpdateWPFTabletSupport(bool enabled)
    {
// InputManager のタイプの取得
        Type inputManagerType = typeof(System.Windows.Input.InputManager);

        // InputManager.Current インスタンスの StylusLogic メソッドの呼び出し
        object stylusLogic = inputManagerType.InvokeMember("StylusLogic",
                    BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                    null, InputManager.Current, null);

        if (stylusLogic != null) {
            Type stylusLogicType = stylusLogic.GetType();
            if (enabled) {
                // 有効化処理
                while (tabletDevicesObservable.Count > 0) {
                    TabletDevice device = tabletDevicesObservable[0];
                    tabletDevicesObservable.Remove(device);
                    stylusLogicType.InvokeMember("OnTabletAdded",
                            BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
                            null, stylusLogic, new object[] { (uint)device.Id });
                }
            } else {
                // 無効化処理
                TabletDeviceCollection devices = System.Windows.Input.Tablet.TabletDevices;
                while (devices.Count > 0) {
                    TabletDevice device = devices[0];
                    tabletDevicesObservable.Add(device);
                    stylusLogicType.InvokeMember("OnTabletRemoved",
                            BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
                            null, stylusLogic, new object[] { (uint)0 });
                }
           }
        }
    }

----------

アプリケーションの任意のタイミングから、「UpdateWPFTabletSupport(false);」を実行すると、スタイラス / タッチ機能が無効となり、「UpdateWPFTabletSupport(true);」を実行すると有効になります。

なお、無効にしたときの情報を利用して、有効にする処理を実装しているため、無効化・有効化の順番でペアで利用する必要がありますのでご注意ください。
また、UpdateWPFTabletSupport は、スタイラス / タッチ機能を操作するため、スタイラス / タッチのイベント ハンドラから呼び出すと例外が発生する可能性がありますので、こちらもご注意ください。