'How to initialize cppwinrt TimeSpan struct?

According to the master docs for cppwinrt, Migrating C++..., "The equivalent C++/WinRT source code to set the value for a Windows Runtime property calls a method with the same name as the Windows Runtime property and a parameter for the new value:

record.UserState(newValue); // Set the UserState property

But this doesn't seem to work when attempting to set the TimeSpan property of a Duration object:

TimeSpan ts = TimeSpan(6000000);
Duration duration = Duration();
duration.TimeSpan(ts);

The third line produces an intellisense error on "duration": "Call of an object of class type without appropriate operator or conversion functions to pointer-to-function type." The build error for the same line is "Term does not evaluate to a function taking 1 arguments." I should add that the constructor for Duration seems to have one argument, a TimeSpan, but that is not accepted either. How can one set the TimeSpan property of a Duration when using cppwinrt?



Solution 1:[1]

Remember, in C++/WinRT Windows::Foundation::TimeSpan is simply a typedef of std::chrono::duration, so you can use std::chrono's useful functionality.

Direct init:

Duration duration{ std::chrono::milliseconds{ 100 }, DurationType::Automatic };

Setting individually:

Duration duration{ }; duration.TimeSpan = std::chrono::milliseconds{ 100 };

Solution 2:[2]

OK, I think I can answer my own question. While it's called a "property" of Duration in the MSDN .NET docs, in this cppwinrt environment TimeSpan is not a property of Duration but rather is a data value of the Duration struct. So you don't set it using the above-described method for setting properties; you set it this way:

TimeSpan ts = TimeSpan(6000000);
Duration duration = Duration();
duration.TimeSpan = ts;

Hope that will help anyone else in a similar situation...

Solution 3:[3]

Windows::Foundation::TimeSpan is defined

using TimeSpan = std::chrono::duration<int64_t, impl::filetime_period>;

so when you have a function taking a TimeSpan, say DispatcherQueueTimer::Interval, you can simply do

timer.Interval(std::chrono::seconds{ 1 });

or

using namespace std::literals::chrono_literals; timer.Interval(1s);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ryan Shepherd
Solution 2 user3743210
Solution 3 Tom Huntington