NX/UG二次开发—界面—Clistctrl仿UGblockUI的Treelist重绘-笔记

效果图:

1、绘制非item区域可以使用NM_CUSTOMDRAW这个消息。非item区域分为:插入行的下方和插入行的右侧两个区域。

2、对于create的clistctrl控件,在MFC对话框中正常响应NM_CUSTOMDRAW,但对于嵌入到blcokUI后,不响应。我目前的解决方案是:嵌入MFC对话框,然后从资源工具栏拖到对话框内,然后子类化控件。

3、插入行不能使用InsertItem,需要用数组记录每次插入行的信息(我定义了一个结构体,把单元格颜色信息也存取了),然后使用LVN_GETDISPINFO更新列表显示内容。插入行或者更改单元格内容后,使用SetItemCount更新显示。

4、列表控件跟随Block窗口大小变化,方案1:在blcokUI里添加定时器,定时刷新,更改控件窗口位置。方案2:子类化blockUI对话框,并重载onsize和onsizing在里面设置clistctrl控件大小。

5、双击单元格可修改内容,继承Cedit,重写一个类,clistctrl响应双击消息,并create一个edit控件,用来编辑内容。

6、相关参数,可能不是很准确。表头高度23,行高20。表头背景色RGB(240,240,240);表格奇数行背景色RGB(250,250,250),偶数行RGB(255,255,255);网格线颜色RGB(236,236,236);选中高亮色RGB(51,153,255)。

以下为绘制关键代码:

//绘制表格
void NxListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLVCUSTOMDRAW pLVCD = (LPNMLVCUSTOMDRAW)pNMHDR;

    *pResult = CDRF_DODEFAULT;

    if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )  //准备开始绘制循环
    {
        *pResult = CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT; //CDRF_NOTIFYITEMDRAW指出项或子项将进行绘制。注意:它下面的值与 CDRF_NOTIFYSUBITEMDRAW 相同。 //CDRF_NOTIFYPOSTPAINT 列表项绘制结束时发送消息
        return;
    }
    else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage ) //准备开始绘制item区域右侧非item区域
    {
        DrawRightNonItemSpace(pLVCD);
        *pResult =  CDRF_NOTIFYSUBITEMDRAW; //指出项(或子项)将进行绘制。注意,它上面的值与 CDRF_NOTIFYITEMDRAW 相同。
        return;
    } 
    else if ( (CDDS_ITEMPREPAINT | CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage ) //准备开始绘制绘制item区域
    {
        int nRow = static_cast<int>( pLVCD->nmcd.dwItemSpec );//获得子项(行数)
        int nCol = pLVCD->iSubItem;//获得子项(列数)

        if (nRow >= 0 && nCol >= 0)
        {
            //是否选中单元格
            bool bSelected = false;
            if (GetItemState(nRow, LVIS_SELECTED))
            {
                bSelected = true;
            }

            //是否list控件聚焦
            bool bFocus = false;
            CWnd *pWndFocus = GetFocus();
            if (IsChild(pWndFocus) || pWndFocus == this)
            {
                bFocus = true;
            }

            //获取单元格位置
            CRect rSubItem;            
            GetSubItemRect(nRow, nCol, LVIR_LABEL,rSubItem);
            rSubItem.NormalizeRect();

            //绘制单元格
            CDC dc;
            dc.Attach(pLVCD->nmcd.hdc);
            DrawSubItem(&dc, nRow, nCol, rSubItem, bSelected, bFocus);
            dc.Detach();            
        }

        *pResult = CDRF_SKIPDEFAULT;
        return;
    }
    else if (pLVCD ->nmcd.dwDrawStage == CDDS_POSTPAINT) //绘制循环结束, 绘制item区域下方的非item区域
    {
        DrawBottomNonItemSpace(pLVCD);
        *pResult =  CDRF_SKIPDEFAULT;
        return;
    }
    
    *pResult = CDRF_DODEFAULT;
}

 

//绘制插入的Item区域
void NxListCtrl::DrawSubItem(CDC *pDC, int nRow, int nCol, CRect &rectSubItem, bool bSelected, bool bFocus)
{
    //判断区域是否合理
    if (rectSubItem.Width() <= 0 || rectSubItem.Height() <= 0) return;

     pDC->SetBkMode(TRANSPARENT);

     int nSave = pDC->SaveDC();

    bool bParity = (nRow % 2 == 0 ? true : false);    
    if (bSelected)
    {
        if (bFocus)
        {
            CBrush selectBrush;
            selectBrush.CreateSolidBrush(RGB(51, 153, 255));
            pDC->FillRect(&rectSubItem, &selectBrush);
        }
        else
        {
            CBrush selectNoFocusBrush;
            selectNoFocusBrush.CreateSolidBrush(RGB(250, 250, 250));
            pDC->FillRect(&rectSubItem, &selectNoFocusBrush);
        }
    }
    else if (bParity)
    {
        CBrush oddBrush;
        oddBrush.CreateSolidBrush(m_itemsInfor.at(nRow).at(nCol).bkgClor);
        pDC->FillRect(&rectSubItem, &oddBrush);
    }
    else
    {
        CBrush normalBrush;
        normalBrush.CreateSolidBrush(m_itemsInfor.at(nRow).at(nCol).bkgClor);
        pDC->FillRect(&rectSubItem, &normalBrush);
    }

    // 画竖线
    CPen pen;
    pen.CreatePen(PS_SOLID, 1, RGB(236, 236, 236));
    pDC->SelectObject(&pen);
    pDC->MoveTo(rectSubItem.right - 1, rectSubItem.top);
    pDC->LineTo(rectSubItem.right - 1, rectSubItem.bottom);
    pDC->MoveTo(rectSubItem.left, rectSubItem.bottom - 1);
    pDC->LineTo(rectSubItem.right, rectSubItem.bottom - 1);
    

     pDC->RestoreDC(nSave);


    //创建字体
    CFont font;
    font.CreateFont(12, 0,  0, 0,  FW_NORMAL, FALSE, FALSE,0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,  CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("宋体"));
    pDC->SelectObject(&font);

    //设置文字颜色
    pDC->SetTextColor(m_itemsInfor.at(nRow).at(nCol).frgClor);

    //获取单元格内的字符
    CString strText;
    strText = GetItemText(nRow, nCol);    

    //重绘字体
    rectSubItem.left = rectSubItem.left + 5;
    pDC->DrawText(strText, strText.GetLength(), &rectSubItem, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_END_ELLIPSIS); //DT_CENTER  DT_RIGHT
}
 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恩·艾克斯·红

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值