【问题标题】:Disable touch visual feedback on windows 8.1 (programmatically) [Desktop App]在 Windows 8.1 上禁用触摸视觉反馈(以编程方式)[桌面应用程序]
【发布时间】:2015-02-17 11:08:30
【问题描述】:

我有一个专门用于 Win8.1 的 C# WPF 应用程序(桌面应用程序,不是 Metro)。

我希望用户能够使用触摸注入,但我正在尝试禁用窗口为点击手势按住并拖动(如在桌面上选择多个文件)和其他手势(缩放滚动等)创建的可视化反馈.

在网上搜索了很长时间后,我发现了这个帖子: How do I disable Windows 8 touch contact visualizations for my application? 所以我试着做同样的事情......

我试过了(会把我的 Win32 课放在最后)

public void DisableGestureVisualization()
{
    const int SPI_SETCONTACTVISUALIZATION = 0x2019;
    const int SPI_SETGESTUREVISUALIZATION = 0x201B;
    ulong gv = 0;
    Logger.Debug(!Win32.SystemParametersInfo(SPI_SETGESTUREVISUALIZATION, 0, ref gv, 0)
        ? @"Failed SystemParametersInfo SPI_SETGESTUREVISUALIZATION"
        : @"Successfuly returned from SystemParametersInfo SPI_SETGESTUREVISUALIZATION");

    Logger.Debug(!Win32.SystemParametersInfo(SPI_SETCONTACTVISUALIZATION, 0, ref gv, 0)
        ? @"Failed SystemParametersInfo SPI_SETCONTACTVISUALIZATION"
        : @"Successfuly returned from SystemParametersInfo SPI_SETCONTACTVISUALIZATION");
}

还有这个:

public void TryDisableWindowsVisualFeedback(IntPtr hWnd)
{
    bool enable = false;
    foreach (Win32.FEEDBACK_TYPE type in Enum.GetValues(typeof(Win32.FEEDBACK_TYPE)))
    {
        if (type == Win32.FEEDBACK_TYPE.FEEDBACK_MAX)
        {
            continue;
        }

        Logger.Debug(!Win32.SetWindowFeedbackSetting(hWnd, type, 0, 4, ref enable) 
               ? @"Failed to SetWindowFeedbackSetting for " + type
               : @"Successfuly returned from SetWindowFeedbackSetting for " + type);
    }
}

我从我的 WPF 应用程序中这样称呼它:

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    Window window = Window.GetWindow(this);
    var wih = new WindowInteropHelper(window);
    IntPtr hWnd = wih.Handle;
    TryDisableWindowsVisualFeedback(hWnd);
}

这是我的辅助 Win32 类:

internal class Win32
{
    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SystemParametersInfo(
        uint uiAction,
        uint uiParam,
        ref ulong pvParam,
        uint fWinIni
        );

    public enum FEEDBACK_TYPE : uint
    {
        FEEDBACK_TOUCH_CONTACTVISUALIZATION = 1,
        FEEDBACK_PEN_BARRELVISUALIZATION = 2,
        FEEDBACK_PEN_TAP = 3,
        FEEDBACK_PEN_DOUBLETAP = 4,
        FEEDBACK_PEN_PRESSANDHOLD = 5,
        FEEDBACK_PEN_RIGHTTAP = 6,
        FEEDBACK_TOUCH_TAP = 7,
        FEEDBACK_TOUCH_DOUBLETAP = 8,
        FEEDBACK_TOUCH_PRESSANDHOLD = 9,
        FEEDBACK_TOUCH_RIGHTTAP = 10,
        FEEDBACK_GESTURE_PRESSANDTAP = 11,
        FEEDBACK_MAX = 0xFFFFFFFF
    }

    [DllImport("user32.dll")]
    public static extern bool SetWindowFeedbackSetting(
        IntPtr hwnd,
        FEEDBACK_TYPE feedback,
        uint dwFlags,
        uint size,
        [In] ref bool configuration
        );

}

以上都没有禁用圆形灰色点击视觉反馈,也没有禁用按住和拖动时出现的白色小圆圈。

我什至尝试使用博客中的 C# 示例:

Windows.UI.Input.PointerVisualizationSettings.
GetForCurrentView().
IsContactFeedbackEnabled = false;

此代码适用于 Metro 应用程序,因此我尝试了 This SO post 并获得了 Windows 命名空间,但在运行代码时我得到了

