c++ listview自绘例子

By admin at 2018-02-09 • 0人收藏 • 1835人看过
//-------------------------------------------------------------------// 名称: tabCtrlMainProc// 类型: LRESULT// 限定符: CALLBACK//// 描述: 用于响应控件TabCtrl - Main的消息//-------------------------------------------------------------------LRESULT CALLBACK tabCtrlMainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{    if (uMsg == WM_NOTIFY)
    {
        LPNMHDR nmh = (LPNMHDR) lParam;        
        if (nmh->hwndFrom == hListViewPersons && nmh->code == NM_CUSTOMDRAW) // 是来自listViewPersons, 并且消息为NM_CUSTOMDRAW        {
            LPNMLVCUSTOMDRAW lpNMCustomDraw = reinterpret_cast<LPNMLVCUSTOMDRAW>(lParam);            
            int nResult = CDRF_DODEFAULT; // 默认由系统绘制, 除非下面进行了自定义绘制            
            // 如果处于步骤 - CDDS_PREPAINT, 则告诉系统需要自绘每一行            if (CDDS_PREPAINT == lpNMCustomDraw->nmcd.dwDrawStage)
            {
                nResult = CDRF_NOTIFYITEMDRAW;
            }            else if (CDDS_ITEMPREPAINT == lpNMCustomDraw->nmcd.dwDrawStage)
            {                // 这里获得了当前行的信息, 而需要获得当前列的消息.                nResult = CDRF_NOTIFYSUBITEMDRAW;
            }            else if ((CDDS_ITEMPREPAINT | CDDS_SUBITEM) == lpNMCustomDraw->nmcd.dwDrawStage)
            {                // 默认由自己绘制                nResult = CDRF_SKIPDEFAULT;                const DWORD dwStyle = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_END_ELLIPSIS;

                BOOL bCtrlFocused = GetFocus() == hListViewPersons; // 控件是否有焦点                COLORREF clrTextColor = RGB(0, 0, 0); // 保存文本颜色, 默认为黑色                HDC hdc = lpNMCustomDraw->nmcd.hdc; // 获得绘制句柄                int nItem = (int)lpNMCustomDraw->nmcd.dwItemSpec; // 获得当前行                int nSubItem = lpNMCustomDraw->iSubItem; // 获得当前列                
                // 获得当前行状态                // p.s 本来可以用lpNMCustomDraw->nmcd.uItemState判断的, 但是msdn上说CDIS_SELECTED工作不正常..                BOOL bItemSelected = ListView_GetItemState(hListViewPersons, nItem, LVIS_SELECTED);
                BOOL bItemFocused = ListView_GetItemState(hListViewPersons, nItem, LVIS_FOCUSED);                // 获得列绘制区域                RECT subItemRect;
                ListView_GetSubItemRect(hListViewPersons, nItem, nSubItem, LVIR_BOUNDS, &subItemRect);                // 根据项目的状态绘制背景色                if (bItemSelected)
                {    // 被选中                    if (bCtrlFocused)
                    {    // 有焦点                        FillRect(hdc, &subItemRect, CreateSolidBrush(RGB(185, 213, 241)));                        if (bItemFocused)
                        {    // 焦点所在项                            RECT itemRect;
                            ListView_GetItemRect(hListViewPersons, nItem, &itemRect, LVIR_BOUNDS);
                            FrameRect(hdc, &itemRect, CreateSolidBrush(RGB(51, 153, 255)));
                        }
                    }                    else // 无焦点                        FillRect(hdc, &subItemRect, CreateSolidBrush(RGB(240, 240, 240)));
                }                // 获得内容                LPTSTR szText = new TCHAR[MAX_STRING];
                ListView_GetItemText(hListViewPersons, nItem, nSubItem, szText, MAX_STRING);                
                // 判断列                switch (nSubItem)
                {                case 0: // 第1列 - "名称"                    {                        // 获得图标绘制区域                        RECT iconRect;
                        ListView_GetSubItemRect(hListViewPersons, nItem, nSubItem, LVIR_ICON, &iconRect);
                        OffsetRect(&iconRect, 0, 1);                        // 画图标                        HDC memDC = CreateCompatibleDC(hdc);                        if (bItemSelected)
                        {    // 被选中                            if (bCtrlFocused) // 有焦点                                SelectObject(memDC, (HGDIOBJ) LoadBitmap(AppInfo.hInstance, MAKEINTRESOURCE(IDB_USER_SELECT_FOCUS)));                            else // 无焦点                                SelectObject(memDC, (HGDIOBJ) LoadBitmap(AppInfo.hInstance, MAKEINTRESOURCE(IDB_USER_SELECT_NOTFOCUS)));
                        }                        else
                        {
                            SelectObject(memDC, (HGDIOBJ) LoadBitmap(AppInfo.hInstance, MAKEINTRESOURCE(IDB_USER_NORMAL)));
                        }
                        BitBlt(hdc, iconRect.left, iconRect.top, 16, 16, memDC, 0, 0, SRCCOPY);
                        DeleteDC(memDC);                        // 获得文字绘制区                        RECT fontRect;
                        ListView_GetSubItemRect(hListViewPersons, nItem, nSubItem, LVIR_LABEL, &fontRect);                        // 画字                        OffsetRect(&fontRect, 18, 0);
                        DrawText(hdc, szText, _tcslen(szText), &fontRect, dwStyle);                        break;
                    }                case 2: // 第3列 - "得分"                    {                        // 调整绘制区                        subItemRect.left += 2; subItemRect.right -= 2; subItemRect.top += 2; subItemRect.bottom -= 2;                        // 填充背景为灰色                        FillRect(hdc, &subItemRect, CreateSolidBrush(RGB(240, 240, 240)));                        
                        int nScore = _ttoi(szText); // 获得分数                        if (nScore != 0) // 0分就不绘制了                        {                            // 计算绘制区域                            RECT scoreRect = subItemRect;
                            scoreRect.right = scoreRect.left + (int)((scoreRect.right - scoreRect.left) * ((float) nScore / 400.0));
                            FillRect(hdc, &scoreRect, CreateSolidBrush(RGB(189, 189, 189))); // 填充区域                        }                        // 画字                        OffsetRect(&subItemRect, 2, 0);
                        DrawText(hdc, szText, _tcslen(szText), &subItemRect, dwStyle);                        break;
                    }                case 4: // 第5列 - "状态"                    if (!_tcscmp(szText, _T("已评测")))
                        clrTextColor = RGB(0, 120, 0); // 将颜色设为绿色                    else if (!_tcscmp(szText, _T("未评测")))
                        clrTextColor = RGB(255, 69, 0); // 橘红色                    else if (!_tcscmp(szText, _T("正在评测")))
                        clrTextColor = RGB(0, 0, 255); // 蓝色                    else if (!_tcscmp(szText, _T("等待评测")))
                        clrTextColor = RGB(139, 0, 245); // 紫色
                default:                    // 设置颜色 & 画字(这就是所谓的统一文字绘制)                    SetTextColor(hdc, clrTextColor);
                    OffsetRect(&subItemRect, 5, 0);
                    DrawText(hdc, szText, _tcslen(szText), &subItemRect, dwStyle);
                }                // 释放                delete[] szText;
            }            return nResult;
        } // if    }    // 其他消息都还给Windows    return CallWindowProc(Control.tabCtrlMain.oldProc, hWnd, uMsg, wParam, lParam);
}

