原作者:ccrun
更新日期:2006-07-19
浏览次数:1357
关键字:ListView,ListItem,DrawItem,自画,ownerDraw,ccrun
关于VCL控件自画的代码先前ccrun发过很多,比如TListBox, TCheckListbox, TComboBox,
TMenuItem等,下面的代码是自绘TListItem,也就是ListView在ViewStyle为vsReport时Item的自画。效果图如
下:
首先定义几个我们需要用到的颜色,这里用的是Office 2003菜单的高亮条颜色:
#define MYCOLOR_BACK TColor(0x00CFB9B1)
#define
MYCOLOR_BORDER clHighlight
#define MYCOLOR_ROW
TColor(RGB(240, 240, 240))
一般来讲,VCL中提供了自画功能的控件都有类似OnDrawXX或OnCustomDrawXX的事件,ListView有四个类似的事件,这个例子中
我们使用OnDrawItem事件。
在窗体的头文件中,声明一下自画函数,可以放在Form类的__published段内,需要注意的是,由IDE自动产生的
ListViewOnDrawItem自画函数的参数和我们声明的这个略有不同,所以在设计界面上,ListView的OnDrawItem中是看不到这
个函数的。
private: // User declarations
void __fastcall CrnDrawListViewItem(TCustomListView
*Sender,
TListItem *Item,
TRect &Rect, TOwnerDrawState State);
下面是自画函数的具体实现代码:
//---------------------------------------------------------------------------
// 自画ListView的Item
// by ccrun(老妖) info#ccrun.com
// 欢迎光临 C++Builder研究 -
//
做人要厚道,转载要留名
//---------------------------------------------------------------------------
void __fastcall TForm1::CrnDrawListViewItem(TCustomListView
*Sender,
TListItem *Item, TRect &Rect,
TOwnerDrawState State)
{
TListView *lv =
(TListView *)Sender;
// Rect
TRect
rct(Rect.Left + 1, Rect.Top, Rect.Width() - 1,
Rect.Bottom);
// Fill background
if(State.Contains(odFocused) || State.Contains(odSelected))
{
// With focus
lv-> Canvas-> Brush-> Color = MYCOLOR_BACK;
lv-> Canvas-> FillRect(rct);
lv-> Canvas-> Pen-> Color = MYCOLOR_BORDER;
lv-> Canvas-> Rectangle(rct);
}
else
{
lv-> Canvas-> Brush-> Color = lv-> Color;
lv-> Canvas-> FillRect(Rect);
}
int nLeftOffset(0);
// With CheckBox?
// 本文转自 C++Builder 研究 -
/article.asp?i=656&d=qdc7kg
//
63 63 72 75 6E 2E 63 6F 6D
if(lv->
Checkboxes)
{
lv->
Canvas-> Pen-> Color = clBlack;
lv-> Canvas-> Pen-> Width = 2;
// Draw CheckBox Rect
lv->
Canvas-> Rectangle(Rect.Left + 4, Rect.Top + 3, Rect.Left
+ 16, Rect.Bottom - 2);
nLeftOffset = 16;
if(Item-> Checked)
{
// 画CheckBox的勾
lv->
Canvas-> MoveTo(Rect.Left + 6, Rect.Top + 6);
lv-> Canvas-> LineTo(Rect.Left +
8, Rect.Top + 11);
lv-> Canvas-> LineTo(Rect.Left + 13, Rect.Top + 5);
}
lv->
Canvas-> Pen-> Width = 1;
}
// Draw small Icon
if(lv-> SmallImages
&& Item-> ImageIndex != -1)
{
lv-> SmallImages-> Draw(lv-> Canvas,
nLeftOffset + Rect.Left + 2,
Rect.Top + (Rect.Height() - lv-> SmallImages->
Height) / 2 + 1,
Item-> ImageIndex, true);
nLeftOffset
+= lv-> SmallImages-> Width;
/*
*/
}
// Draw Text
lv->
Canvas-> Font-> Color = clBlack;
lv->
Canvas-> TextOutA(Rect.Left + 4 + nLeftOffset,
Rect.Top + (Rect.Height() - lv->
Canvas-> TextHeight( "A ")) / 2,
Item-> Caption);
// Draw SubItem Text
int nColOffset(0);
for(int i=0;
iSubItems-> Count; i++)
{
nColOffset += lv-> Column[i]-> Width;
lv-> Canvas-> TextOutA(nColOffset + Rect.Left +
4,
Rect.Top +
(Rect.Height() - lv-> Canvas-> TextHeight( "A ")) / 2,
Item-> SubItems->
Strings[0]);
}
}
// 自画代码结束
由于这个自画函数与IDE自动产生的不一样,所以需要动态指定ListView的OnDrawItem,同时,ListView还需要一些设置,当然,你
可以在设计时直接在属性中更改。
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
ListView1->
OwnerDraw = true;
ListView1-> RowSelect =
true;
ListView1-> ReadOnly = true;
ListView1-> OnDrawItem
=(TLVDrawItemEvent)&CrnDrawListViewItem;
}
这样就基本OK了,有兴趣的朋友可以测试一下。
.dfm文件内容(View as Text)
=============================================================================
object Form1: TForm1
Left = 196
Top
= 131
BorderStyle = bsDialog
Caption =
'ListItem自画演示 '
ClientHeight = 168
ClientWidth = 231
Color = clBtnFace
Font.Charset = GB2312_CHARSET
Font.Color =
clWindowText
Font.Height = -12
Font.Name =
'宋体 '
Font.Style = []
OldCreateOrder =
False
Position = poScreenCenter
Visible =
True
PixelsPerInch = 96
TextHeight = 12
object Label1: TLabel
Left = 40
Top = 8
Width = 144
Height = 12
Caption = 'by ccrun(老妖)
QQ:165332 '
end
object Label2: TLabel
Left = 24
Top = 144
Width = 186
Height = 12
Caption = 'Welcome to '
end
object ListView1: TListView
Left = 10
Top = 27
Width = 209
Height = 105
Columns = <
item
end
item
Width = 56
end
item
Width = 80
end>
Items.Data = {
EF0000000700000000000000FFFFFFFFFFFFFFFF020000000000000001610261
610361616100000000FFFFFFFFFFFFFFFF020000000000000001620262620362
626200000000FFFFFFFFFFFFFFFF020000000000000001630263630363636300
000000FFFFFFFFFFFFFFFF020000000000000001640264640364646400000000
FFFFFFFFFFFFFFFF020000000000000001650265650365656500000000FFFFFF
FFFFFFFFFF020000000000000001660266660366666600000000FFFFFFFFFFFF
FFFF0200000000000000016702676703676767FFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}
TabOrder = 0
ViewStyle = vsReport
end
end
阅读(1088) | 评论(2) | 转发(0) |