Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule wyjaśniono, jak dodać opinie haptyczne do aplikacji Windows przy użyciu interfejsu API InputHapticsManager, w tym przykłady kodu dla typowych wzorców interakcji.
Aby uzyskać wskazówki dotyczące projektowania dotyczące tego, kiedy i dlaczego należy używać haptyki, zobacz Wskazówki dotyczące projektowania haptyki.
Obsługiwane urządzenia
Haptics są obsługiwane na urządzeniach wejściowych, takich jak myszy, touchpady i długopisy. Dostępność różni się w zależności od modelu i producenta. Zawsze sprawdzaj wsparcie w czasie działania przed wywołaniem interfejsów API funkcji haptycznych (zobacz poniżej sekcję Sprawdzanie wsparcia).
Requirements
| Requirement | Szczegóły |
|---|---|
| Namespace | Windows.Devices.Haptics |
| Minimalna wersja systemu operacyjnego | Windows 11, SDK 10.0.28000.1721 (marzec 2026) |
| Wyrównaj/ zderzaj się / Krok / Rozwijaj kształty fali | Zestaw SDK 10.0.28000.1839 (kwiecień 2026 r.) |
| Kontrakt API |
UniversalApiContract wersja 19.0 |
Aby obsługiwać starsze wersje systemu operacyjnego, użyj ApiInformation.IsTypePresent, aby warunkowo zabezpieczyć wszystkie wywołania (zobacz poniższy kod).
Sprawdź obsługę
Przed użyciem zawsze sprawdź, czy interfejs API jest dostępny i czy urządzenie haptyczne jest obecne. Interfejs API nie jest obecny w starszych wersjach systemu operacyjnego, a nie wszystkie urządzenia wejściowe obsługują haptyki.
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();
Wyzwalanie kształtów fali
Wywołaj InputHapticsManager.GetForCurrentThread() w wątku interfejsu użytkownika, aby uzyskać instancję menedżera powiązaną z fokusem wejściowym bieżącego wątku. Wykrywanie i routing urządzeń są obsługiwane automatycznie — nie musisz wyliczać urządzeń samodzielnie.
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
Wywołaj GetForCurrentThread() z wątku interfejsu użytkownika (lub z wątku, który ma fokus danych wejściowych). Wywołanie tej funkcji z wątku w tle nie będzie przekierowywać informacji zwrotnej do właściwego urządzenia.
Zatrzymaj odtwarzanie
Wywołaj TryStopFeedback, gdy zakończy się przeciąganie lub interakcja, aby zatrzymać wszelkie trwające efekty haptyczne.
using Windows.Devices.Haptics;
if (supported)
{
InputHapticsManager
.GetForCurrentThread()
.TryStopFeedback();
}
Przykład wdrożenia
Wyrównanie obiektu
Prowadnice wyrównania są powszechne w narzędziach projektowych, edytorach prezentacji i aplikacjach do tworzenia diagramów. Sprzężenie haptyczne dodaje drugi kanał, dzięki czemu użytkownicy mogą poczuć, kiedy obiekty wskakują na swoje miejsce — co zmniejsza konieczność powiększania, aby wzrokowo potwierdzić wyrównanie.
Kiedy należy uruchomić: Użyj wyglądu przewodnika wyrównania jako wyzwalacza. Gdy mechanizm przyciągania wyświetli prowadnicę, włącz reakcję haptyczną. Jeśli nie pojawi się wskaźnik, nie oddawaj strzału. Dzięki temu zdarzenia haptyczne są ściśle powiązane z widocznymi informacjami zwrotnymi systemu.
Unikaj duplikatów: Kształt może być wyrównany do wielu prowadnic jednocześnie (na przykład lewa krawędź i górna krawędź). Traktuj to jako jedną interakcję — śledź aktywne prowadnice i uruchamiaj je tylko wtedy, gdy pojawi się nowy przewodnik.
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
Haptyka poprawia interakcje z suwakiem, przypisując informacje zwrotne do istotnych położeń. Zawsze należy powiązać opinie z widocznymi znacznikami, które użytkownik może zrozumieć — znaczniki zaznaczenia, nazwane wartości lub granice zakresu.
Kiedy uruchamiać: Uruchamiaj haptyczne sprzężenie zwrotne, gdy kciuk mija każdy znacznik podziałki. Unikaj ciągłej informacji zwrotnej między tyknięciami, ponieważ może to rozpraszać.
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;
}
Udoskonalanie działania: Dostosuj intensywność haptyki w zależności od położenia suwaka, aby użytkownicy mogli wyczuć, w którym miejscu zakresu się znajdują. Użyj elementu TrySendHapticWaveformForPlayCount, który akceptuje jawną wartość intensywności z 0.0 do 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;
}
Interakcje przeciągania i wykrywanie intencji
Podczas przeciągania obiekt może przechodzić przez wiele linii wyrównania — środek strony, prowadnice i inne obiekty. Uruchamianie informacji haptycznej przy każdym przekroczeniu może przytłaczać użytkowników, zwłaszcza podczas szybkich ruchów, gdy zmieniają położenie, a nie próbują działać precyzyjnie.
Użyj wykrywania intencji, aby uruchamiać informację zwrotną tylko wtedy, gdy użytkownik próbuje świadomie wyrównać element, a nie tylko obok niego przechodzi.
Podejście 1. Filtr szybkości
Wyłącz reakcje haptyczne, gdy kursor porusza się szybko, pozostawiając je dla wolniejszych, bardziej celowych ruchów.
- Stabilizuj sygnał. Unikaj używania nieprzetworzonych różnic kursorów, które mogą być hałaśliwe dla typów wejściowych, ustawień DPI i konfiguracji wyświetlania. Normalizuj i wygładź sygnał.
- Starannie wybierz próg. Zweryfikuj różne urządzenia, typy danych wejściowych, skale wyświetlania i konfiguracje z wieloma wyświetlaczami.
Podejście 2. Odrzuć czasomierz
Gdy obiekt wchodzi w strefę wyzwalacza, uruchom krótki czasomierz (50 ms jest rozsądnym punktem początkowym). Jeśli obiekt nadal znajduje się w strefie, gdy licznik czasu dobiegnie końca, uznaj to za działanie zamierzone i uruchom sygnał haptyczny. Jeśli obiekt przemieści się, zanim upłynie czas timera, wstrzymaj informację zwrotną.
- Prostsze do zaimplementowania i ma tendencję do tworzenia bardziej stabilnego zachowania niż filtrowanie szybkości.
- Opóźnienie 50 ms jest wystarczająco długie, aby odróżnić celowe ustawienie od szybkiego przesunięcia, a jednocześnie pozostaje poniżej progu zauważalnej zwłoki.
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();
}
Wybieranie między nimi
| Filtr prędkości | Eliminacja drgań timera | |
|---|---|---|
| Jak to działa | Reaktywne — mierzy ruch w czasie rzeczywistym | Predykcyjna — czeka krótko, aby potwierdzić intencję |
| Poczuj | Może sprawiać wrażenie bardziej bezpośredniego | Nieco opóźnione, ale bardziej spójne |
| Wysiłek związany ze strojeniem | Wyższa — wymaga starannej kalibracji | Niższa — pojedyncza wartość opóźnienia jest zwykle wystarczająca |
| Zalecane dla | Aplikacje wymagające bardzo dynamicznej opinii | Większość aplikacji; dobry domyślny punkt początkowy |