The app object and DirectX (Windows Runtime apps using DirectX with C++)
Windows Store apps with DirectX (mostly games) don't use many of the new Windows UI user interface elements and objects. Rather, because they run at a lower level in the Windows Runtime stack, they must interoperate with the user interface framework in a more fundamental way: by accessing and interoperating with the app object directly. Learn when and how this interoperation occurs, and how you, as a DirectX developer, can effectively use this model in the development of your Windows Store apps.
First, let's note the Windows Runtime namespaces that you must include (with using) in your Windows Store apps. We get into the details in a bit.
In your Windows Store app, you want to get a window and a view provider from which you can get a view and to which you can connect your swap chain (your display buffers). You can also hook this view into the window-specific events for your running app. To get the parent window for the app object, defined by the CoreWindow type, create a type that implements IFrameworkViewSource, as we did in the previous code snippet.
Here's the basic set of steps to get a window using the core user interface framework:
Create a type that implements IFrameworkView. This is your view.
In this type, define:
- An Initialize method that takes an instance of CoreApplicationView as a parameter. You can get an instance of this type by calling CoreApplication.CreateNewView. The app object calls it when the app is launched.
- A SetWindow method that takes an instance of CoreWindow as a parameter. You can get an instance of this type by accessing the CoreWindow property on your new CoreApplicationView instance.
- A Load method that takes a string for an entry point as the sole parameter. The app object provides the entry point string when you call this method. This is where you set up resources. You create your device resources here. The app object calls it when the app is launched.
- A Run method that activates the CoreWindow object and starts the window event dispatcher. The app object calls it when the app's process starts.
- An Uninitialize method that cleans up the resources set up in the call to Load. The app object calls this method when the app is closed.
Create a type that implements IFrameworkViewSource. This is your view provider.
In this type, define:
- Pass an instance of the view provider to CoreApplication.Run from main.
With those basics in mind, let's look at more options you have to extend this approach.
Here are other core user interface types in the Windows Runtime that you might find helpful:
You can use these types to access your app's view, specifically, the bits that draw the contents of the app's parent window, and handle the events fired for that window. The app window's process is an application single-threaded apartment (ASTA) that is isolated and that handles all callbacks.
Your app's view is generated by the view provider for your app window, and in most cases will be implemented by a specific framework package or the system itself, so you don't need to implement it yourself. For DirectX, you need to implement a thin view provider, as discussed previously. There is a specific 1-to-1 relationship between the following components and behaviors:
- An app's view, which is represented by the CoreApplicationView type, and which defines the method(s) for updating the window.
- An ASTA, the attribution of which defines the threading behavior of the app. You cannot create instances of COM STA-attributed types on an ASTA.
- A view provider, which your app obtains from the system or which you implement.
- A parent window, which is represented by the CoreWindow type.
- Sourcing for all activation events. Both views and windows have separate activation events.
In summary, the app object provides a view provider factory. It creates a view provider and instantiates a parent window for the app. The view provider defines the app's view for the parent window of the app. Now, let's discuss the specifics of the view and the parent window.
CoreApplicationView represents the current app view. The app singleton creates the app view during initialization, but the view remains dormant until it is activated. You can get the CoreWindow that displays the view by accessing the CoreApplicationView.CoreWindow property on it, and you can handle activation and deactivation events for the view by registering delegates with the CoreApplicationView.Activated event.
The parent window, which is a CoreWindow instance, is created and passed to the view provider when the app object initializes. If the app has a window to display, it displays it; otherwise, it simply initializes the view.
CoreWindow provides a number of events specific to input and basic window behaviors. You can handle these events by registering your own delegates with them.
You can determine the threading behavior of event dispatching for a window with the CoreDispatcher type. On this type, there's one particularly important method: the CoreDispatcher.ProcessEvents method, which starts window event processing. Calling this method with the wrong option for your app can lead to all sorts of unexpected event processing behaviors.
|CoreProcessEventsOption.ProcessOneAndAllPending||Dispatch all currently available events in the queue. If no events are pending, wait for the next new event.|
|CoreProcessEventsOption.ProcessOneIfPresent||Dispatch one event if it is pending in the queue. If no events are pending, don't wait for a new event to be raised but instead return immediately.|
|CoreProcessEventsOption.ProcessUntilQuit||Wait for new events and dispatch all available events. Continue this behavior until the window is closed or the application calls the Close method on the CoreWindow instance.|
|CoreProcessEventsOption.ProcessAllIfPresent||Dispatch all currently available events in the queue. If no events are pending, return immediately.|
Windows Store apps using DirectX should use the CoreProcessEventsOption.ProcessAllIfPresent option to prevent blocking behaviors that might interrupt graphics updates.