WinRT/UWP ICoreWindow

Wie kommt man von main zu ICoreWindow und dem restlichen UWP Schnickschnack der Windows RunTime?

Nun, wenn ich schon die C Interface Projection zerlege, dann kann ich das hiermit auch gleich mal mitdokumentieren.


WinRT Programme werden ja “anders” behandelt als reguläre Win32 Prozesse. Ähnlich wie bei Services erwartet das System, dass der Prozess binnen einer bestimmten Zeit sich meldet und seine Schnittstellen zum Empfangen von “Anweisungen” bereitstellt.
Gut analysieren kann man das über die C++ DirectX UWP Projektvorlage.

In WinRT übernimmt das die Klasse CoreApplication, deren statische Methode Run eine Instanz von IFrameworkViewSource entgegen nimmt, was wiederum nur eine Factory für eine IFrameworkView Instanz ist, die mit der Methode CreateView() genau eine solche erzeugt.

CoreApplication::Run() ruft nach der Erzeugung von IFrameworkView folgende Methoden auf:

  • Initialize()
    Hier erhält man ein ICoreApplicationView wo man seine eigene Ereignisbehandlung für Events wie Activated, Suspending oder Resuming setzen kann
  • SetWindow()
    Über den ICoreWindow Parameter erhalten wir DAS Fenster, in dem die App laufen wird. Auch hier kann man diverse Event-Handler für Fensteränderungen setzen
  • Load()
    Dann sollten Einstellungen und Ressourcen geladen werden, was hier angestoßen werden sollte.
  • Run()
    Und wenn alles vorbereitet ist, darf gearbeitet werden … oder man wartet einfach auf ein Shutdown bzw. CloseWindow Event. Dazu lässt man in einer Schleife die Methode ProcessEvents() von ICoreDispatcher ausführen, welchen man von ICoreWindow über das Dispatcher Property erhalten hat.
  • Uninitialize()
    Kehrt Run zurück, wird die App üblicherweise beendet und eben hier tritt die Uninitialize() Methode in Aktion.

Was muss man also tun?

Man implementiert eine IFrameworkView Ableitung, welches die ICoreApplicationView und ICoreWindow von Initialize und SetWindow aufbewahrt und “vorbereitet”. Dann implementiert man eine IFrameworkViewSource, die die zuvor beschriebene IFrameworkView Ableitung instanziiert. In main erzeugt man seine IFrameworkViewSource Instanz und übergibt sie an CoreApplication::Run.

Klingt kompliziert … naja, ist eben COM.

Und wie macht man weiter?

Für DirectX/Direct3D gibt es ja ein schönes Beispiel. XAML ist mir aktuell echt zu anstrengend, um das nativ alles nachzubauen. Da ist man eben doch mit den fertigen Templates und den C++ Erweiterungen gut beraten, die die Generierung der nötigen Codes und Metadaten übernehmen.

Aber zum Herumspielen sei noch eines erwähnt:
Tief versteckt gibt es noch das Interface ICoreWindowInterop mit der Methode get_WindowHandle, die ein HWND zurückliefert.

Oh mein Gott! Ein HWND in jedem CoreWindow?

Tja, sieht fast so aus. Bei Nicht-Desktop Apps deaktiviert Microsoft die Implementierung in den Headern … aber wer das Interface selbst zusammenbaut und per QueryInterface auf die IID 45D64A29-A63E-4CB6-B498-5781D298CB4F wechselt, der wird auch dort mit einer HWND belohnt.

Da sag ich nur: NICE!