void CListCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
LPDRAWITEMSTRUCT lpDIS = lpDrawItemStruct;
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
LVITEM lvi = {0};
lvi.mask = LVIF_STATE;//|LVIF_IMAGE;
lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED ;
lvi.iItem = lpDIS->itemID;
BOOL bGet = GetItem(&lvi);
BOOL bHighlight =((lvi.state & LVIS_DROPHILITED)||((lvi.state & LVIS_SELECTED) &&
((GetFocus() == this)|| (GetStyle() & LVS_SHOWSELALWAYS))));
// 画文本背景
CRect rcBack = lpDIS->rcItem;
pDC->SetBkMode(TRANSPARENT);
if( bHighlight )
{
pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
pDC->FillRect(rcBack, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
}
else
{
if (lpDIS->itemID%2 ==0)
{
pDC->SetTextColor(0x0C0F80);
pDC->FillRect(rcBack, &CBrush(0xEEF1E3));
}
else
{
pDC->SetTextColor(RGB(0,128,255));
pDC->FillRect(rcBack, &CBrush(0xE3e3e3));
}
}
//设置字体颜色
CString str;
//得到焦点大小
CRect rcFocus = lpDIS->rcItem;
rcFocus.DeflateRect(1,1,1,1);
if (lpDIS->itemAction & ODA_DRAWENTIRE)
{
//写文本
CString szText;
for (int i = 0; i < /*GetColumns()*/10; i++)
{ //循环得到文本
CRect rcItem;
if ( !GetSubItemRect(lpDIS->itemID, i, LVIR_LABEL, rcItem ))
continue;
szText = GetItemText( lpDIS->itemID, i );
rcItem.left += 5; rcItem.right -= 1;
pDC->DrawText(szText/*szText*/, lstrlen(szText), &rcItem, DT_CENTER|DT_VCENTER|DT_NOPREFIX|DT_SINGLELINE);
}
}
}
<!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!-- [if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->
DRAWITEMSTRUCT 结构的定义如下:
typedef struct tagDRAWITEMSTRUCT {
UINT CtlType;
UINT CtlID;
UINT itemID;
UINT itemAction;
UINT itemState;
HWND hwndItem;
HDC hDC;
RECT rcItem;
ULONG_PTR itemData;
} DRAWITEMSTRUCT, NEAR *PDRAWITEMSTRUCT, FAR *LPDRAWITEMSTRUCT ; 结构成员:
成员:
CtlType
指定了控件的类型,其取值如下表所示。
ODT_BUTTON :按钮控件
ODT_COMBOBOX :组合框控件
ODT_LISTBOX :列表框控件
ODT_LISTVIEW :列表视图控件
ODT_MENU :菜单项
ODT_STATIC :静态文本控件
ODT_TAB :Tab 控件
CtlID
指定了自绘控件的ID 值,而对于菜单项则不需要使用该成员
itemID
表示菜单项ID ,也可以表示列表框或者组合框中某项的索引值。对于一个空的列表框或组合框,该 成员的值为–1 。这时应用程序只绘制焦点矩形(该矩形的坐标由rcItem 成员给出)虽然此时控件中没有需要显示的项,但是绘制焦点矩形还是很有必要的,因为这样做能够提示用户该控件是否具有输入焦点。当然也可以设置 itemAction 成员为合适值,使得无需绘制焦点。
itemAction
指定绘制行为,其取值可以为下表中所示值的一个或者多个的联合。
ODA_DRAWENTIRE :当整个控件都需要被绘制时,设置该值
ODA_FOCUS :如果控件需要在获得或失去焦点时被绘制,则设置该值。此时应该检查itemState 成员,以确定控件是否具有输入焦点。
ODA_SELECT
如果控件需要在选中状态改变时被绘制,则设置该值。此时应该检查itemState 成员,以确定控件是否处于选中状态。
itemState
指定了当前绘制操作完成后,所绘项的可见状态。例如,如果菜单项应该被灰色显示,则可以指定ODS_GRAYED 状态标志。其取值可以为下表中所示值的一个或者多个的联合。
ODS_CHECKED :如果菜单项将被选中,则可设置该值。该值只对菜单项有用。
ODS_COMBOBOXEDIT :在自绘组合框控件中只绘制选择区域。
ODS_DEFAULT :默认值。
ODS_DISABLED :如果控件将被禁止,则设置该值。
ODS_FOCUS :如果控件需要输入焦点,则设置该值。
ODS_GRAYED :如果控件需要被灰色显示,则设置该值。该值只在绘制菜单时使用。
ODS_HOTLIGHT :Windows 98/Me, Windows 2000/XP: 如果鼠标指针位于控件之上,则设置该值,这时控件会显示高亮颜色。
ODS_INACTIVE :Windows 98/Me, Windows 2000/XP: 表示没有激活的菜单项。
ODS_NOACCEL :Windows 2000/XP: 控件是否有快速键盘。
ODS_NOFOCUSRECT :Windows 2000/XP: 不绘制捕获焦点的效果。
ODS_SELECTED :选中的菜单项。
hwndItem
指定了组合框、列表框和按钮等自绘控件的窗口句柄;如果自绘的对象时菜单项,则表示包含该菜单项的菜单句柄。
hDC
指定了绘制操作所使用的设备环境。
rcItem
指定了将被绘制的矩形区域。这个矩形区域就是上面hDC 的作用范围。系统会自动裁剪组合框、列 表框或按钮等控件的自绘制区域以外的部分。也就是说rcItem 中的坐标点(0 ,0 )指的就是控件的左上角。但是系统不裁剪菜单项,所以在绘制菜单项的时 候,必须先通过一定的换算得到该菜单项的位置,以保证绘制操作在我们希望的区域中进行。
itemData
对于菜单项,该成员的取值可以是由
CMenu::AppendMenu 、
CMenu::InsertMenu 或者
CMenu::ModifyMenu
等函数传递给菜单的值。
对于列表框或这组合框,该成员的值可以为由
ComboBox::AddString 、
CComboBox::InsertString 、
CListBox::AddString 或者
CListBox::InsertString
等传递给控件的值。
如果ctlType 的取值是ODT_BUTTON 或者ODT_STATIC, itemData 的取值为0 。
FromHandle
MFC 实际上是对内核对象HANDLE( 如CDC 的m_hDC ,CWnd 的m_hWnd )封装了这个句柄有关的所有操作,一个类生成一个新对象的时候这个句柄是 无效的,要获得这个句柄,可以有两个方法,一个是Create 来创建,另一个就是用Attach 来与一个已有的句柄建立关联,实际上也就是给类的句柄成员 变量赋值。 而有个时候这个句柄不是由我们创建, 但是我们要对它的封装类进行操作,(mfc 框架) 必需创建对应的封装类包装它
MFC 中对各种包含内核对象的封装类都有FromHandle(HANDLE h) 方法
FromHandle(HANDLE h) 先查找由用户定义的内核对象对象的封装类, 如果找到直接返回, 没有找到构造一个临时对象返回.
例如:
void CListViewEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CListCtrl& ListCtrl=GetListCtrl();
// 构造了一个句柄是lpDrawItemStruct->hDC 的包装类
CDC* pDC = (CDC *)CDC::FromHandle(lpDrawItemStruct->hDC);
}
列表视图控件(List Control )
列表视图控件是一种非常常用的控件,在需要以报表形式显示数据时,列表控件通常是最好的选择,许多专用的数据报表控件,也是在它的基础上派生而来。与树视图类似,列表控件可以由多个子项目组成,并且支持大图标、小图标、列表和报表4 种方式显示信息,如图1 所示。
图1 列表视图的4 种显示方式
列 表视图包含一个项目列表,而其中每个项目由图标、项目名称和多个子项组成,每一个子项所包含的项目的数目必须相同,属性相同的每个子项显示在同一个列中。 列表视图控件有两个重要的数据结构LVCOLUMN 和LVITEM 。LVCOLUMN 用于定义报表方式下的“ 列” 的结构;LVITEM 用于定义“ 项” 的结 构。这两个结构的定义及说明如下:
typedef struct _LVCOLUMN {
UINT mask; // 说明此结构中哪些成员是有效的
int fmt; // 列的对齐方式
int cx; // 列的初始宽度
LPTSTR pszText; // 列的标题
int cchTextMax; //pszText 所指向的缓冲区的大小
int iSubItem; // 与列关联的子项的索引值,从0 开始
int iImage; // 与列关联的图像列表中指定图像的索引值
int iOrder; // 第几列,0 代表最左一列
} LVCOLUMN, FAR *LPLVCOLUMN;
typedef struct _LVITEM {
UINT mask; // 说明LVITEM 结构中哪些成员有效
int iItem; // 项目的索引值( 可以视为行号) 从0 开始
int iSubItem; // 子项的索引值( 可以视为列号) 从0 开始
UINT state; // 子项的状态
UINT stateMask; // 状态有效的屏蔽位
LPTSTR pszText; // 主项或子项的名称
int cchTextMax; //pszText 所指向的缓冲区大小
int iImage; // 关联图像列表中指定图像的索引值
LPARAM lParam; // 程序定义的32 位参数
int iIndent; // 表示图像位置缩进的单位
} LVITEM, FAR *LPLVITEM;
列表项常用的属性如下:View 指定程序运行后列表视图控件最初显示的方式,可以设置为Icon (大图标)、SmallIcon (小图标)、List (列 表)或Report (报表);Single selection 表示每次只能选中一个项;Auto arrange 使得项目在Icon 和Small Icon 显示方式下能够自动排序;Edit Labels 表示可以编辑项目的卷标;No column header 表示取消控件所有列的标题。