Sdílet prostřednictvím


Vstup klávesnice, myši a ovladače (C++)

Tento článek se týká starších nativních rozhraní API WinRT. Pro nové projekty nativních aplikací doporučujeme použít rozhraní OpenXR API.

Fragmenty kódu v tomto článku v současné době ukazují použití C++/CX místo C++17 kompatibilních C++/WinRT, jak se používá v šabloně holografického projektu C++. Koncepty jsou ekvivalentem pro projekt C++/WinRT, ale kód budete muset přeložit.

Přihlášení k odběru vstupních událostí CoreWindow

Vstup klávesnice

Do šablony aplikace Windows Holographic zahrneme obslužnou rutinu události pro zadávání pomocí klávesnice stejně jako jakoukoli jinou aplikaci pro UPW. Vaše aplikace využívá vstupní data z klávesnice stejným způsobem v Windows Mixed Reality.

Z AppView.cpp:

// Register for keypress notifications.
   window->KeyDown +=
       ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &AppView::OnKeyPressed);

    …

   // Input event handlers

   void AppView::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ args)
   {
       //
       // TODO: Respond to keyboard input here.
       //
   }

Zadávání virtuální klávesnice

U imerzivních stolních náhlavních souprav můžete podporovat virtuální klávesnice vykreslené systémem Windows přes imerzivní zobrazení implementací CoreTextEditContext. Díky tomu může Systém Windows pochopit stav vlastních textových polí vykreslených aplikací, aby virtuální klávesnice správně přispěla k textu.

Další informace o implementaci podpory CoreTextEditContext najdete v ukázce CoreTextEditContext.

Vstup myši

Můžete také použít vstup pomocí myši, opět prostřednictvím obslužných rutin událostí vstupu CoreWindow pro UPW. Tady je postup, jak upravit šablonu aplikace Windows Holographic tak, aby podporovala kliknutí myší stejným způsobem jako stisknutá gesta. Po provedení této úpravy se po kliknutí myší na zařízení s imerzivní náhlavní soupravou přesune datová krychle.

Poznámka

Aplikace pro UPW můžou také získat nezpracovaná data XY pro myš pomocí rozhraní API MouseDevice .

Začněte deklarací nové obslužné rutiny OnPointerPressed v AppView.h:

protected:
       void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);

V AppView.cpp přidejte do SetWindow tento kód:

// Register for pointer pressed notifications.
   window->PointerPressed +=
       ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &AppView::OnPointerPressed);

Pak vložte tuto definici pro OnPointerPressed do dolní části souboru:

void AppView::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
   {
       // Allow the user to interact with the holographic world using the mouse.
       if (m_main != nullptr)
       {
           m_main->OnPointerPressed();
       }
   }

Obslužná rutina události, která jsme právě přidali, je průchozí do hlavní třídy šablony. Pojďme upravit hlavní třídu tak, aby podporovala toto předávání. Do souboru hlaviček přidejte tuto deklaraci veřejné metody:

// Handle mouse input.
       void OnPointerPressed();

Budete také potřebovat tuto proměnnou privátního člena:

// Keep track of mouse input.
       bool m_pointerPressed = false;

Nakonec aktualizujeme hlavní třídu novou logikou, která podporuje kliknutí myší. Začněte přidáním této obslužné rutiny události. Nezapomeňte aktualizovat název třídy:

void MyHolographicAppMain::OnPointerPressed()
   {
       m_pointerPressed = true;
   }

Teď v metodě Update nahraďte stávající logiku pro získání pozice ukazatele tímto:

SpatialInteractionSourceState^ pointerState = m_spatialInputHandler->CheckForInput();
   SpatialPointerPose^ pose = nullptr;
   if (pointerState != nullptr)
   {
       pose = pointerState->TryGetPointerPose(currentCoordinateSystem);
   }
   else if (m_pointerPressed)
   {
       pose = SpatialPointerPose::TryGetAtTimestamp(currentCoordinateSystem, prediction->Timestamp);
   }
   m_pointerPressed = false;

Znovu zkompilujte a nasaďte znovu. Všimněte si, že kliknutí myší teď změní umístění datové krychle v imerzivní náhlavní soupravě – nebo HoloLens s připojenou myší Bluetooth.

Podpora herního ovladače

Herní ovladače můžou být zábavným a pohodlným způsobem, jak uživateli umožnit ovládat imerzivní Windows Mixed Reality prostředí.

