0

Does anyone know of example code to illustrate the creation of a periodic timer, say with DispatcherTimer, in c++/winrt? The examples in the docs are managed C++ and I have not been able to successfully convert them for use with c++/winrt. Thanks... [Update: in response to popular demand, let me show my own attempts to translate the C++/CX code. Here is the sample code from the DispatcherTimer documentation:

void MainPage::StartTimerAndRegisterHandler() {
auto timer = ref new Windows::UI::Xaml::DispatcherTimer();
TimeSpan ts;
ts.Duration = 500;
timer->Interval = ts;
timer->Start();
auto registrationtoken = timer->Tick += ref new EventHandler<Object^>(this, &MainPage::OnTick);}

void MainPage::OnTick(Object^ sender, Object^ e) {
// do something on each tick here ...}

//Now, for translating to C++/winrt:

void MainPage::StartTimerAndRegisterHandler() {
auto timer = Windows::UI::Xaml::DispatcherTimer(); //that's easy enough
TimeSpan ts = TimeSpan(500);    //This can be done in one step, I think
timer.Interval(ts); //And this is easy
timer.Start();  //Seems right
//The following line is the tricky bit.
//I change timer->Tick to timer.Tick
//The following += is described as a way to add a delegate; I drop the ref new
//But Object is not going to work here; it needs to be replaced 
//by, I think, IInspectable const & sender, and probably a lambda
//would replace the OnTick, there is a lot of mystery on this line
//and there hardly seems any point in displaying my several attempts to get past it:

auto registrationtoken = timer.Tick += ref new EventHandler<Object^>(this, &MainPage::OnTick);}

So, if anyone has a way to implement that tick handler in cppwinrt I would love to see it. Thanks.

4

2 回答 2

3

您似乎在注册自定义活动时遇到了困难。虽然 C++/CX 已经使用紧凑的语法,但 C++/WinRT 进一步减少了设置事件处理程序所需的代码量。

Tick事件处理程序接收一个参数DispatcherTimer。签名是:IInspectable

void MainPage::OnTick(IInspectable const& sender, IInspectable const& event)

使用事件注册事件处理程序Tick也相当简单。虽然您可以命名临时的EventHandler类模板类型,但没有理由这样做。使用统一的初始化语法,变得像调用一样简单

auto registrationtoken = timer.Tick({ this, &MainPage::OnTick });

注销事件处理程序的代码如下所示:

timer.Tick(registrationtoken);

这看起来与注册码非常相似,我觉得有点不幸。您的眼睛需要一段时间才能接受训练以识别其中任何一个。

请注意,虽然您可以将未命名的 lambda 与自定义事件处理程序一起使用,但不鼓励这样做,以免引入循环引用。

C++/WinRT 的官方(尚未维护的)GitHub 存储库中有其他信息:使用 lambda 注册事件。MSDN中也有官方文档:Events;如何在 C++/WinRT 中创作和处理它们

于 2018-04-23T08:32:05.117 回答
2

DispatcherTimer文档中的示例代码展示了如何在 C++/CX 中执行此操作。C++/WinRT 代码将非常相似。在转换 C++/CX 形式时,通用 C++/WinRT 文档应该有助于解决任何小问题。

如果您已经尝试过,但仍然存在文档空白,请告诉我们。

(编辑 1)

看起来你已经连接了大部分,但是被事件处理程序绊倒了。我同意这不是第一次 100% 直观,我意识到我们关于这个主题的文档可能会更彻底一些,所以这就是我的看法。请注意,这使用了预览版 SDK 中已有的所有最新语法 (get_weak)。

void MainPage::StartTimerAndRegisterHandler()
{
  auto timer = Windows::UI::Xaml::DispatcherTimer();
  time.Interval(std::chrono::milliseconds{ 500 });
  timer.Start();
  auto token = timer.Tick([weak = get_weak()](auto const& sender, auto const& args)
  {
    auto self = ref.get();
    if (self)
    {
      self->OnTick(sender, args);
    }
  });
}

void MainPage::OnTick(IInspectable const& sender, IInspectable const& args)
{
}
于 2018-04-22T08:52:49.530 回答