zoukankan      html  css  js  c++  java
  • MFC 鼠标去留

    题目不醒目,特解

      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日星期六

     

     

  • 相关阅读:
    移动端(手机端)页面自适应解决方案1(rem布局)---750设计稿
    ionic4之ion-sliders
    ionic4 新建
    Object的多种方法
    angular的Hash 模式和 HTML 5 模式
    关于滚动条
    前端笔记(1-20)
    百度图片网址
    ImageLoader_显示图片
    viewpager_轮播
  • 原文地址:https://www.cnblogs.com/daoluanxiaozi/p/2337561.html
Copyright © 2011-2022 走看看