MFC等GUI框架是如何实现工具提示Tooltip悬停时间计算的

 mfc提供了CToolTipCtrl、CMFCToolTipCtrl等类用于控件的tooltip。一直存在一个疑问,mfc是如何获取鼠标在控件上的悬停时间的呢?按照常规的思路,当鼠标停止移动时开始计时,但是系统根本没有鼠标停止运动这个事件,或者说系统也无法得知鼠标停止运动。

在翻看vtkBalloonWidget和vtkHoverWidget的源码时,偶然发现vtk是如何计算鼠标在对象上的悬停时间的,我想mfc也是大概的思路吧。

  // Okay, define the events for this widget. Note that we look for extra events
  // (like button press) because without it the hover widget thinks nothing has changed
  // and doesn't begin retiming.
  this->CallbackMapper->SetCallbackMethod(
    vtkCommand::LeftButtonPressEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
  this->CallbackMapper->SetCallbackMethod(
    vtkCommand::MiddleButtonPressEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
  this->CallbackMapper->SetCallbackMethod(
    vtkCommand::RightButtonPressEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
  this->CallbackMapper->SetCallbackMethod(
    vtkCommand::MouseWheelForwardEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
  this->CallbackMapper->SetCallbackMethod(
    vtkCommand::MouseWheelBackwardEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
  this->CallbackMapper->SetCallbackMethod(
    vtkCommand::MouseMoveEvent, vtkWidgetEvent::Move, this, vtkHoverWidget::MoveAction);
  this->CallbackMapper->SetCallbackMethod(
    vtkCommand::TimerEvent, vtkWidgetEvent::TimedOut, this, vtkHoverWidget::HoverAction);

看上面的代码,主要有两个事件响应函数,分别是MoveAction和HoverAction。其中HoverAction就是计时器到达指定的悬停时间后,弹出信息提示文字。关键是MoveAction,鼠标点击,鼠标移动,滚轮滚动等都会调用MoveAction函数,下面是改函数的实现。

  vtkHoverWidget* self = reinterpret_cast<vtkHoverWidget*>(w);
  if (self->WidgetState == vtkHoverWidget::Timing)
  {
    self->Interactor->DestroyTimer(self->TimerId);
  }
  else // we have already timed out, on this move we begin retiming
  {
    self->WidgetState = vtkHoverWidget::Timing;
    self->SubclassEndHoverAction();
    self->InvokeEvent(vtkCommand::EndInteractionEvent, nullptr);
  }
  self->TimerId = self->Interactor->CreateRepeatingTimer(self->TimerDuration);

通过上面的代码不难发现,一旦鼠标发生移动,如果此时正在悬停计时,则停止计时,如果没有悬停计时,则开始计时,即开始记录悬停的时间。这其实是一种反向思维,既然无法知道鼠标什么时候停止移动,但是知道鼠标什么时候移动,只要移动,就停止计时,没有计时,就开始计时,从而实现计算悬停时间的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值