Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come aggiungere feedback aptico all'app Windows usando l'API InputHapticsManager, inclusi esempi di codice per modelli di interazione comuni.
Per indicazioni sulla progettazione su quando e perché usare gli aptici, vedere Linee guida per la progettazione aptici.
Dispositivi supportati
Gli aptici sono supportati su dispositivi di input come mouse, touchpad e penne. La disponibilità varia in base al modello e al produttore. Verificare sempre il supporto in fase di esecuzione prima di chiamare le API aptici (vedere Controllare il supporto di seguito).
Requirements
| Requisito | dettagli |
|---|---|
| Namespace | Windows.Devices.Haptics |
| Sistema operativo minimo | Windows 11, SDK 10.0.28000.1721 (marzo 2026) |
| Allinea/Collide/Passo/Crescere forme d'onda | SDK 10.0.28000.1839 (aprile 2026) |
| Contratto dell'API |
UniversalApiContract versione 19.0 |
Per usare le versioni precedenti del sistema operativo, usare ApiInformation.IsTypePresent per proteggere tutte le chiamate (vedere il codice seguente).
Verificare la disponibilità del supporto
Verificare sempre che l'API sia disponibile e che sia presente un dispositivo aptico prima dell'uso. L'API non è presente nelle versioni precedenti del sistema operativo e non tutti i dispositivi di input supportano gli aptici.
using Windows.Devices.Haptics;
using Windows.Foundation.Metadata;
// Guard against older OS versions where the API is absent.
bool apiPresent = ApiInformation.IsTypePresent("Windows.Devices.Haptics.InputHapticsManager");
// Check that a supported haptic device is connected.
bool supported = apiPresent && InputHapticsManager.IsSupported();
Attiva una forma d'onda
Chiamare InputHapticsManager.GetForCurrentThread() nel thread dell'interfaccia utente per ottenere un'istanza del gestore associata al focus di input del thread corrente. Il rilevamento e il routing dei dispositivi vengono gestiti automaticamente: non è necessario enumerare manualmente i dispositivi.
using Windows.Devices.Haptics;
if (supported)
{
var mgr = InputHapticsManager.GetForCurrentThread();
// The second parameter is a fallback waveform used if the first is
// unsupported. Passing 0 lets the system choose a device-appropriate
// fallback. TrySendHapticWaveform returns false if neither waveform is
// supported; this is a non-fatal condition.
bool sent = mgr.TrySendHapticWaveform(
KnownSimpleHapticsControllerWaveforms.Align,
0);
}
Important
Chiama GetForCurrentThread() dal thread dell'interfaccia utente (o dal thread che ha il focus di input). Chiamarlo da un thread in background non indirizzerà il feedback al dispositivo corretto.
Interrompi riproduzione
Chiama TryStopFeedback quando termina un trascinamento o un'interazione per interrompere qualsiasi riproduzione aptica in corso.
using Windows.Devices.Haptics;
if (supported)
{
InputHapticsManager
.GetForCurrentThread()
.TryStopFeedback();
}
Esempi di implementazione
Allineamento degli oggetti
Le guide di allineamento sono comuni negli strumenti di progettazione, negli editor di presentazioni e nelle app di creazione di diagrammi. Il feedback aptico aggiunge un secondo canale in modo che gli utenti possano sentire quando gli oggetti si bloccano sul posto, riducendo la necessità di eseguire lo zoom avanti per confermare visivamente l'allineamento.
Quando attivare: Usa la comparsa della guida di allineamento come segnale. Quando la logica di ancoraggio visualizza una guida, attiva il feedback aptico. Se non viene visualizzata alcuna guida, non sparare. Ciò mantiene gli eventi aptici strettamente associati al feedback visibile del sistema.
Evitare duplicati: Una forma può essere allineata contemporaneamente a più guide (ad esempio, bordo sinistro e bordo superiore). Considera questo come una singola interazione: tieni traccia delle guide attive e attiva solo quando viene visualizzata una nuova guida.
using Windows.Devices.Haptics;
private readonly HashSet<int> _activeGuides = new();
// Call this after computing which alignment guides are currently visible.
void OnGuidesUpdated(IEnumerable<int> currentGuideIds)
{
var currentGuides = currentGuideIds.ToHashSet();
bool hasNewGuide = currentGuides.Except(_activeGuides).Any();
// Update the tracked set in place (field is readonly).
_activeGuides.Clear();
_activeGuides.UnionWith(currentGuides);
if (hasNewGuide && supported)
{
InputHapticsManager.GetForCurrentThread()
.TrySendHapticWaveform(
KnownSimpleHapticsControllerWaveforms.Align,
0);
}
}
Sliders
Il feedback aptico migliora le interazioni con il cursore ancorando il feedback a posizioni chiave. Associare sempre il feedback ai marcatori visibili che l'utente può comprendere: segni di graduazione, valori denominati o limiti di intervallo.
Quando attivare: Attiva il feedback aptico quando il pollice supera ogni tacca. Evitare un feedback continuo tra un ticchettio e l’altro, poiché può risultare fastidioso.
using Windows.Devices.Haptics;
double _previousValue;
const double TickInterval = 25.0;
void OnSliderValueChanged(double newValue)
{
int previousTick = (int)(_previousValue / TickInterval);
int currentTick = (int)(newValue / TickInterval);
if (currentTick != previousTick && supported)
{
InputHapticsManager.GetForCurrentThread()
.TrySendHapticWaveform(
KnownSimpleHapticsControllerWaveforms.Step,
0);
}
_previousValue = newValue;
}
Affinamento dell'esperienza: Scalare l'intensità aptica in base alla posizione del dispositivo di scorrimento per aiutare gli utenti a percepire dove si trovano all'interno dell'intervallo. Usare TrySendHapticWaveformForPlayCount, che accetta un valore di intensità esplicito da 0.0 a 1.0.
void OnSliderValueChangedWithIntensity(double newValue, double maxValue)
{
int previousTick = (int)(_previousValue / TickInterval);
int currentTick = (int)(newValue / TickInterval);
if (currentTick != previousTick && supported)
{
double intensity = newValue / maxValue; // Scale 0.0–1.0
InputHapticsManager.GetForCurrentThread()
.TrySendHapticWaveformForPlayCount(
KnownSimpleHapticsControllerWaveforms.Step,
0, // fallback waveform
intensity,
1, // playCount
TimeSpan.Zero);
}
_previousValue = newValue;
}
Interazioni di trascinamento e rilevamento dell'intenzione
Durante un trascinamento, un oggetto può attraversare molti limiti di allineamento, ovvero il centro pagine, le guide e altri oggetti. L'attivazione del feedback aptico a ogni superamento di una soglia può risultare eccessiva per gli utenti, soprattutto durante i movimenti rapidi, quando stanno semplicemente riposizionandosi anziché cercare la massima precisione.
Usare il rilevamento dell’intenzione per attivare il feedback solo quando l’utente sta cercando intenzionalmente di allinearsi, non quando vi passa semplicemente attraverso.
Approccio 1: Filtro velocità
Disattiva il feedback aptico quando il cursore si sposta rapidamente, riservando il feedback ai movimenti più lenti e deliberati.
- Stabilizza il segnale. Evitare di usare delta di cursori non elaborati, che possono essere rumorosi tra tipi di input, impostazioni DPI e configurazioni di visualizzazione. Normalizzare e regolare il segnale.
- Scegliere attentamente una soglia. Verificare su dispositivi diversi, tipi di input, scale di visualizzazione e configurazioni con più schermi.
Approccio 2: Debounce del timer
Quando un oggetto entra in una zona trigger, avviare un breve timer (50 ms è un punto di partenza ragionevole). Se l'oggetto rimane nella zona quando il timer scade, consideralo intenzionale e attiva il feedback aptico. Se l'oggetto si sposta prima dell'attivazione del timer, eliminare il feedback.
- Più semplice da implementare e tende a produrre un comportamento più stabile rispetto al filtro della velocità.
- Un ritardo di 50 ms è sufficientemente lungo da distinguere l'allineamento intenzionale da un passaggio rapido, mentre rimane al di sotto della soglia di latenza evidente.
using System;
using Microsoft.UI.Xaml;
using Windows.Devices.Haptics;
private DispatcherTimer? _alignTimer;
void OnObjectEnteredAlignmentZone()
{
_alignTimer?.Stop();
_alignTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(50) };
_alignTimer.Tick += (_, _) =>
{
_alignTimer.Stop();
if (supported)
{
InputHapticsManager.GetForCurrentThread()
.TrySendHapticWaveform(
KnownSimpleHapticsControllerWaveforms.Align,
0);
}
};
_alignTimer.Start();
}
void OnObjectLeftAlignmentZone()
{
_alignTimer?.Stop();
}
Scelta tra i due
| Filtro velocità | Debounce timer | |
|---|---|---|
| Funzionamento | Reattivo: misura lo spostamento in tempo reale | Predittivo: attende brevemente di confermare la finalità |
| Sentire | Può sentirsi più immediato | Leggermente ritardato, ma più coerente |
| Ottimizzazione dello sforzo | Superiore: richiede un'attenta calibrazione | Minore: un singolo valore di ritardo è in genere sufficiente |
| Consigliato per | App che richiedono feedback altamente reattivo | La maggior parte delle app; buon punto di partenza predefinito |