microsoft / cppwinrt

C++/WinRT
MIT License
1.67k stars 239 forks source link

Implementing IFrameworkView and IFrameworkViewSource as separate classes #62

Closed Zingam closed 7 years ago

Zingam commented 7 years ago

If I implement a both interfaces as in the examples. The app runs fine. When I implement them as separate classes as seen in the video Universal Windows Apps with Standard C++. The App just crashes. BTW How current is the information in the video? What I am basically trying to do is to port the DirectX basic samples to C++WinRT.

class App
    : public winrt::implements<App
    , winrt::Windows::ApplicationModel::Core::IFrameworkView
    , winrt::Windows::ApplicationModel::Core::IFrameworkViewSource>
kennykerr commented 7 years ago

C++/WinRT now provides a generalized way of implementing any set of WinRT interfaces via the implements class template. That video was recorded before we introduced this capability. At that time, it was only possible to implement a hand-picked set of interfaces.

Although the samples all implement IFrameworkViewSource and IFrameworkView in a single implementation class, you can certainly implement them as two separate classes as follows:

struct View : implements<View, IFrameworkView>
{
    void Initialize(CoreApplicationView const &)
    {
    }

    void Load(hstring_ref)
    {
    }

    void Uninitialize()
    {
    }

    void Run()
    {
        CoreWindow window = CoreWindow::GetForCurrentThread();
        window.Activate();

        CoreDispatcher dispatcher = window.Dispatcher();
        dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
    }

    void SetWindow(CoreWindow const &)
    {
    }
};

struct Source : implements<Source, IFrameworkViewSource>
{
    IFrameworkView CreateView()
    {
        return make<View>();
    }
};

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    CoreApplication::Run(make<Source>());
}
Zingam commented 7 years ago

Thanx, Kenny. I first started to get familiar with C++WinRT after I read the white paper by Stephen Hammond on the Xbox developer site. When the XDK with the headers were available I converted (to my best understanding at the time) the default template project for Xbox but it would crash. I believe in the core lib with no useful stack trace. I tried to debug it but to no avail. Then I decided to convert the Direct3D 11 project template for UWP. As it is more complex I had some more issues with it but I managed to compile and run it and it would also crash in the same manner. Then I moved to the sample projects and started a UWP project from scratch by doing the appropriate changes.

I am pretty sure I came up with exactly the same code as above. The only difference is that I didn't use make<T>();

    return View()

instead of

    return make<View>();

and

    CoreApplication::Run(Source());

instead of

    CoreApplication::Run(make<Source>());

What is the purpose of make()? I mean it is obvious in the sample above but is there any documentation anywhere about these additional templates like winrt::implements<>, winrt::make<>(), etc.

BTW. I've just seen on the other thread the C++WinRT Game template project. I'll try that when I get back to my development machine next week. I use Visual Studio 2015 Update 3 because that's what we use for our production code but I'll try VS2017 at least for the samples as you suggest.

EDIT: I guess one needs to read this article: C++/WinRT: Working with Implementations as a starter.

kennykerr commented 7 years ago

The make function template is essential. The View and Source classes above are just regular C++ classes that happen to implement various COM interfaces. For those objects to outlive the local stack frame they must be heap-allocated and that’s what the make function template does for you. It creates the object on the heap and returns an object representing one reference to that object. This resulting object can then be used, copied, or moved and it will take care of the lifetime of the heap-allocated object automatically. If you happen to watch some of my earliest demos you might notice that I do it without a "make" function but that didn't end up working too well.

Chuck Walbourn’s Direct3D project templates are a good place to start if you’re coming from a DirectX background. I would however suggest that you move the C++/WinRT includes into the precompiled header.

Yes, I’ve started a series of short articles explaining some of these topics. It covers implementations and talks about this in a bit more detail.

Zingam commented 7 years ago

Would you, please, create a new section on the web site and link these articles as a TOC. It would be easier for newcomers to locate them.