CListCtrl 失去焦点仍然显示选中高亮(转)

80 篇文章 2 订阅
44 篇文章 0 订阅

CListCtrl中需要把选中的item高亮显示时只需要调用SetItemState传入LVIS_SELECTED就好。
但是这样需要把焦点设置到CListCtrl上,一旦CListCtrl失去焦点高亮就会消失。


最近工作中遇到一个需求,需要让CListCtrl在失去焦点的情况下依然显示高亮的item。
总的来说有三种方法来实现这个功能。

继承CListCtrl然后重绘

太麻烦了不想用这个……

NM_CUSTOMDRAW事件

这个是一个类似于回调的处理过程,Windows在绘制List Ctrl的某个时间点上发送这个消息,可以选择忽略所有的通知,或者处理某部分的绘制,甚至绘制整个控件。用起来比较灵活方便,我只重绘被选中的那个item就好。 参考帖子

void CHighLightDlg::OnNMCustomdrawRecQueryList(NMHDR* pNMHDR, LRESULT* pResult)
{
    NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);

    *pResult = CDRF_DODEFAULT;

    if (CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
    {
        *pResult = CDRF_NOTIFYITEMDRAW;
    }
    else if (CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
    {
        *pResult = CDRF_NOTIFYSUBITEMDRAW;
    }
    else if ((CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
    {

        COLORREF clrNewTextColor, clrNewBkColor;

        int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);

        POSITION pos = m_lstRecQueryRes.GetFirstSelectedItemPosition();
        int index = m_lstRecQueryRes.GetNextSelectedItem(pos);

        if (index == nItem)//如果要刷新的项为当前选择的项,则将文字设为白色,背景色设为蓝色
        {
            clrNewTextColor = RGB(255, 255, 255);        //Set the text to white
            clrNewBkColor = RGB(49, 106, 197);        //Set the background color to blue
        }
        else
        {
            clrNewTextColor = RGB(0, 0, 0);        //set the text black
            clrNewBkColor = RGB(255, 255, 255);    //leave the background color white
        }

        pLVCD->clrText = clrNewTextColor;
        pLVCD->clrTextBk = clrNewBkColor;

        *pResult = CDRF_DODEFAULT;
    }
}

然而!我们代码里面用的BCG的list ctrl坑爹的自己把NM_CUSTOMDRAW处理了……用不了这个方法

NM_KILLFOCUS

当控件失去焦点的时候就会发送这个消息,我们只要在这个消息的处理函数里面把需要高亮的item设置成LVIS_DROPHILITED,然后在NM_SETFOCUS的时候把状态取消就好了~

void CTestDlg::OnNMKillfocusList(NMHDR *pNMHDR, LRESULT *pResult)
{
    // TODO: 在此添加控件通知处理程序代码
    m_nSelectedItemIndex = m_List.GetSelectionMark();
    m_List.SetItemState(m_nSelectedItemIndex, LVIS_DROPHILITED, LVIS_DROPHILITED);
    *pResult = 0;
}


void CTestDlg::OnNMSetfocusList(NMHDR *pNMHDR, LRESULT *pResult)
{
    // TODO: 在此添加控件通知处理程序代码
    m_List.SetItemState(m_nSelectedItemIndex, FALSE, LVIF_STATE);
    *pResult = 0;
}

Tips

注意:1、CListCtrl的控件属性Always show selection一定要设为False,不然没效果。

2、如果有点击相应等操作,LVN_ITEMCHANGED事件有问题需要增加额外代码,建议用NM_CLICK事件

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值