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

7 篇文章 0 订阅
5 篇文章 0 订阅

《如何在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);
}
我选择了第一种,简单直接。第二种可以借鉴。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值