博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MFC 鼠标去留
阅读量:4983 次
发布时间:2019-06-12

本文共 2150 字,大约阅读时间需要 7 分钟。

题目不醒目,特解

  win32编程中,有两个消息比较特别,WM_MOUSEHOVER和WM_MOUSELEAVE。系统不会想应用程序发送这两个消息,MSDN中规定要用到TrackMouseEvent方法来向程序投递这两个消息。

去留分析

  去WM_MOUSELEAVE,留WM_MOUSEHOVER。打个比方,调用TrackMouseEvent就向在消息队列中设置了一个哨兵,当发现WM_MOUSEHOVER或者WM_MOUSELEAVE的时候,就将其放入消息队列,而此时如果这个消息是WM_MOUSELEAVE这个哨兵会消失,而如果这个消息是WM_MOUSEHOVER,这个哨兵会暂留,但是他只能检测WM_MOUSELEAVE。

  (参看MSDN中的原话,对于WM_MOUSEHOVER,“Hover tracking stops when this message is generated. The application must call TrackMouseEvent again if it requires further tracking of mouse hover behavior.”;而对于WM_MOUSELEAVE,“All tracking requested by TrackMouseEvent is canceled when this message is generated.”)。因此可以利用这个规定特点,来设计判断“鼠标去留”的方法。

  按照以往的习惯,应该在WM_MOUSEMOVE的处理函数当中放置哨兵TrackMouseEvent,在类中添加BOOL变量m_bTrack标志,用来判断是否要进行放置哨兵。

  为了方便理解,画成如下图:

如此这般,可以用悬停标志来决定处理过程。在鼠标悬停和鼠标离去处理函数中,做想做的事情。

具体实现

  1. 添加WM_MOUSEMOVE,WM_MOUSEHOVER,WM_MOUSELEAVE消息的处理函数。VS2008可以在类的属性当中自动添加,但是VC6中,WM_MOUSEHOVER,WM_MOUSELEAVE需要手动添加。
  2. 在WM_MOUSEMOVE处理函数中,放置哨兵。
    if(m_bTrack)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize = 
    sizeof(TRACKMOUSEEVENT);
        tme.dwFlags = TME_HOVER | TME_LEAVE;
        tme.hwndTrack = 
    this->GetSafeHwnd();
        tme.dwHoverTime = HOVER_DEFAULT;  
    //
    悬停多少时间之后产生WM_MOUSEHOVER
        ::_TrackMouseEvent(&tme);
        m_bTrack = 
    false;
    }
  3. 在WM_MOUSELEAVE处理函数中,因为TRACKMOUSEEVENT完全作废,所以需要允许追踪鼠标;并且更新Hover标志变量。
    m_bHover = 
    false;
    m_bTrack = 
    true;
  4. 在WM_MOUSEHOVER处理函数中,更新Hover标志变量。
    m_bHover = 
    true;
     

面是详细的代码,是核心代码,没有实现什么功能,可以自行添加。

void CDLEdit::OnMouseHover(UINT nFlags, CPoint point)
{
    
//
 TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bHover = 
true;
    CEdit::OnMouseHover(nFlags, point);
}
void CDLEdit::OnMouseLeave()
{
    
//
 TODO: 在此添加消息处理程序代码和/或调用默认值
    m_bHover = 
false;
    m_bTrack = 
true;
    CEdit::OnMouseLeave();
}
void CDLEdit::OnMouseMove(UINT nFlags, CPoint point)
{
    
//
 TODO: 在此添加消息处理程序代码和/或调用默认值
    
if(m_bTrack)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize = 
sizeof(TRACKMOUSEEVENT);
        tme.dwFlags = TME_HOVER | TME_LEAVE;
        tme.hwndTrack = 
this->GetSafeHwnd();
        tme.dwHoverTime = HOVER_DEFAULT;        
//
悬停多少时间之后产生WM_MOUSEHOVER
        ::_TrackMouseEvent(&tme);
        m_bTrack = 
false;
    }
    CEdit::OnMouseMove(nFlags, point);
}

 

收获与感受

鼠标去留技术不难,但是用处很广,属于技术细节,就拿QQ产品来说,很多地方都有体现。

 

捣乱小子 2012年2月4日星期六

 

 

转载于:https://www.cnblogs.com/daoluanxiaozi/archive/2012/02/04/2337561.html

你可能感兴趣的文章
一天一个设计模式:适配器模式
查看>>
第5题 查找字符串中的最长回文字符串---Manacher算法
查看>>
HDOJ 1069 Monkey and Banana 解题报告
查看>>
11锚点与图像对象
查看>>
Ios中比较两个日期之间的时间差距
查看>>
jQuery基础选择器
查看>>
寒假作业03
查看>>
P1129 [ZJOI2007]矩阵游戏
查看>>
hdu2046 骨牌铺方格
查看>>
Linux下mysql启动失败
查看>>
同心圆闪烁扩散功能
查看>>
oracle 如何恢复误删的表记录数据
查看>>
Druid连接池错误(数据库版本问题)
查看>>
console对象-转
查看>>
洛谷 4216 BZOJ 4448 [SCOI2015]情报传递
查看>>
清北学堂2018DP&图论精讲班 DP部分学习笔记
查看>>
css3 2D变换 transform
查看>>
Fastjson获取天气信息封装bean
查看>>
不同编码字符所占大小
查看>>
使用迭代器优化代码
查看>>