SubItem Selection in List Control改进版
来源:互联网 发布:js获取当天0点时间戳 编辑:程序博客网 时间:2024/04/28 01:07
近期把List Control扩展成Grid,参考了两篇关于SubItem Selection的文章,一篇来自Piotr Szewczyk.. 采用NM_CUSTOMDRAW方法,另一篇来自Muhammad Azam.,采用LVS_OWNERDRAWFIXED。我个人偏好于NM_CUSTOMDRAW,因为NM_CUSTOMDRAW可以控制是否自绘,可以控制自绘区域(CDDS_ITEMPREPAINT和CDDS_SUBITEM),详细内容请参阅Neat Stuff to do in List Controls Using Custom Draw。
但两篇文章都存在一个问题:DrawText时总是用DT_LEFT,因为我为每个Column都设了Alignment,结果是每列都是Align Left。于是我用作了修改,DrawText时分别对应每个Column的Alignment,但是问题又出现了。
我用NM_CUSTOMDRAW方法,当移动Column Header时,如果该列的Alignment为Center或Right时,该列的内容就出现“花屏”现象,原因是作者为了防止闪烁,采用以下方法:
void CMyList::InvalidateCell(int nRow, int nCol)
{
//I add this function to reduce flickering
CRect rc;
if(nCol==0)
GetItemRect(nRow,&rc,LVIR_LABEL);
else
GetSubItemRect(nRow,nCol,LVIR_BOUNDS,rc);
InvalidateRect(&rc);
}
程序中保存两个变量m_nRow,m_nCol,当变量的值改变了就会调用InvalidateCell(int nRow, int nCol)。而当我拖动Column Header时不会调用InvalidateCell(int nRow, int nCol)。
解决方法当然是捕获拖动Column Header时的消息,查看了相关资料,相关的消息是HDN_ITEMCHANGED:拖动过程中不断收到
HDN_BEGINTRACK:拖到开始时
EDN_ENDTRACK:拖动结束时
那些消息是从CHeaderCtrl反馈回来的。(注:CHeaderCtrl有两种获得方法:一种是CListCtrl::GetHeaderCtrl(),一种是CListCtrl::GetDlgItem(0)。)
我的CMyList是继承自CListCtrl,不论我怎样设定风格,如CMyList->GetHeaderCtrl()->ModifyStyle(0, HDS_HOTTRACK),还是捕获不了HDN_ITEMCHANGED,其它消息也捕不了。
最后的办法只有设计一个类CMyHeaderCtrl继承自CHeaderCtrl,然后在CMyList的SubclassHeaderControl加入以下代码:
CHeaderCtrl* pHeader = GetHeaderCtrl();
if (pHeader)
{
VERIFY(m_HeaderCtrl.SubclassWindow(pHeader->m_hWnd));
}
因为ClassView中没有HDN_ITEMCHANGED所以要自己加
ON_NOTIFY_REFLECT(HDN_ITEMCHANGED, OnItemChanged)
以下是OnItemChanged的实现
void CMyHeaderCtrl::OnItemChanged(NMHDR * pNMHDR, LRESULT* pResult)
{
*pResult = 0;
CMyList* pzList = static_cast<CMyList*>(GetParent());
ASSERT(pzList);
NMHEADER *pHdr = (NMHEADER*)pNMHDR;
int nCol;//The changed column
int topRow,bottomRow;//The visit top row and bottom row
nCol = pHdr->iItem;
if( pzList->Cols[nCol].getTextAlignFixed() == AlignLeft)
return;//因为AlignLeft不存在“花屏”现象
if( 0 == pzList->GetItemCount())
return;
topRow = pzList->GetTopIndex();
bottomRow = pzList->GetCountPerPage();
CRect rc1,rc2;
pzList->GetSubItemRect(topRow,nCol,LVIR_BOUNDS,rc1);
pzList->GetSubItemRect(bottomRow,nCol,LVIR_BOUNDS,rc2);
if( 0 == nCol)
{
rc1.left = 0;
rc2.left = 0;
rc1.right = pzList->GetColumnWidth(0);
rc2.right = rc1.right;
}
rc1.bottom = rc2.bottom;
pzList->InvalidateRect(&rc1);
TRACE("ItemChanged/n");
}
至此,虽然问题已解决,重画区域已减到最小,但也存在小小的闪烁,但比Invalidate好多了。
一些问题也是想不通:
1. 为什么继承的CListCtrl不能收到CHeaderCtrl的Trace消息?
2. 的Column为什么不会出现“花屏”现象?AlignLeft
今天收获很大,虽然最后也要动用到继承CHeaderCtrl,但也不失为好事,因为迟早也要继承CHeaderCtrl才能完成一些功能的,如禁止改变列宽,在列上画排序箭头。
参考资料:
Matt Weagle:Using the Header Control
Piotr Szewczyk:SubItem Selection in List Control
Muhammad Azam:SubItem Selection in List Control
Michael Dunn:Neat Stuff to do in List Controls Using Custom Draw
- SubItem Selection in List Control改进版
- Column based selection in rich edit control.
- Handling tree control check box selection/de-selection in Win32/MFC
- Displaying icons in a Flex List control
- Sign in SAP Selection
- Selection in QuickSort
- List control
- list control
- LIST CONTROL
- List Control
- list control
- Customized Report List Control with In-Place Combo Box '& Edit Control
- Selection in expected linear time
- List Control的用法:
- List Control 基本使用
- ZoneAlarm Programs Control List
- list control单击事件
- List Control(VC++)
- 结构体字段错位引起的"1970-1-1 08:00:01"的问题
- 实体-联系模型(习题)
- 放弃什么都不要放弃希望!缺少什么也不能缺少信念!
- 大表建立索引时候的注意问题
- 东方不败转行IT以后谈软件开发
- SubItem Selection in List Control改进版
- access连接远程数据库
- Tomcat 中 "The value for the useBean class attribute is invalid" 错误的排除
- JDBC开发时的一个“可爱的”错误
- Linux Fedro Core 5下PPPOE上网配置全记录
- 罪过 -毕业补遗(0)
- 入侵oracle时常用的命令
- GridView分页
- 新鲜出炉,几分钟以前刚刚完成,一个带自定义分页,排序功能的DATAGRID控件(公开源码)