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


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


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

继承CListCtrl然后重绘

太麻烦了不想用这个……

NM_CUSTOMDRAW事件

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

    void CMainFrame::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

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

  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值