了解如何在 Windows 应用 SDK 应用中利用笔式设备提供的触觉反馈,实现更自然、更具触感的交互。
Windows 11引入了数字笔的触觉反馈,让用户感受到其笔与应用的 UI 交互。 提及此功能时,触觉用于开发人员 API 和文档,而 触感是 Windows 设置中向用户显示的名称。
关键 API
- PenDevice
- SimpleHapticsController
- KnownSimpleHapticsControllerWaveforms
- PenDeviceInterop (Windows 应用 SDK)
触觉反馈类型
提供两种类型的触觉反馈:
- 墨迹反馈 — 通过在笔接触屏幕时持续振动,模拟书写或绘图工具(钢笔、记号笔、铅笔、荧光笔)的手感。
- 交互反馈 - 用户操作的短触觉信号,例如将鼠标悬停在按钮上、单击或确认已完成的操作。
检测笔输入
注册 PointerEntered 事件并检查指针设备类型是否为笔:
private void InputObserver_PointerEntered(object sender, PointerRoutedEventArgs e)
{
if (e.Pointer.PointerDeviceType != Microsoft.UI.Input.PointerDeviceType.Pen)
{
return;
}
// Pen detected — check for haptic support.
}
在 Windows 应用 SDK 中获取 PenDevice
在Windows 应用 SDK应用中,使用PenDeviceInteropWindows 应用 SDK互操作类从指针点获取 WinRT PenDevice 对象。
PenDevice、SimpleHapticsController 和 KnownSimpleHapticsControllerWaveforms 是来自 Windows.Devices.Input 和 Windows.Devices.Haptics 命名空间的 WinRT 类型;只有互操作调用本身来自 Windows 应用 SDK 的 Microsoft.UI.Input.Interop 命名空间:
using Microsoft.UI.Input.Interop;
using Windows.Devices.Haptics;
using Windows.Devices.Input;
using Windows.Foundation.Metadata;
private void InputObserver_PointerEntered(object sender, PointerRoutedEventArgs e)
{
if (e.Pointer.PointerDeviceType != Microsoft.UI.Input.PointerDeviceType.Pen)
{
return;
}
var penDevice = PenDeviceInterop.FromPointerPoint(e.GetCurrentPoint(null));
if (penDevice == null)
{
return; // Pen does not support advanced features.
}
// SimpleHapticsController requires Windows 11. Check for API presence
// before accessing it so the app doesn't throw on Windows 10.
if (!ApiInformation.IsPropertyPresent(
"Windows.Devices.Input.PenDevice", "SimpleHapticsController"))
{
return; // Haptic feedback requires Windows 11.
}
var hapticsController = penDevice.SimpleHapticsController;
if (hapticsController == null)
{
return; // Pen does not support haptic feedback.
}
// Configure haptic feedback (see examples below).
}
注释
在 UWP 应用中,请改用 PenDevice.GetFromPointerId 。 该PenDeviceInterop类特定于Windows 应用 SDK。
书写墨迹波形
当笔接触屏幕时,墨迹波形会持续显示。 任何触觉笔都可保证支持所需的波形。
| 波形 | Description | 必选 |
|---|---|---|
| InkContinuous | 默认圆珠笔手感。 不受支持的波形的回退。 | 是的 |
| BrushContinuous | 画笔工具 | 否 |
| PencilContinuous | 铅笔工具 | 否 |
| MarkerContinuous | 标记工具 | 否 |
| ChiselMarkerContinuous | 斜头记号笔/荧光笔 | 否 |
| EraserContinuous | 橡皮擦工具 | 否 |
| GalaxyPenContinuous | 特殊墨迹(多色画笔) | 否 |
交互波形
交互波形为 UI 操作提供简短的直接反馈。
| 波形 | Description | 必选 |
|---|---|---|
| Click | 默认短按。 不受支持的交互的回退。 | 是的 |
| Error | 操作失败或发生错误 | 否 |
| 悬停 | 开始将鼠标悬停在交互式元素上 | 否 |
| 请按 | 按下交互式元素 | 否 |
| 发布 | 释放了交互式元素 | 否 |
| 成功 | 操作成功 | 否 |
| BuzzContinuous | 持续蜂鸣声 | 否 |
| RumbleContinuous | 持续轰鸣 | 否 |
发送触觉反馈
遍历 SupportedFeedback 以查找所需波形,然后调用 SendHapticFeedback:
SimpleHapticsControllerFeedback currentWaveform = null;
// Try to use BrushContinuous, fall back to InkContinuous.
foreach (var waveform in hapticsController.SupportedFeedback)
{
if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.BrushContinuous)
{
currentWaveform = waveform;
break;
}
}
if (currentWaveform == null)
{
foreach (var waveform in hapticsController.SupportedFeedback)
{
if (waveform.Waveform == KnownSimpleHapticsControllerWaveforms.InkContinuous)
{
currentWaveform = waveform;
break;
}
}
}
if (currentWaveform != null)
{
hapticsController.SendHapticFeedback(currentWaveform);
}
停止触觉反馈
当指针退出元素时,始终停止触觉反馈。 在同一元素上为 PointerExited 注册:
private void Canvas_PointerExited(object sender, PointerRoutedEventArgs e)
{
hapticsController?.StopFeedback();
}
注释
当笔离开屏幕时,某些手写笔会自动停止触觉反馈。 但是,并非所有笔都会这样做,因此请务必显式地调用 StopFeedback。
自定义触觉反馈
某些笔支持其他自定义。 使用前请先确认是否支持:
| 资产 | 使用以下项检查是否支持 |
|---|---|
| 强度 | IsIntensitySupported |
| 播放次数 | IsPlayCountSupported |
| 播放持续时间 | IsPlayDurationSupported |
| 重播暂停间隔 | IsReplayPauseIntervalSupported |
if (hapticsController.IsIntensitySupported)
{
hapticsController.SendHapticFeedback(currentWaveform, 0.75); // 75% intensity
}