在 Windows 8.1 上禁用触摸视觉反馈(以编程方式)[桌面应用]
本文关键字:方式 编程 应用 桌面 Windows 视觉 触摸 | 更新日期: 2023-09-27 18:34:40
我有一个专门用于Win8.1(桌面应用程序,而不是地铁(的C# WPF应用程序。
我希望用户能够使用触摸注入,但我正在尝试禁用窗口为点击手势按住并拖动(如在桌面上选择多个文件(和其他手势(缩放滚动等(创建的可视化反馈。
在网上搜索了很长时间后,我找到了这篇文章:如何为我的应用程序禁用 Windows 8 触摸接触可视化?所以我试着做同样的事情...
我试过这个(将把我的 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;
这段代码适用于地铁应用程序,所以我尝试了这个 SO 帖子并获得了 Windows 命名空间,但在运行代码时我得到了
"An unhandled exception of type 'System.Exception' occurred in MyProg.exe
WinRT information: Element not found.
Additional information: Element not found."
据我所知,桌面应用程序不支持PointerVisualizationSettings
,因此这种方式注定要失败......
如果有人可以帮助我解决这个问题,请这样做。
谢谢
我遇到了类似的问题,我能够通过添加来删除我的点击手势反馈
Stylus.IsTapFeedbackEnabled = "False" to my root window.
您的 TryDisableWindowsVisualFeedback 方法看起来具有错误的 pinvoke 签名,因此您可能正在设置视觉反馈而不是清除它。配置参数是 BOOL* 而不是 bool*,BOOL 是 4 字节整数。您可以使用 MarshalAs 属性修复此问题:
[In , MarshalAs(UnmanagedType.Bool)] ref bool configuration
您可以调用 GetWindowFeedbackSet 来确认它已正确设置。
使用正确的pinvoke和hWnd,SetWindowFeedbackSet应该可以工作。我确认它在本机应用程序中对我有用。 WPF 处理触摸有点奇怪。我不希望它影响这一点,但我已经好几年没有深入研究 WPF。
对于其他方法,Windows .UI.Input 类被记录为仅在 Windows 应用商店应用中工作,因此从桌面应用调用它们时会出现错误。在封面下,他们将进行与SetWindowFeedbackSetting相同的更改。
使用 SystemParametersInfo 来影响全局 UI 是矫枉过正的:您不想通过导致全局问题来解决本地问题。也就是说,如果您触发更改通知,它可能会起作用。不过,使用SetWindowFeedbackSetup仅针对您的窗口是一个更好的解决方案。
这是否会解决 OP 的原始问题(甚至会有所作为(,但我可以确认我已经使用以下方法(几乎就像 OP 建议的方法(有选择地禁用了我自己的 Control 派生类的所有与触摸相关的视觉反馈 - 至少在我的 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);
}
}