WPF应用启动时,检测触摸失效的几种方式

在开发OPS项目,发现插拔式的OPS在切换系统、开关机、重启,会时不时出现部分WPF开机自启的 应用触摸失效的问题。而且出现问题的应用都是全屏窗口应用。用snoop 附加上去,没有Touch 和Stylus的 的相关事件,但是鼠标事件是能触发的,而且系统的其他的应用软件都可以触摸。这就是我们常见的WPF应用的触摸失效的一些案例事件。

以下记录WPF应用启动检测触摸失效的方法

 1、检测系统是否存在触摸设备

  [DllImport("user32.dll")]
  public static extern int GetSystemMetrics(int nIndex);

public static bool DetectSystemTablet() => GetSystemMetrics(94) > 0 || GetSystemMetrics(95) > 0 || GetSystemMetrics(86) > 0;

2、检测WPF 是否加载了触摸设备

 public static bool DetectFrameworkTablet() => Tablet.TabletDevices.Count > 0;

3、检测是否检测到触摸数字化器,输入的触摸设备(需要引用WinRT,nuget包引用:Microsoft.Windows.SDK.Contract)

 private static bool IsTouchEnabledSystem()
 {
     var touchCapabilities = new TouchCapabilities();
     var isTouch = touchCapabilities.TouchPresent > 0;
     return isTouch;
 }

4、是否存在触摸设备尺寸

  public static bool ExistTabletSize()
  {
    bool flag = false;
    foreach (TabletDevice tabletDevice in (IEnumerable) Tablet.TabletDevices)
    {
      PropertyInfo property = tabletDevice.GetType().GetProperty("TabletDeviceImpl", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty);
      object obj = (object) property == null ? (object) tabletDevice : property.GetValue((object) tabletDevice);
      if (obj.GetType().GetProperty("TabletSize", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty)?.GetValue(obj, (object[]) null) is Size size && tabletDevice.StylusDevices.Count > 0 && size.Width > 0)
        flag = true;
      if (flag)
        break;
    }
    return flag;
  }

5、FirstChanceException 监听触笔 异常

 
   AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;

private void CurrentDomain_FirstChanceException(object sender, FirstChanceExceptionEventArgs e)
 {
     AppDomain.CurrentDomain.FirstChanceException -= CurrentDomain_FirstChanceException;
     try
     {
         if (e.Exception.StackTrace.Contains("Penimc.IPimcManager2.GetTablet"))
         {
             //todo
         }
         else if (e.Exception.StackTrace.Contains("Windows.Input.StylusWisp.WispLogic.RegisterStylusDeviceCore"))
         {
             //todo 
         }
     }
     finally
     {
         AppDomain.CurrentDomain.FirstChanceException -= CurrentDomain_FirstChanceException;
         AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
     }
 }

 

由于之前的应用的判断,我们只采用到了1、2的俩种方式组合判断,发现还是会存在触摸失效的。于是在相关的应用上增加了3、4的方法,并增加了日志打印,发现在存在 系统触摸设备,并且WPF应用存在触摸个数的情况下,3、4的返回结果是触摸异常的

 

总结:

由于WPF应用触摸失效的场景非常的多,并且很诡异,目前以上的几种方式只能通过检测异常重启应用的方式去规避的。

 

posted @ 2024-12-24 17:41  wuty007  阅读(203)  评论(2)    收藏  举报