Billentyűzet-, egér- és vezérlőbemenet (C++)
Ez a cikk az örökölt WinRT natív API-kkal kapcsolatos. Új natív alkalmazásprojektek esetén az OpenXR API használatát javasoljuk.
A jelen cikkben szereplő kódrészletek jelenleg a C++/CX használatát mutatják be a C++17-kompatibilis C++/WinRT helyett, a C++ holografikus projektsablonban használt módon. A fogalmak egyenértékűek egy C++/WinRT-projekt esetében, bár a kódot le kell fordítania.
Feliratkozás CoreWindow bemeneti eseményekre
Billentyűzet bemenete
A Windows Holographic alkalmazássablonban egy eseménykezelőt is használunk a billentyűzetbemenethez, ugyanúgy, mint bármely más UWP-alkalmazás. Az alkalmazás ugyanúgy használja fel a billentyűzetbemeneti adatokat, mint Windows Mixed Reality.
Az AppView.cpp fájlból:
// 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.
//
}
Virtuális billentyűzet bemenete
Modern asztali headsetek esetén a CoreTextEditContext implementálásával támogatja a Windows által a modern nézetben megjelenített virtuális billentyűzeteket. Ez lehetővé teszi a Windows számára a saját alkalmazás által renderelt szövegdobozok állapotának megértését, hogy a virtuális billentyűzet megfelelően hozzájáruljon a szöveghez.
A CoreTextEditContext támogatásának implementálásáról további információt a CoreTextEditContext minta című témakörben talál.
Egér bemenete
Az egérbemenetet az UWP CoreWindow bemeneti eseménykezelők segítségével is használhatja. Így módosíthatja a Windows Holographic alkalmazássablont úgy, hogy az egérkattintásokat ugyanúgy támogassa, mint a lenyomott kézmozdulatokat. A módosítás elvégzése után egy egérkattintás, miközben magával ragadó headsetet visel, áthelyezi a kockát.
Megjegyzés
Az UWP-alkalmazások nyers XY-adatokat is lekérhetnek az egérhez a MouseDevice API használatával.
Először deklaráljon egy új OnPointerPressed kezelőt az AppView.h-ban:
protected:
void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
Az AppView.cpp fájlban adja hozzá ezt a kódot a SetWindow fájlhoz:
// Register for pointer pressed notifications.
window->PointerPressed +=
ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &AppView::OnPointerPressed);
Ezután tegye a definíciót az OnPointerPressed kifejezésre a fájl alján:
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();
}
}
Az imént hozzáadott eseménykezelő átengedi a sablon főosztályát. Módosítsa a főosztályt, hogy támogassa ezt a továbbítást. Adja hozzá ezt a nyilvános metódus deklarációt a fejlécfájlhoz:
// Handle mouse input.
void OnPointerPressed();
Erre a privát tagváltozóra is szüksége lesz:
// Keep track of mouse input.
bool m_pointerPressed = false;
Végül frissítjük a főosztályt új logikával az egérkattintások támogatásához. Először vegye fel ezt az eseménykezelőt. Győződjön meg arról, hogy frissíti az osztály nevét:
void MyHolographicAppMain::OnPointerPressed()
{
m_pointerPressed = true;
}
Az Update metódusban cserélje le a mutatópóz lekérésének meglévő logikáját a következőre:
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;
Újrafordítása és ismételt üzembe helyezése. Figyelje meg, hogy az egérkattintás mostantól áthelyezi a kockát a magával ragadó headsetbe – vagy a HoloLensbe bluetooth egérrel csatlakoztatva.
Játékvezérlő támogatása
Játékvezérlők lehet egy szórakoztató és kényelmes módja annak, hogy lehetővé teszi a felhasználó számára, hogy vezérelje a magával ragadó Windows Mixed Reality élményt.
adja hozzá a következő privát tag deklarációkat a törzsfájl fejlécosztályához:
// 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;
Inicializálja a gamepadeseményeket és a jelenleg csatlakoztatott játékpadokat a főosztály konstruktorában:
// 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);
}
Adja hozzá ezeket az eseménykezelőket a főosztályhoz. Győződjön meg arról, hogy frissíti az osztály nevét:
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());
}
Végül frissítse a bemeneti logikát, hogy felismerje a vezérlőállapot változásait. Itt ugyanazt a m_pointerPressed változót használjuk, amelyet a fenti szakaszban tárgyaltunk az egéresemények hozzáadásához. Adja hozzá ezt az Update metódushoz, közvetlenül a SpatialPointerPose ellenőrzése előtt:
// 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;
Ne felejtse el törölni az események regisztrációját a főosztály törlésekor:
if (m_gamepadAddedEventToken.Value != 0)
{
Gamepad::GamepadAdded -= m_gamepadAddedEventToken;
}
if (m_gamepadRemovedEventToken.Value != 0)
{
Gamepad::GamepadRemoved -= m_gamepadRemovedEventToken;
}
Újrafordítása és ismételt üzembe helyezése. Mostantól csatolhat vagy párosíthat egy játékvezérlőt, és ezzel áthelyezheti a forgó kockát.