Implementera haptisk feedback i Windows appar

Den här artikeln beskriver hur du lägger till haptisk feedback i din Windows-app med hjälp av InputHapticsManager-API:et, inklusive kodexempel för vanliga interaktionsmönster.

Designvägledning om när och varför du ska använda haptics finns i Haptics designriktlinjer.

Enheter som stöds

Haptik stöds för inmatningsenheter som möss, pekplattor och pennor. Tillgängligheten varierar beroende på modell och tillverkare. Sök alltid efter support vid körning innan du anropar haptics-API:er (se Sök efter support nedan).

Requirements

Krav Detaljer
Namespace Windows.Devices.Haptics
Lägsta operativsystem Windows 11, SDK 10.0.28000.1721 (mars 2026)
Justera / Överlappa / Stega / Förstora vågformer SDK 10.0.28000.1839 (april 2026)
API-kontrakt UniversalApiContract version 19.0

Om du vill rikta in dig på äldre OS-versioner använder du ApiInformation.IsTypePresent för att skydda alla anrop (se koden nedan).

Kontrollera om stöd finns

Kontrollera alltid att API:et är tillgängligt och att det finns en haptisk enhet före användning. API:et finns inte i äldre os-versioner och inte alla indataenheter stöder haptics.

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();

Utlösa en vågform

Anropa InputHapticsManager.GetForCurrentThread() på UI-tråden för att hämta en hanterarinstans som är kopplad till den aktuella trådens indatafokus. Enhetsidentifiering och routning hanteras automatiskt – du behöver inte räkna upp enheter själv.

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

Anropa GetForCurrentThread() från användargränssnittstråden (eller tråden som äger indatafokus). Om du anropar den från en bakgrundstråd dirigeras inte feedback till rätt enhet.

Stoppa uppspelning

Anropa TryStopFeedback när ett drag eller en interaktion avslutas för att stoppa eventuell pågående haptisk återgivning.

using Windows.Devices.Haptics;

if (supported)
{
    InputHapticsManager
        .GetForCurrentThread()
        .TryStopFeedback();
}

Implementeringsexempel

Objektjustering

Justeringsguider är vanliga i designverktyg, presentationsredigerare och diagramappar. Haptic feedback lägger till en andra kanal så att användarna kan känna när objekt fästs på plats, vilket minskar behovet av att zooma in för att visuellt bekräfta justeringen.

När du ska avfyra: Använd justeringsguidens utseende som utlösare. När din snaplogik visar en guide aktiverar du den haptiska återkopplingen. Om ingen guide visas, avfyra inte. Detta håller haptiska händelser nära kopplade till synlig systemfeedback.

Undvik dubbletter: En form kan justeras mot flera stödlinjer samtidigt (till exempel vänsterkant och överkant). Behandla detta som en enda interaktion – spåra aktiva guider och starta bara när en ny guide visas.

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

Haptics förbättrar skjutreglageinteraktioner genom att förankra feedback till meningsfulla positioner. Koppla alltid feedback till synliga markörer som användaren kan förstå – bockmarkeringar, namngivna värden eller intervallgränser.

När den ska aktiveras: Utlös haptisk återkoppling när tummen passerar varje markering. Undvik kontinuerlig feedback mellan fästingar, vilket kan kännas distraherande.

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;
}

Förfina upplevelsen: Skala haptisk intensitet baserat på skjutreglagets position för att hjälpa användarna att känna av var de befinner sig inom intervallet. Använd TrySendHapticWaveformForPlayCount, som accepterar ett explicit intensitetsvärde från 0.0 till 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;
}

draginteraktioner och avsiktsdetektering

När ett objekt dras kan det passera flera justeringsgränser – sidans mitt, hjälplinjer och andra objekt. Att utlösa haptisk återkoppling vid varje passage kan överväldiga användare, särskilt vid snabba rörelser när de flyttar om snarare än försöker vara precisa.

Använd avsiktsdetektering för att utlösa feedback endast när användaren avsiktligt försöker rikta in sig, inte när de bara passerar förbi.

Metod 1: Hastighetsfilter

Inaktivera haptisk återkoppling när markören rör sig snabbt, så att återkoppling endast ges vid långsammare och mer medvetna rörelser.

  • Stabilisera signalen. Undvik att använda råa markördelta, vilket kan vara brus mellan indatatyper, DPI-inställningar och visningskonfigurationer. Normalisera och jämna ut signalen.
  • Välj ett tröskelvärde noggrant. Verifiera mellan olika enheter, indatatyper, visningsskalor och installationer för flera bildskärmar.

Metod 2: Timerdebounce

När ett objekt går in i en utlösarzon startar du en kort timer (50 ms är en rimlig startpunkt). Om objektet finns kvar i zonen när timern har löpt ut, betrakta det som avsiktligt och utlös den haptiska återkopplingen. Om objektet går vidare innan timern utlöses undertrycker du feedbacken.

  • Enklare att implementera och tenderar att skapa stabilare beteende än hastighetsfiltrering.
  • En fördröjning på 50 ms är tillräckligt lång för att skilja avsiktlig justering från en snabbpassning, samtidigt som den ligger under tröskelvärdet för märkbar svarstid.
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();
}

Välja mellan de två

Hastighetsfilter Tidsfördröjning
Så här fungerar det Reaktiv – mäter rörelse i realtid Predictive – väntar kort för att bekräfta avsikten
Känn Kan kännas mer omedelbart Något fördröjd, men mer konsekvent
Justeringsinsats Högre – kräver noggrann kalibrering Lägre – ett enda fördröjningsvärde räcker vanligtvis
Rekommenderas för Appar som kräver mycket responsiv feedback De flesta appar; bra standardstartpunkt