Now that you created the basic flow of your DirectX app using C++ and the Windows Runtime APIs, you're ready to start connecting handlers to the events fired for PLM and basic user input.
Instructions
In Create and initialize a view, you developed the Initialize and SetWindow methods on the view provider class, which are called by the app when it starts. These required methods attach the new view and window to the app, and map handlers to the Process Lifetime Management (PLM) events that your app supports. The code looks like this:
void MyDirectXApp::Initialize(CoreApplicationView^ applicationView) { applicationView->Activated += ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &MyDirectXApp::OnActivated); CoreApplication::Suspending += ref new EventHandler<SuspendingEventArgs^>(this, &MyDirectXApp::OnSuspending); CoreApplication::Resuming += ref new EventHandler<Platform::Object^>(this, &MyDirectXApp::OnResuming); m_renderer = ref new MyAppRenderer(); // MyAppRenderer is assumed to be derived from Direct3DBase. }
void MyDirectXApp::SetWindow(CoreWindow^ window) { window->SizeChanged += ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &MyDirectXApp::OnWindowSizeChanged); window->VisibilityChanged += ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &MyDirectXApp::OnVisibilityChanged); window->Closed += ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &MyDirectXApp::OnWindowClosed); window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); window->PointerPressed += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &MyDirectXApp::OnPointerPressed); window->PointerMoved += ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &MyDirectXApp::OnPointerMoved); m_renderer->Initialize(CoreWindow::GetForCurrentThread()); }
This maps to the set of events we defined in the header on your main app object. From the header file for your Direct3D App template app (in this case, MyDirectXApp.h):
// Event handlers void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args); void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args); void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args); void OnResuming(Platform::Object^ sender, Platform::Object^ args); void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args); void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
In this code, you have a handler for view activation: OnActivated. It's called when an app activates the view; that is, when the app view is active in the foreground of the display. In this sample, our code simply activates the associated CoreWindow instance. We also have handlers for the PLM suspend and resume events: OnSuspending and OnResuming.
We also have handlers for window visibility and size change events:
- OnVisibilityChanged is called when the app's main window moves from foreground to background, and vice versa.
- OnWindowSizeChanged is called when the display orientation changes, or if the app is snapped or unsnapped.
And we have handlers for some basic input events:
- OnPointerMoved is called when the user moves the mouse pointer or a touch input device.
- OnPointerPressed is called when the user presses a mouse button or a touch input device.
Now, you implement these handlers.
First, you define the view activation event handler, OnActivated.
void MyDirectXApp::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
{
CoreWindow::GetForCurrentThread()->Activate();
}
As mentioned earlier, you're simply activating the window that the app provided to the instance of the view provider. You can extend this method to generate a splash screen using the SplashScreen object provided by IActivatedEventArgs.SplashScreen, if you're feeling creative.
Now, you define the basic behaviors when OnSuspending and OnResuming are called by the suspend and resume PLM events respectively.
void MyDirectXApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) { // Save app state asynchronously after requesting a deferral. Holding a deferral // indicates that the application is busy performing suspending operations. Be // aware that a deferral cannot be held indefinitely. After about five seconds, // the app will be forced to exit. SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); create_task([this, deferral]() { // Insert your code here. deferral->Complete(); }); } void MyDirectXApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) { // Restore any data or state that was unloaded on suspend. By default, data // and state are persisted when resuming from suspend. Be aware that this event // doesn't occur if the app was previously terminated. }
Next , you write the code for window's event handlers: OnWindowSizeChanged and OnVisibilityChanged.
void MyDirectXApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) { m_renderer->UpdateForWindowSizeChange(); } void MyDirectXApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) { m_windowVisible = args->Visible; }
In OnWindowSizeChanged, you must provide code that will recreate your DirectX swap chain's display size when the window is resized. In this example, you create a private method UpdateForWindowSizeChange, as called in the code earlier. (The template uses the base implementation provided in Direct3DBase.h/.cpp.) We talk more about this method in Connect the DirectX swap chain.
You must update the graphics resources when the size changes. Add a method like this to your view provider class (or, in this case, its parent class):
void Direct3DBase::UpdateForWindowSizeChange() { if (m_window->Bounds.Width != m_windowBounds.Width || m_window->Bounds.Height != m_windowBounds.Height || m_orientation != DisplayProperties::CurrentOrientation) { ID3D11RenderTargetView* nullViews[] = {nullptr}; m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr); m_renderTargetView = nullptr; m_depthStencilView = nullptr; m_d3dContext->Flush(); CreateWindowSizeDependentResources(); } }
CreateWindowSizeDependentResources is discussed in Step 3: Connect the DirectX swap chain.
Last, you create handlers for the input events.
/void MyDirectXApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) { // Insert your code here. } void MyDirectXApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) { // Insert your code here. }
Previous step
Create and initialize a viewNext step
Connect the DirectX swap chainRelated topics
- How to set up your DirectX Windows Store app to display a view
- Complete code for a DirectX Windows Store app
Build date: 3/11/2013