如何关闭应用程序、窗口或控件级别的所有触摸输入?

发布于 2024-10-19 04:17:11 字数 332 浏览 5 评论 0原文

使用 c# 开发 wpf 应用程序,如果在 Windows 7 中控制面板中启用了触摸功能,则默认情况下用户可以用手指在 InkCanvas 上“书写”。我想禁用它并仅强制使用手写笔输入。

如果可能的话,我想知道如何以多种方式执行此操作:首先禁用 InkCanvas 上的触摸,其次为特定窗口禁用它,第三为整个应用程序禁用它。第四个好处是知道如何在系统范围内打开或关闭触摸。

我尝试过 UnregisterTouchWindow,并且尝试将 InkCanvas 的 Stylus.SetIsTouchFeedbackEnabled 设置为 false,但都不起作用。

Using c# for a wpf application, if in Windows 7 touch is enabled in the control panel, a user by default can 'write' on an InkCanvas with a finger. I want to disable that and force stylus input only.

I'd like to know how to do it more than one way if possible: first by disabling touch on the InkCanvas, second by disabling it for a particular window, and third by disabling it for the entire application. A bonus fourth would be knowing how to turn touch on or off system-wide.

I have tried UnregisterTouchWindow, and I have tried setting Stylus.SetIsTouchFeedbackEnabled to false for the InkCanvas, but neither has worked.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

转瞬即逝 2024-10-26 04:17:11

进一步的挖掘帮助我将以下内容组合在一起,作为在系统范围内打开/关闭触摸的方法。如果有人知道如何以其他三种方式中的任何一种来完成此任务,我仍然会很感激这些答案。

基本步骤是检查当前注册表状态,必要时进行更改(然后刷新系统以识别更改),并记下初始状态,以便在程序退出时根据需要进行恢复。

感谢两个上的海报 教育链接

public MainWindow(){

    InitializeComponent();

    RegistryKey regKey = Registry.CurrentUser;
    regKey = regKey.OpenSubKey(@"Software\Microsoft\Wisp\Touch", true);
    string currKey = regKey.GetValue("TouchGate").ToString();
    if (currKey == "1")
    {
        regKey.SetValue("TouchGate", 0x00000000);
        User32Utils.Notify_SettingChange();
        UserConfig.TGate = "1";
    }
    regKey.Close();
    ...
}


public static class UserConfig {
    public static string TGate { get; set; }
    ...
}


private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e){
    ...
    if (UserConfig.TGate == "1")
    {
        RegistryKey regKey = Registry.CurrentUser;
        regKey = regKey.OpenSubKey(@"Software\Microsoft\Wisp\Touch", true);
        regKey.SetValue("TouchGate", 0x00000001);
        User32Utils.Notify_SettingChange();
        regKey.Close();
    }
}



//------------------User32Utils.cs
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace (...)
{
    internal class User32Utils
    {
        #region USER32 Options
        static IntPtr HWND_BROADCAST = new IntPtr(0xffffL);
        static IntPtr WM_SETTINGCHANGE = new IntPtr(0x1a);
        #endregion

        #region STRUCT
        enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0000,
            SMTO_BLOCK = 0x0001,
            SMTO_ABORTIFHUNG = 0x2,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
        }
        #endregion

        #region Interop

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern IntPtr SendMessageTimeout(IntPtr hWnd,
                                                uint Msg,
                                                UIntPtr wParam,
                                                UIntPtr lParam,
                                                SendMessageTimeoutFlags fuFlags,
                                                uint uTimeout,
                                                out UIntPtr lpdwResult);
        #endregion

        internal static void Notify_SettingChange()
        {
            UIntPtr result;
            SendMessageTimeout(HWND_BROADCAST, (uint)WM_SETTINGCHANGE,
                               UIntPtr.Zero, UIntPtr.Zero,
                                SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out result);
        }
    }
}

Further digging helped me put together the following as a way to toggle touch on/off system-wide. If anyone knows how to accomplish this in any of the other 3 ways, I'd still appreciate those answers.

The basic steps are to check the current registry status, change it if necessary (and then refresh the system to recognize the change), and make note of the initial state to restore if needed on program exit.

Thanks to the posters at these two links for the education.

public MainWindow(){

    InitializeComponent();

    RegistryKey regKey = Registry.CurrentUser;
    regKey = regKey.OpenSubKey(@"Software\Microsoft\Wisp\Touch", true);
    string currKey = regKey.GetValue("TouchGate").ToString();
    if (currKey == "1")
    {
        regKey.SetValue("TouchGate", 0x00000000);
        User32Utils.Notify_SettingChange();
        UserConfig.TGate = "1";
    }
    regKey.Close();
    ...
}


public static class UserConfig {
    public static string TGate { get; set; }
    ...
}


private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e){
    ...
    if (UserConfig.TGate == "1")
    {
        RegistryKey regKey = Registry.CurrentUser;
        regKey = regKey.OpenSubKey(@"Software\Microsoft\Wisp\Touch", true);
        regKey.SetValue("TouchGate", 0x00000001);
        User32Utils.Notify_SettingChange();
        regKey.Close();
    }
}



//------------------User32Utils.cs
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace (...)
{
    internal class User32Utils
    {
        #region USER32 Options
        static IntPtr HWND_BROADCAST = new IntPtr(0xffffL);
        static IntPtr WM_SETTINGCHANGE = new IntPtr(0x1a);
        #endregion

        #region STRUCT
        enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0000,
            SMTO_BLOCK = 0x0001,
            SMTO_ABORTIFHUNG = 0x2,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
        }
        #endregion

        #region Interop

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern IntPtr SendMessageTimeout(IntPtr hWnd,
                                                uint Msg,
                                                UIntPtr wParam,
                                                UIntPtr lParam,
                                                SendMessageTimeoutFlags fuFlags,
                                                uint uTimeout,
                                                out UIntPtr lpdwResult);
        #endregion

        internal static void Notify_SettingChange()
        {
            UIntPtr result;
            SendMessageTimeout(HWND_BROADCAST, (uint)WM_SETTINGCHANGE,
                               UIntPtr.Zero, UIntPtr.Zero,
                                SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out result);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文