"An unhandled exception of type 'System.Exception' occurred in MyProg.exe
WinRT information: Element not found.
Additional information: Element not found."

据我所知,桌面应用程序不支持PointerVisualizationSettings,所以这种方式注定要失败......

如果有人能帮我解决这个问题,请帮忙。

谢谢

【问题讨论】:

    标签: c# winapi windows-runtime touch windows-8.1


    【解决方案1】:

    您的 TryDisableWindowsVisualFeedback 方法看起来有错误的 pinvoke 签名,因此您可能正在设置视觉反馈而不是清除它。配置参数是 BOOL* 而不是 bool*,BOOL 是 4 字节整数。您可以使用MarshalAs 属性解决此问题:

    [In , MarshalAs(UnmanagedType.Bool)] ref bool configuration
    

    您可以调用 GetWindowFeedbackSetting 来确认设置是否正确。

    使用正确的 pinvoke 和 hWnd,SetWindowFeedbackSetting 应该可以工作。我确认它在本机应用程序中对我有用。 WPF 处理触摸有点奇怪。我不希望它会影响这一点,但我已经好几年没有深入研究 WPF 了。

    对于您的其他方法,Windows.UI.Input 类被记录为仅在 Windows 应用商店应用程序中工作,因此从桌面应用程序调用它们时会出现错误。在幕后,它们将进行与 SetWindowFeedbackSetting 相同的更改。

    使用 SystemParametersInfo 影响全局 UI 是多余的:您不想通过引起全局问题来解决局部问题。也就是说,如果您触发更改通知,它可能会起作用。不过,使用 SetWindowFeedbackSetting 仅针对您的窗口是一个更好的解决方案。

    【讨论】:

    • 感谢您的评论,我已经用 GetWindowFeedbackSetting 检查了更改,我看到在设置为 false 之前我得到了一个错误的返回值(并且 ref bool 没有改变)并且在调用 SetWindowFeedbackSetting 之后如果为 false,GetWindowFeedbackSetting 会以 false 值输出布尔值...我会尝试您的建议,但我对诚实持怀疑态度。您介意发布您的原生应用吗?
    【解决方案2】:

    我遇到了类似的问题,我可以通过添加删除我的点击手势反馈

    Stylus.IsTapFeedbackEnabled = "False" to my root window.
    

    【讨论】:

      【解决方案3】:

      我不知道这是否会解决 OP 的原始问题(甚至会产生影响),但我可以确认我已为我自己的 Control 成功禁用 all 与触摸相关的视觉反馈-使用以下方法选择性地派生类(几乎就像 OP 建议的那样) - 至少在我的 Windows 10 机器上:

      public class MyTouchControl: Control
      {
          // ...a lot of other touch related stuff going on...
      
          enum FEEDBACK_TYPE
          {
              TOUCH_CONTACTVISUALIZATION = 1,
              PEN_BARRELVISUALIZATION = 2,
              PEN_TAP = 3,
              PEN_DOUBLETAP = 4,
              PEN_PRESSANDHOLD = 5,
              PEN_RIGHTTAP = 6,
              TOUCH_TAP = 7,
              TOUCH_DOUBLETAP = 8,
              TOUCH_PRESSANDHOLD = 9,
              TOUCH_RIGHTTAP = 10,
              GESTURE_PRESSANDTAP = 11
          }
      
          [DllImport("user32.dll")]
          [return: MarshalAs(UnmanagedType.Bool)]
          static extern bool SetWindowFeedbackSetting(IntPtr hWnd, FEEDBACK_TYPE feedback, int dwFlags, int size, ref int config);
      
          void disableAllTouchVisualFeedback()
          {
              int enable = 0;
              foreach (FEEDBACK_TYPE type in Enum.GetValues(typeof(FEEDBACK_TYPE)))
              {
                  SetWindowFeedbackSetting(Handle, type, 0, 4, ref enable);
              }
          }
      
          protected override void OnHandleCreated(EventArgs e)
          {
              disableAllTouchVisualFeedback();
              base.OnHandleCreated(e);
          }
      }
      

      【讨论】:

      • 已经 4 年了 :) 不再从事这个工作,但我希望我的代码能以某种方式帮助你
      • 我几乎预料到了 ;-) 但它确实帮助了我很多。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      相关资源
      最近更新 更多