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

Example code for use of DispatcherTime in 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 处理程序,我很乐意看到它。谢谢

在转换形式 C++/CX 时,DispatcherTimer documentation has sample code that shows how to do this in C++/CX. The C++/WinRT code would be quite similar. The 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)
{
}

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

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

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

Tick 事件注册事件处理程序也相当简单。虽然您可以命名 EventHandler class template type of the temporary, there is no reason to do so. Using uniform initialization 语法,但它变得像调用

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

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

timer.Tick(registrationtoken);

这看起来与注册码非常相似,我觉得有点遗憾。训练您的眼睛来识别其中任何一个都需要一段时间。

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

C++/WinRT 的官方(尚未维护)GitHub 存储库中有其他信息:Registering for events using a lambda. There is also official documentation in the MSDN: Events; how to author and handle them in C++/WinRT