探讨《如何在MFC设计超链接控件类》

来源:互联网 发布:淘宝商家贴吧 编辑:程序博客网 时间:2024/05/29 14:44

《如何在MFC设计超链接控件类》

原文传送门:http://blog.kingsamchen.com/archives/517#comment-1912

运行之后一切都完美,只有一个问题,当弹出IE窗口挡住了Label之后,在切换会原来的程序,鼠标移动到Label上时不会再次显示手型鼠标指针。查询资料跟踪程序后发现:

void CLinkLabel::OnMouseMove(UINT nFlags, CPoint point){    // TODO: 在此添加消息处理程序代码和/或调用默认值    if (m_bTrack)    {        if (m_bMouseOn)        {            CRect rec;            GetClientRect(&rec);            // 鼠标离开了LinkLabel            if (!rec.PtInRect(point))            {                m_bMouseOn = FALSE;                ::ReleaseCapture();            }        }        // 鼠标进入LabelLink        else        {            m_bMouseOn = TRUE;            SetCapture();            // #define IDC_HAND  MAKEINTRESOURCE(32649)            // 直接引用IDC_HAND需要添加头文件            ::SetCursor(AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649)));            Invalidate(TRUE);        }    }    CStatic::OnMouseMove(nFlags, point);}

如果我鼠标悬停在CLinkLabel,如果突然有窗口阻挡了CLinkLabel所在的主窗口,鼠标再次移动到CLinkLabel,因为之前主窗口丢失了焦点,手型鼠标被重置成焦点窗口默认样式,SetCapture(手型)已经自动失效

鼠标不在CLinkLabel,不会发生CLinkLabel::OnMouseMove,鼠标在CLinkLabel,则 rec.PtInRect(point)==TRUE,不会进入进入if (!rec.PtInRect(point))执行m_bMouseOn = FALSE

,因此m_bMouseOn一直是等于TRUE,CLinkLabel认为鼠标一直在控件上,不会再次::SetCursor()。

通过论坛朋友帮助和网上查询咨询找到了两种解决方案:

1、在WM_SETCURSOR消息中执行SetCursor(论坛提供)

2、在PreTranslateMessage中截获WM_MOUSEMOVE,添加一个监视,如果鼠标离开则产生WM_MOUSELEAVE事件,然后处理之。传送门

PreTranslateMessage(MSG* pMsg){// TODO: 在此添加专用代码和/或调用基类// m_ToolTip.RelayEvent(pMsg);switch( pMsg->message ){case WM_MOUSEMOVE://为了让系统产生上面的WM_MOUSELEAVE消息,你必需做如下处理TRACKMOUSEEVENT trmouse;trmouse.cbSize = sizeof(TRACKMOUSEEVENT);trmouse.dwFlags = TME_LEAVE;trmouse.dwHoverTime = 400;trmouse.hwndTrack = pMsg->hwnd;if(!_TrackMouseEvent(&trmouse))return FALSE;break;}return CLinkLabel::PreTranslateMessage(pMsg);}
我选择了第一种,简单直接。第二种可以借鉴。


原创粉丝点击