转自:http://www.phpfans.net/ask/MTM0NTA3OQ.html

3 个回复 | 最后更新于 2018-10-10
2018-04-28   #1

于是aar中应该这样写:

import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=945;bottom=474)
winform.add(
流程编辑框={cls="listview";left=0;top=0;right=946;bottom=350;edge=1;font=LOGFONT(name='FontAwesome';h=-19);fullRow=1;vscroll=1;z=1}
)
/*}}*/

import win.fontAwesome;
import win.graphics;
import win.imageList;
var imagelist = win.imageList(1,34);
winform.流程编辑框.setImageList( imagelist,1/*_LVSIL_SMALL*/ );
winform.流程编辑框.insertColumn("",30,,0x2/*_LVCFMT_CENTER*/) 
winform.流程编辑框.insertColumn("中断",80,,0x2/*_LVCFMT_CENTER*/) 
winform.流程编辑框.insertColumn("备注",300,,0x0/*_LVCFMT_LEFT*/) 
winform.流程编辑框.insertColumn("功能",100,,0x0/*_LVCFMT_LEFT*/)
winform.流程编辑框.insertColumn("参数",300,,0x0/*_LVCFMT_LEFT*/)
winform.流程编辑框.insertColumn("",80,,0x2/*_LVCFMT_CENTER*/)
//自适应列宽度 
winform.流程编辑框.adjust = function(cx,cy){
    winform.流程编辑框.fillParent(5/*列序号*/);
}


winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"X轴前进到对准位置";"直线运动";'{["速度"]=1000;["模式"]="相对运动";["距离"]="2380";["是否等待"]="否";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00d';'\uF05e';"Z轴缓慢前进";"直线运动";'{["速度"]=300;["模式"]="连续运动";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"连续读传感器值直到大于0.8";"调用子程序";'{["调用子程序"]="连续读传感器";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"对准操作";"调用子程序";'{["调用子程序"]="回字形对准算法";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"X轴前进到对准位置";"直线运动";'{["速度"]=1000;["模式"]="相对运动";["距离"]="2380";["是否等待"]="否";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00d';'\uF05e';"Z轴缓慢前进";"直线运动";'{["速度"]=300;["模式"]="连续运动";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"连续读传感器值直到大于0.8";"调用子程序";'{["调用子程序"]="连续读传感器";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"对准操作";"调用子程序";'{["调用子程序"]="回字形对准算法";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"X轴前进到对准位置";"直线运动";'{["速度"]=1000;["模式"]="相对运动";["距离"]="2380";["是否等待"]="否";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00d';'\uF05e';"Z轴缓慢前进";"直线运动";'{["速度"]=300;["模式"]="连续运动";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"连续读传感器值直到大于0.8";"调用子程序";'{["调用子程序"]="连续读传感器";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"对准操作";"调用子程序";'{["调用子程序"]="回字形对准算法";["是否等待"]="是";}';'\uF01a'} 
} )

//自绘
winform.流程编辑框.onnotify = function(id,code,ptr){ 
        if( code == 0xFFFFFFF4/*_NM_CUSTOMDRAW*/ ){
                var lvcd = winform.流程编辑框.getNotifyCustomDraw(code,ptr);
                console.log( "------------------------" )
                console.log( lvcd.nmcd.dwDrawStage )
                if( lvcd.nmcd.dwDrawStage == 0x10001/*_CDDS_ITEMPREPAINT*/){
                        return 0x20/*_CDRF_NOTIFYSUBITEMDRAW*/
                }
                elseif( lvcd.nmcd.dwDrawStage == 1/*_CDDS_PREPAINT*/ ){
                        return 0x20/*_CDRF_NOTIFYITEMDRAW*/;
                }
                elseif( lvcd.nmcd.dwDrawStage == ( 0x10001/*_CDDS_ITEMPREPAINT*/ | 0x20000/*_CDDS_SUBITEM*/) ){ 
                        //注意这里 iSubItem 的索引自0开始( 其他函数通常自1开始 )
                        
                    var cvs = win.graphics.canvas(); // 创建一个画布
                    cvs.fromHDC(lvcd.nmcd.hdc); // 传入 hDC
                    var nItem = lvcd.nmcd.dwItemSpec+1;//行加1
                    var nSubItem = lvcd.iSubItem;
                    
                    var rc = owner.getItemRect(nItem,nSubItem);
                    cvs.pen.color = 0xebebeb; // 定义画笔的颜色
                    cvs.drawEdge(rc);
                    lvcd.update()
                        
                    cvs.destroy();
                    return 0/*_CDRF_DODEFAULT*/
                }
        }
}


winform.show() 
win.loopMessage();

blob.png

最后一列边框没显示出来.(⊙o⊙)…

试了几种办法都不行, 暂时先这样用了,对我来说不影响,后续有其他方案在修改更新.

2018-04-28   #2

listview中自绘进度条:

QQ截图20180428234726.jpg

import win.ui;
/*DSG{{*/
var winform = win.form(text="listview中添加进度条演示";right=945;bottom=474)
winform.add(
button={cls="button";text="(点击这里随机更新一次第二行的进度值)";left=0;top=392;right=944;bottom=472;font=LOGFONT(h=-21);z=2};
流程编辑框={cls="listview";left=0;top=0;right=946;bottom=384;edge=1;font=LOGFONT(name='FontAwesome';h=-19);fullRow=1;vscroll=1;z=1}
)
/*}}*/

import win.fontAwesome;
import win.graphics;
import win.imageList;
var imagelist = win.imageList(5,34);
winform.流程编辑框.setImageList( imagelist,1/*_LVSIL_SMALL*/ );
winform.流程编辑框.insertColumn("",30,,0x2/*_LVCFMT_CENTER*/) 
winform.流程编辑框.insertColumn("中断",80,,0x2/*_LVCFMT_CENTER*/) 
winform.流程编辑框.insertColumn("备注",300,,0x0/*_LVCFMT_LEFT*/) 
winform.流程编辑框.insertColumn("功能",100,,0x0/*_LVCFMT_LEFT*/)
winform.流程编辑框.insertColumn("参数",300,,0x0/*_LVCFMT_LEFT*/)
winform.流程编辑框.insertColumn("",30,,0x2/*_LVCFMT_CENTER*/)
winform.流程编辑框.insertColumn("",1,,0x2/*_LVCFMT_CENTER*/)
//自适应列宽度 
winform.流程编辑框.adjust = function(cx,cy){
    winform.流程编辑框.fillParent(5/*列序号*/);
}


winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';30;"直线运动";'{["速度"]=1000;["模式"]="相对运动";["距离"]="2380";["是否等待"]="否";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00d';'\uF05e';100;"直线运动";'{["速度"]=300;["模式"]="连续运动";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';200;"调用子程序";'{["调用子程序"]="连续读传感器";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';50;"调用子程序";'{["调用子程序"]="回字形对准算法";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';150;"直线运动";'{["速度"]=1000;["模式"]="相对运动";["距离"]="2380";["是否等待"]="否";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';120;"直线运动";'{["速度"]=1000;["模式"]="相对运动";["距离"]="2380";["是否等待"]="否";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00d';'\uF05e';10;"直线运动";'{["速度"]=300;["模式"]="连续运动";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';70;"调用子程序";'{["调用子程序"]="连续读传感器";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';260;"调用子程序";'{["调用子程序"]="回字形对准算法";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';130;"直线运动";'{["速度"]=1000;["模式"]="相对运动";["距离"]="2380";["是否等待"]="否";}';'\uF01a'} 
} )

//自绘
winform.流程编辑框.onnotify = function(id,code,ptr){ 
        if( code == 0xFFFFFFF4/*_NM_CUSTOMDRAW*/ ){
                var lvcd = winform.流程编辑框.getNotifyCustomDraw(code,ptr);
                if( lvcd.nmcd.dwDrawStage == 0x10001/*_CDDS_ITEMPREPAINT*/)
                        return 0x20/*_CDRF_NOTIFYSUBITEMDRAW*/
                elseif( lvcd.nmcd.dwDrawStage == 1/*_CDDS_PREPAINT*/ ){
                        return 0x20/*_CDRF_NOTIFYITEMDRAW*/;
                }
                elseif( lvcd.nmcd.dwDrawStage == ( 0x10001/*_CDDS_ITEMPREPAINT*/ | 0x20000/*_CDDS_SUBITEM*/) ){ 
                        //注意这里 iSubItem 的索引自0开始( 其他函数通常自1开始 )
                        
                        var cvs = win.graphics.canvas(); // 创建一个画布
                    cvs.fromHDC(lvcd.nmcd.hdc); // 传入 hDC
                    var nItem = lvcd.nmcd.dwItemSpec+1;
                    var nSubItem = lvcd.iSubItem;
                    var rc = owner.getItemRect(nItem,nSubItem);
                    if(nSubItem == 3){
                    	
                    	var RetRc = ::RECT(rc.left+1,rc.top+6,rc.right-tonumber(owner.getItemText(nItem,3)),rc.bottom-6);
                    	cvs.brush.color = 0x00ff00;
                    	cvs.fillRect(RetRc)
                    		
                    }
                    cvs.pen.color = 0xebebeb; // 定义画笔的颜色
                    cvs.drawEdge(rc);
                        
                    lvcd.update()
                    cvs.destroy();
                    
                    return 0/*_CDRF_DODEFAULT*/
                }
        }
}
//演示更新进度
winform.button.oncommand = function(id,event){
	winform.流程编辑框.setItemText(tostring(math.random(10,280)),2,3);
}

winform.show() 
win.loopMessage();


2018-10-24   #3
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=945;bottom=474)
winform.add(
流程编辑框={cls="listview";left=0;top=0;right=946;bottom=350;edge=1;font=LOGFONT(name='FontAwesome';h=-19);fullRow=1;z=1}
)
/*}}*/

import win.fontAwesome;
import win.graphics;
import win.imageList;
var imagelist = win.imageList(5,34);
winform.流程编辑框.setImageList( imagelist,1/*_LVSIL_SMALL*/ );
winform.流程编辑框.insertColumn("",30,,0x2/*_LVCFMT_CENTER*/) 
winform.流程编辑框.insertColumn("中断",80,,0x2/*_LVCFMT_CENTER*/) 
winform.流程编辑框.insertColumn("备注",300,,0x0/*_LVCFMT_LEFT*/) 
winform.流程编辑框.insertColumn("功能",100,,0x0/*_LVCFMT_LEFT*/)
winform.流程编辑框.insertColumn("参数",300,,0x0/*_LVCFMT_LEFT*/)
winform.流程编辑框.insertColumn("",30,,0x2/*_LVCFMT_CENTER*/)
//自适应列宽度 
winform.流程编辑框.adjust = function(cx,cy){
    winform.流程编辑框.fillParent(5/*列序号*/);
}
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"X轴前进到对准位置";"直线运动";'{["速度"]=1000;["模式"]="相对运动";["距离"]="2380";["是否等待"]="否";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00d';'\uF05e';"Z轴缓慢前进";"直线运动";'{["速度"]=300;["模式"]="连续运动";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"连续读传感器值直到大于0.8";"调用子程序";'{["调用子程序"]="连续读传感器";["是否等待"]="是";}';'\uF01a'} 
} )
winform.流程编辑框.addItem( { 
        text={'\uF00c';'\uF1db';"对准操作";"调用子程序";'{["调用子程序"]="回字形对准算法";["是否等待"]="是";}';'\uF01a'} 
} )


//自绘
winform.流程编辑框.onnotify = function(id,code,ptr){ 
        if( code == 0xFFFFFFF4/*_NM_CUSTOMDRAW*/ ){
                var lvcd = winform.流程编辑框.getNotifyCustomDraw(code,ptr);
                console.log( "------------------------" )
                console.log( lvcd.nmcd.dwDrawStage )
                if( lvcd.nmcd.dwDrawStage == 0x10001/*_CDDS_ITEMPREPAINT*/){
                        return 0x20/*_CDRF_NOTIFYSUBITEMDRAW*/
                }
                elseif( lvcd.nmcd.dwDrawStage == 1/*_CDDS_PREPAINT*/ ){
                        return 0x20/*_CDRF_NOTIFYITEMDRAW*/;
                }
                elseif( lvcd.nmcd.dwDrawStage == ( 0x10001/*_CDDS_ITEMPREPAINT*/ | 0x20000/*_CDDS_SUBITEM*/) ){ 
                        //注意这里 iSubItem 的索引自0开始( 其他函数通常自1开始 )
                        
                    var cvs = win.graphics.canvas(); // 创建一个画布
                    cvs.fromHDC(lvcd.nmcd.hdc); // 传入 hDC
                    var nItem = lvcd.nmcd.dwItemSpec+1;
                    var nSubItem = lvcd.iSubItem;
                    
                    var rc = owner.getItemRect(nItem,nSubItem);
                    cvs.pen.color = 0xebebeb; // 定义画笔的颜色
                    cvs.drawEdge(rc);
                    lvcd.update()
                        
                    cvs.destroy();
                    return 0/*_CDRF_DODEFAULT*/
                }
        }



winform.show() 
win.loopMessage();

用下面的代码替换画edge可以实现画任意颜色

cvs.pen.color = 0xff0000//0xebebeb; // 定义画笔的颜色
                    //cvs.drawEdge(rc);
                    //左上到右上
                    cvs.moveTo(rc.left, rc.top); // 落笔
                cvs.lineTo(rc.right, rc.top); // 提笔
                    //右上到右下
                    cvs.moveTo(rc.right, rc.top); // 落笔
                cvs.lineTo(rc.right, rc.bottom); // 提笔
                    //右下到左下
                    cvs.moveTo(rc.right, rc.bottom); // 落笔
                cvs.lineTo(rc.left, rc.bottom); // 提笔
                //左下到左上
                    cvs.moveTo(rc.left, rc.bottom); // 落笔
                cvs.lineTo(rc.left, rc.top); // 提笔



登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...