Přidejte následující deklarace privátních členů do třídy hlaviček pro váš hlavní soubor:

// Recognize gamepads that are plugged in after the app starts.
       void OnGamepadAdded(Platform::Object^, Windows::Gaming::Input::Gamepad^ args);
// Stop looking for gamepads that are unplugged.
       void OnGamepadRemoved(Platform::Object^, Windows::Gaming::Input::Gamepad^ args);
Windows::Foundation::EventRegistrationToken                     m_gamepadAddedEventToken;
       Windows::Foundation::EventRegistrationToken                     m_gamepadRemovedEventToken;
// Keeps track of a gamepad and the state of its A button.
       struct GamepadWithButtonState
       {
           Windows::Gaming::Input::Gamepad^ gamepad;
           bool buttonAWasPressedLastFrame = false;
       };
       std::vector<GamepadWithButtonState>                             m_gamepads;

Inicializace událostí gamepadu a všech aktuálně připojených gamepadů v konstruktoru pro vaši hlavní třídu:

// If connected, a game controller can also be used for input.
   m_gamepadAddedEventToken = Gamepad::GamepadAdded +=
       ref new EventHandler<Gamepad^>(
           bind(&$safeprojectname$Main::OnGamepadAdded, this, _1, _2)
           );
m_gamepadRemovedEventToken = Gamepad::GamepadRemoved +=
       ref new EventHandler<Gamepad^>(
           bind(&$safeprojectname$Main::OnGamepadRemoved, this, _1, _2)
           );
for (auto const& gamepad : Gamepad::Gamepads)
   {
       OnGamepadAdded(nullptr, gamepad);
   }

Přidejte tyto obslužné rutiny událostí do hlavní třídy. Nezapomeňte aktualizovat název třídy:

void MyHolographicAppMain::OnGamepadAdded(Object^, Gamepad^ args)
   {
       for (auto const& gamepadWithButtonState : m_gamepads)
       {
           if (args == gamepadWithButtonState.gamepad)
           {
               // This gamepad is already in the list.
               return;
           }
       }
       m_gamepads.push_back({ args, false });
   }
void MyHolographicAppMain::OnGamepadRemoved(Object^, Gamepad^ args)
   {
       m_gamepads.erase(
           std::remove_if(m_gamepads.begin(), m_gamepads.end(), [&](GamepadWithButtonState& gamepadWithState)
               {
                   return gamepadWithState.gamepad == args;
               }),
           m_gamepads.end());
   }

Nakonec aktualizujte vstupní logiku, aby rozpoznala změny ve stavu kontroleru. V tomto případě použijeme stejnou proměnnou m_pointerPressed probíranou v předchozí části pro přidání událostí myši. Přidejte toto do metody Update, těsně před místem, kde zkontroluje SpatialPointerPose:

// Check for new input state since the last frame.
   for (auto& gamepadWithButtonState : m_gamepads)
   {
       bool buttonDownThisUpdate = ((gamepadWithButtonState.gamepad->GetCurrentReading().Buttons & GamepadButtons::A) == GamepadButtons::A);
       if (buttonDownThisUpdate && !gamepadWithButtonState.buttonAWasPressedLastFrame)
       {
           m_pointerPressed = true;
       }
       gamepadWithButtonState.buttonAWasPressedLastFrame = buttonDownThisUpdate;
   }
// For context.
   SpatialInteractionSourceState^ pointerState = m_spatialInputHandler->CheckForInput();
   SpatialPointerPose^ pose = nullptr;
   if (pointerState != nullptr)
   {
       pose = pointerState->TryGetPointerPose(currentCoordinateSystem);
   }
   else if (m_pointerPressed)
   {
       pose = SpatialPointerPose::TryGetAtTimestamp(currentCoordinateSystem, prediction->Timestamp);
   }
   m_pointerPressed = false;

Nezapomeňte zrušit registraci událostí při čištění hlavní třídy:

if (m_gamepadAddedEventToken.Value != 0)
   {
       Gamepad::GamepadAdded -= m_gamepadAddedEventToken;
   }
   if (m_gamepadRemovedEventToken.Value != 0)
   {
       Gamepad::GamepadRemoved -= m_gamepadRemovedEventToken;
   }

Znovu zkompilujte a nasaďte znovu. Teď můžete připojit nebo spárovat herní ovladač a použít ho k přemístění rotující datové krychle.

Viz také