我想自繪ListView 在DrawItem事件中實作,第一,二列顯示文字,第三列顯示圖片。
但是在改變列寬時文字出現了重影,請問下如何去自繪呢?
uj5u.com熱心網友回復:
問妖哥要代碼
uj5u.com熱心網友回復:
關于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研究 - http://www.ccrun.com
// 做人要厚道,轉載要留名
//---------------------------------------------------------------------------
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?
// 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,
// 本文轉自 C++Builder研究 - http://www.ccrun.com/article.asp?i=656&d=qdc7kg
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; i<Item->SubItems->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 http://www.ccrun.com'
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/118627.html
標籤:基礎類
上一篇:關于frameset布局
