在c ++ / winrt中使用DispatcherTime的示例代码?

时间:2018-04-21 20:19:00

标签: c++-winrt

有没有人知道用于说明在C ++ / winrt中使用DispatcherTimer创建周期性计时器的示例代码?文档中的示例是托管C ++,我无法成功转换它们以用于c ++ / winrt。谢谢... [更新:为响应大众需求,让我展示自己尝试翻译C ++ / CX代码。以下是DispatcherTimer文档中的示例代码:

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 ...}

//现在,转换为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);}

所以,如果有人有办法在cppwinrt中实现这个tick处理程序,我很乐意看到它。感谢。

2 个答案:

答案 0 :(得分:1)

DispatcherTimer文档包含示例代码,说明如何在C ++ / CX中执行此操作。 C ++ / WinRT代码非常相似。在转换C ++ / CX时,general-purpose C++/WinRT documentation应该有助于解决任何小问题。

如果您已尝试过,但仍存在文档缺口,请告知我们。

(编辑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)
{
}

答案 1 :(得分:1)

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

DispatcherTimer的{​​{3}}事件处理程序会收到IInspectable个参数。签名是:

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

使用Tick事件注册事件处理程序也非常简单。虽然您可以命名临时的Tick类模板类型,但没有理由这样做。使用EventHandler语法,就像调用

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

取消注册事件处理程序的代码如下所示:

timer.Tick(registrationtoken);

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

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

C ++ / WinRT的官方(但未维护)GitHub存储库中还有其他信息:uniform initialization。 MSDN中还有官方文档:Registering for events using a lambda