Windows触控板单击
我正在尝试以编程方式启用/禁用该选项:
设置 → 蓝牙与设备 → 触控板 → 轻触 → “用单指轻触实现单击”
当通过Windows设置手动切换时,效果是即时的。
然而,当我在以下注册表键下进行修改时:
HKCU\Software\Microsoft\Windows\CurrentVersion\PrecisionTouchPad
更改只有在执行完整系统重启后才会生效。
我已经尝试过:
- 重启资源管理器(
explorer.exe) - 重启与输入相关的服务(如
hidserv、TabletInputService) - 重新枚举设备(
pnputil /scan-devices) - 重启驱动程序(HID / 触控板)
- 结束并重新打开
SystemSettings.exe
这些方法都不能让更改立即生效。
有没有办法:
- 强制Windows在不重启的情况下重新加载高精度触控板设置,或者
- 通过编程方式模拟切换操作(例如通过API、PowerShell或 UI自动化),使效果立即生效?
(20260414_204100) - 在问题中添加了最小可复现示例。
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace ttpd
{
public partial class Form1 : Form
{
// SystemParametersInfo constants
private const uint SPI_GETTOUCHPADPARAMETERS = 0x00AE;
private const uint SPI_SETTOUCHPADPARAMETERS = 0x00AF;
private const uint SPIF_UPDATEINIFILE = 0x01; // Save config to user .ini
private const uint SPIF_SENDCHANGE = 0x02; // Notify system change
// Stores current Tap to Click state
private bool touchpadClickEnabled;
// UI controls (assumed from designer)
private Label lblStatus;
[StructLayout(LayoutKind.Sequential)]
public struct TOUCHPAD_PARAMETERS_V1
{
public uint versionNumber;
public uint maxSupportedContacts;
public uint legacyTouchpadFeatures;
public uint flags1;
public uint flags2;
public uint sensitivityLevel;
public uint cursorSpeed;
public uint feedbackIntensity;
public uint clickForceSensitivity;
public uint rightClickZoneWidth;
public uint rightClickZoneHeight;
// Access tapEnabled (bit 2 of flags2)
public bool TapEnabled
{
get => ((flags2 >> 2) & 1) == 1;
set
{
if (value)
flags2 |= (1u << 2); // set bit
else
flags2 &= ~(1u << 2); // clear bit (uint safe)
}
}
}
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SystemParametersInfo(
uint uiAction,
uint uiParam,
ref TOUCHPAD_PARAMETERS_V1 pvParam,
uint fWinIni);
public static void ToggleTapToClick(bool enable)
{
TOUCHPAD_PARAMETERS_V1 touchpadParams = new TOUCHPAD_PARAMETERS_V1();
touchpadParams.versionNumber = 1;
// Get current settings
if (SystemParametersInfo(SPI_GETTOUCHPADPARAMETERS, (uint)Marshal.SizeOf(touchpadParams), ref touchpadParams, 0))
{
Console.WriteLine($"Current Tap to Click: {touchpadParams.TapEnabled}");
// Modify tapEnabled
touchpadParams.TapEnabled = enable;
// Apply new settings
if (SystemParametersInfo(SPI_SETTOUCHPADPARAMETERS, (uint)Marshal.SizeOf(touchpadParams), ref touchpadParams, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE))
{
Console.WriteLine($"Tap to Click set to: {enable}");
}
else
{
Console.WriteLine($"Error setting Tap to Click: {Marshal.GetLastWin32Error()}");
}
}
else
{
Console.WriteLine($"Error reading touchpad settings: {Marshal.GetLastWin32Error()}");
}
}
public Form1()
{
InitializeComponent();
UpdateTapToClickStatusAndButton();
}
private void button1_Click(object sender, EventArgs e)
{
ToggleTapToClick(!touchpadClickEnabled);
UpdateTapToClickStatusAndButton();
}
private void UpdateTapToClickStatusAndButton()
{
TOUCHPAD_PARAMETERS_V1 touchpadParams = new TOUCHPAD_PARAMETERS_V1();
touchpadParams.versionNumber = 1;
if (SystemParametersInfo(SPI_GETTOUCHPADPARAMETERS, (uint)Marshal.SizeOf(touchpadParams), ref touchpadParams, 0))
{
touchpadClickEnabled = touchpadParams.TapEnabled;
if (lblStatus != null)
lblStatus.Text = $"Tap to Click: {(touchpadClickEnabled ? "ENABLED" : "DISABLED")}";
if (button1 != null)
button1.Text = touchpadClickEnabled ? "Disable Tap to Click" : "Enable Tap to Click";
}
else
{
if (lblStatus != null)
lblStatus.Text = $"Tap to Click: ERROR ({Marshal.GetLastWin32Error()})";
if (button1 != null)
button1.Text = "Error reading status";
}
}
}
}
解决方案
应用程序通过 WM_SETTINGCHANGE window message 来更新新设置。虽然你也可以自己实现,但有一种官方方法可以完成所有这些,通过 SystemParametersInfo。
你需要以下定义:
[DllImport("user32.dll", SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SystemParametersInfoW(
uint uiAction, uint uiParam, ref TOUCHPAD_PARAMETERS_V1 pvParam, uint fWinIni);
private const uint SPI_GETTOUCHPADPARAMETERS = 0x00AE;
private const uint SPI_SETTOUCHPADPARAMETERS = 0x00AF;
private const uint SPIF_UPDATEINIFILE = 0x01;
private const uint SPIF_SENDCHANGE = 0x02;
[StructLayout(LayoutKind.Sequential)]
private struct TOUCHPAD_PARAMETERS_V1
{
uint versionNumber = 1;
public uint maxSupportedContacts;
public LEGACY_TOUCHPAD_FEATURES legacyTouchpadFeatures;
public TOUCHPAD_FLAGS1 flags1;
public TOUCHPAD_FLAGS2 flags2;
public TOUCHPAD_SENSITIVITY_LEVEL sensitivityLevel;
public uint cursorSpeed;
public uint feedbackIntensity;
public uint clickForceSensitivity;
public uint rightClickZoneWidth;
public uint rightClickZoneHeight;
}
[Flags]
private enum TOUCHPAD_FLAGS1 : uint
{
TouchpadPresent = 1u << 0,
LegacyTouchpadPresent = 1u << 1,
ExternalMousePresent = 1u << 2,
TouchpadEnabled = 1u << 3,
TouchpadActive = 1u << 4,
FeedbackSupported = 1u << 5,
ClickForceSupported = 1u << 6,
}
[Flags]
private enum TOUCHPAD_FLAGS2 : uint
{
AllowActiveWhenMousePresent = 1u << 0,
FeedbackEnabled = 1u << 1,
TapEnabled = 1u << 2,
TapAndDragEnabled = 1u << 3,
TwoFingerTapEnabled = 1u << 4,
RightClickZoneEnabled = 1u << 5,
MouseAccelSettingHonored = 1u << 6,
PanEnabled = 1u << 7,
ZoomEnabled = 1u << 8,
ScrollDirectionReversed = 1u << 9,
}
private enum LEGACY_TOUCHPAD_FEATURES
{
LEGACY_TOUCHPAD_FEATURE_NONE = 0x00000000,
LEGACY_TOUCHPAD_FEATURE_ENABLE_DISABLE = 0x00000001,
LEGACY_TOUCHPAD_FEATURE_REVERSE_SCROLL_DIRECTION = 0x00000004
}
private enum TOUCHPAD_SENSITIVITY_LEVEL
{
TOUCHPAD_SENSITIVITY_LEVEL_MOST_SENSITIVE = 0x00000000,
TOUCHPAD_SENSITIVITY_LEVEL_HIGH_SENSITIVITY = 0x00000001,
TOUCHPAD_SENSITIVITY_LEVEL_MEDIUM_SENSITIVITY = 0x00000002,
TOUCHPAD_SENSITIVITY_LEVEL_LOW_SENSITIVITY = 0x00000003,
TOUCHPAD_SENSITIVITY_LEVEL_LEAST_SENSITIVE = 0x00000004
}
Then get the current params, change the values you want and set back. The function sets the registry (if you use SPIF_UPDATEINIFILE or SPIF_SENDCHANGE) and fire a message (if you use SPIF_SENDCHANGE).
var touchParams = new TOUCHPAD_PARAMETERS_V1();
// get existing params
if (!SystemParametersInfoW(SPI_GETTOUCHPADPARAMETERS, Marshal.SizeOf<TOUCHPAD_PARAMETERS_V1>(), ref touchParams, 0))
throw new Win32Exception(Marshal.GetLastPInvokeError());
touchParams.Flags2 |= TOUCHPAD_FLAGS2.TapEnabled;
// set new params and fire message
if (!SystemParametersInfoW(SPI_SETTOUCHPADPARAMETERS, Marshal.SizeOf<TOUCHPAD_PARAMETERS_V1>(), ref touchParams, SPIF_SENDCHANGE))
throw new Win32Exception(Marshal.GetLastPInvokeError());
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。