Haptikus visszajelzések implementálása Windows alkalmazásokban

Ez a cikk bemutatja, hogyan adhat hozzá haptikus visszajelzést a Windows-alkalmazáshoz az InputHapticsManager API használatával, beleértve a gyakori interakciós minták kódpéldáit is.

A haptik használatának időpontjáról és okáról a Haptics tervezési irányelveiből olvashat.

Támogatott eszközök

A haptik támogatottak olyan beviteli eszközökön, mint az egerek, az érintőpárnák és a tollak. A rendelkezésre állás modelltől és gyártótól függően változik. A haptics API-k meghívása előtt mindig ellenőrizze, hogy van-e támogatás futásidőben (lásd alább a támogatás ellenőrzése című témakört).

Requirements

Requirement Részletek
Namespace Windows.Devices.Haptics
Minimális operációs rendszer Windows 11, SDK 10.0.28000.1721 (2026. március)
Igazítás / Összeütközés / Lépés / Hullámformák növelése SDK 10.0.28000.1839 (2026. április)
API-szerződés UniversalApiContract 19.0-s verzió

A korábbi operációsrendszer-verziók célzásához használja ApiInformation.IsTypePresent az összes hívás őrzésére (lásd az alábbi kódot).

Támogatás keresése

Mindig ellenőrizze, hogy elérhető-e az API, és hogy használat előtt van-e egy haptikus eszköz. Az API nem található meg a régebbi operációsrendszer-verziókban, és nem minden bemeneti eszköz támogatja a hapticset.

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

Hullámforma aktiválása

Hívja meg a(z) InputHapticsManager.GetForCurrentThread() elemet az UI-szálon, hogy lekérjen egy, az aktuális szál beviteli fókuszához kötött kezelőpéldányt. Az eszközészlelés és az útválasztás kezelése automatikusan megtörténik – önnek nem kell számba vennie az eszközöket.

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

Hívás GetForCurrentThread() a felhasználói felületi szálról (vagy a bemeneti fókuszt tartalmazó szálról). Ha háttérszálból hívja meg, az nem irányítja a visszajelzést a megfelelő eszközre.

Lejátszás leállítása

A húzási művelet vagy interakció befejezésekor hívja meg a(z) TryStopFeedback elemet, hogy leállítsa a folyamatban lévő haptikus lejátszást.

using Windows.Devices.Haptics;

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

Megvalósítási példák

Objektum igazítása

Az igazítási útmutatók gyakoriak a tervezőeszközökben, a bemutatószerkesztőkben és a diagramkészítési alkalmazásokban. A Haptic-visszajelzések egy második csatornát adnak hozzá, hogy a felhasználók érezzék , amikor az objektumok a helyére kerülnek – így csökkentve a nagyítás szükségességét, hogy vizuálisan megerősítsék az igazítást.

Mikor aktiválódik: Aktiváló jelként az igazítási segédvonal megjelenése szolgáljon. Ha a illesztési logika egy útmutatót jelenít meg, aktiválja a hapticot. Ha nem jelenik meg útmutató, ne gyújtsa be. Ez szorosan összekapcsolja a haptikus eseményeket a látható rendszervisszajelzésekkel.

Kerülje az ismétlődéseket: Az alakzatok egyszerre több segédvonalhoz (például a bal szélhez és a felső szélhez) igazíthatók. Kezelje ezt egyetlen interakcióként – kövesse nyomon az aktív segédvonalakat, és csak új útmutató megjelenésekor aktiválja a műveletet.

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

A Haptics a visszajelzések értelmes pozíciókhoz való rögzítésével javítja a csúszkák közötti interakciókat. Mindig kössön visszajelzést a felhasználó által megérthető látható jelölőkhöz – osztásjelekhez, elnevezett értékekhez vagy tartományhatárokhoz.

Mikor aktiválódjon: Aktiválja a haptikus visszajelzést, amikor a hüvelykujj áthalad az egyes osztásjeleknél. Kerülje az egyes beosztások közötti folyamatos visszajelzést, mivel ez zavaró lehet.

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

A felület finomítása: Haptikus intenzitást skálázhat a csúszka pozíciója alapján, hogy a felhasználók érzékelni tudják, hol vannak a tartományon belül. Használja a(z) TrySendHapticWaveformForPlayCount elemet, amely 0.0 és 1.0 közötti konkrét intenzitásértéket fogad el.

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

Húzási interakciók és a szándék felismerése

Az húzás során az objektumok számos igazítási határt átléphetnek – oldal közepét, segédvonalakat és egyéb objektumokat. A haptikus visszajelzés minden egyes átlépésnél túlterhelheti a felhasználókat, különösen gyors mozgások közben, amikor inkább áthelyeznek valamit, mintsem pontosan próbálnának célozni.

Használja a szándékfelismerést, hogy csak akkor váltson ki visszajelzést, amikor a felhasználó szándékosan próbál igazodni, nem pedig csak áthalad.

1. megközelítés: Sebességszűrő

A kurzor gyors mozgása esetén mellőzheti a haptiket, így a visszajelzéseket a lassabb, megfontoltabb mozgás érdekében megőrizheti.

  • Stabilizálja a jelet. Kerülje a nyers kurzormozgási deltaértékek használatát, mert ezek a bemeneti eszköz típusától, a DPI-beállításoktól és a kijelzőkonfigurációtól függően ingadozóak lehetnek. Normalizálja és simítsa a jelet.
  • Gondosan válasszon ki egy küszöbértéket. Különböző eszközök, beviteli típusok, megjelenítési skálák és több kijelzős beállítások ellenőrzése.

2. megközelítés: Időzítő felbontása

Amikor egy objektum belép egy eseményindító zónába, indítsa el a rövid időzítőt (50 ms ésszerű kiindulópont). Ha az objektum az időzítő befejeződésekor a zónában marad, kezelje szándékosként, és aktiválja a hapticot. Ha az objektum továbbhalad az időzítő kigyulladása előtt, tiltsa le a visszajelzést.

  • Egyszerűbb implementálni, és stabilabb viselkedést eredményez, mint a sebességszűrés.
  • Az 50 ms-os késleltetés elég hosszú ahhoz, hogy megkülönböztesse a szándékos igazítást a gyors áthaladástól, miközben az észrevehető késés küszöbértéke alatt marad.
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álasztás a kettő között

Sebességszűrő Időzítő törlése
Hogyan működik Reaktív – valós időben méri a mozgást Prediktív – rövid várakozás a szándék megerősítéséhez
Érzet Közvetlenebbnek hathat Kissé késleltetett, de konzisztensebb
Finomhangolási munka Magasabb – gondos kalibrálást igényel Alacsonyabb – általában elegendő egyetlen késleltetési érték
Ajánlott a következőhöz: Rendkívül rugalmas visszajelzést igénylő alkalmazások A legtöbb alkalmazás; jó alapértelmezett kiindulási pont