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
表示取消控件所有列的标题。
分享到:
相关推荐
WM_DRAWITEM是Windows消息系统中的一种消息,当控件需要被绘制时,操作系统会发送这个消息给父窗口。例如,当一个按钮或列表框的状态改变,如选中、未选中或获得焦点时,系统就会发送WM_DRAWITEM消息。接收此消息的...
参考buttonST写的按钮控件drawitem函数,很简单,就是实现标准按钮的功能,适合需求简单的同学,比如想改字体颜色,直接在源码里该就可以,当然也可以使用buttonST,但是其功能太强大了,有时候用不着,而且源代码多...
本主题主要围绕`DrawItem`方法的重载来探讨如何实现一个自定义绘制的`ListCtrl`,以满足特定的视觉效果或界面需求。 `DrawItem`是`WM_DRAWITEM`消息的处理函数,当窗口中的控件需要绘制时,系统会发送此消息。在`...
1、使用WM_DRAWITEM和WM_MEASUREITEM消息在父窗口实现按钮自绘; 2、使用WM_DRAWITEM和WM_MEASUREITEM消息在父窗口实现列表控件自绘; 3、使用WM_DRAWITEM和WM_MEASUREITEM消息在父窗口实现下拉控件自绘; 4、通过...
2. **重载DrawItem**:在派生类中,我们重载`DrawItem`函数,该函数接受一个`DRAWITEMSTRUCT`结构体作为参数,包含了控件的相关信息。 3. **计算行高**:在`DrawItem`函数内部,我们可以根据需要计算每个列表项的...
ON_WM_DRAWITEM() ON_WM_MEASUREITEM() ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CMyListCtrl::OnCustomDraw) END_MESSAGE_MAP() // 在OnDrawItem中实现自绘逻辑 void CMyListCtrl::OnDrawItem(int nIDCtl, ...
这通常通过重写`DrawItem`、`DrawSubItem`等回调函数来完成。在描述中提到的高度、背景色和前景色的自绘,可以通过在这些函数中使用GDI(Graphics Device Interface)函数来实现。例如,我们可以使用`SetBkColor`和`...
- 例如重载`CButton::DrawItem`方法来自定义按钮的绘制行为。 #### 五、总结 本文详细介绍了在VC/MFC环境下美化用户界面的各种方法和技术。通过这些技术的应用,开发者可以显著提高软件产品的用户体验和美观度。...
当一个CheckBox需要被绘制时,Windows会发送WM_DRAWITEM消息到控件的父窗口。因此,我们需要在我们的类中处理这个消息,通常是在CMyDialog或CMyFrame类(继承自CDialog或CFrameWnd)中重写OnDrawItem()函数。在这个...
7. **自定义绘制**:如果想要实现更复杂的视觉效果,可以处理`WM_DRAWITEM`消息,通过`CDC`对象和`CRect`对象进行自定义绘制。 在提供的标签中,"源码"暗示了可能存在一段定制的代码或示例,展示了如何创建并美化`...
标签"DRAWITEM"指的是WM_DRAWITEM消息,这是Windows发送给控件父窗口的,指示控件需要进行重绘。当CListBox的某个项需要更新或者高亮显示时,会发送这个消息。CTitleTip类需要响应这个消息,以便在鼠标悬停时正确地...
本话题将深入探讨如何利用`WM_DRAWITEM`消息实现一个与MFC(Microsoft Foundation Classes)Push Button外观一致的自绘按钮。 `WM_DRAWITEM`是Windows消息系统中用于通知应用程序其窗口中的某个控件需要被绘制的...
在本例中,我们将深入探讨`ListView`的`DrawItem`事件及其使用。 `DrawItem`事件在`ListView`的`OwnerDraw`属性被设置为`true`时触发,这意味着开发者需要手动控制ListView项的绘制过程。这个事件提供了一个机会,...
"DrawItem"是Windows消息WM_DRAWITEM的一部分,用于处理控件的绘制事件。当窗口中某个控件需要被绘制时,系统会发送WM_DRAWITEM消息。在CBmpMenu的上下文中,这个消息被用来绘制带有图像的菜单项。通过重载...
"自绘Button 修改Button背景"这个标题表明我们将探讨如何利用`WM_DRAWITEM`消息来改变Button的默认外观。 `WM_DRAWITEM`是Windows消息系统中的一个关键消息,它在窗口控件(如Button)需要被绘制时发送。当用户界面...
当控件需要显示或重绘其内容时,操作系统会发送WM_DRAWITEM消息给控件,然后控件的DrawItem函数被调用进行实际的绘制操作。在这个过程中,消息反射可以让我们在运行时检查和处理DrawItem消息,以实现自定义的绘制...
用于美化现有的菜单。 导出3个函数(标准Win API): long AssignOwnerDraw...在 WM_DRAWITEM 消息,调用 DrawItem, lpdis 为 lParam 菜单内容支持位图(需要用户自行设定)。目前的风格模仿 Firefox Aero 主题。
在`DrawItem`函数中,我们需要根据索引访问`m_ItemColors`数组,获取对应行的颜色,并使用`CDC`对象的`SetBkColor`和`FillSolidRect`方法设置背景色,然后调用父类的`DrawItem`完成标准的文本绘制。 ```cpp void ...
DrawItem()是WM_DRAWITEM消息的处理函数,用于绘制控件的各个部分。在这个函数里,我们可以根据需要自定义每一项的颜色。 ```cpp void CListBoxDemoDlg::DrawItem(int nItem) { if (nItem == -1) return; // 如果...