c++ listview自绘例子
By
admin
at 2018-02-09 • 0人收藏 • 1891人看过
//-------------------------------------------------------------------// 名称: 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
listview中自绘进度条:

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();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); // 提笔
登录后方可回帖
于是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();最后一列边框没显示出来.(⊙o⊙)…
试了几种办法都不行, 暂时先这样用了,对我来说不影响,后续有其他方案在修改更新.