参考一下以下的代码,用于模拟qq的聊天记录,在drawitem部分把文字换成图片即可
History就是一个Listbox,Style:=lbOwnerDrawVariable。
原理是listbox每画一个item的时候,先调用onMeasureItem事件得到每一个item的高度,然后调用onDrawItem事件,去画每一个item.画的时候要分清楚当前item的状态。
//Form的OnCreate事件。
procedure TFrm_Message.FormCreate(Sender: TObject);
begin
HeightOfText := LB_History.Canvas.TextHeight('A');
end;
//onDrawItem事件。
procedure TFrm_Message.LB_HistoryDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
TempStrings:TStringList;
TempRect:TRect;
i:integer;
begin
with (Control as TListBox).Canvas do
Begin
TempStrings:=TStringList.Create ;
try
TempStrings.Text := (Control as TListBox).Items[index];
//用蓝色来画标题
if (odSelected in State) and (odFocused in State) then
begin
Brush.Color:=$00996633;
Font.Color:=clWhite;
end
else Begin
Brush.Color:=$00CF9030;
Font.Color:=clWhite;
end;
TempRect.Left:=Rect.Left;
TempRect.Top:=Rect.Top;
TempRect.Right:=Rect.Right;
TempRect.Bottom:=Rect.Top+HeightOfText;//HeightOfText在From的Private里定义了,是一个integer
TextRect(TempRect,0,TempRect.Top,TempStrings.Strings[0]);
TempStrings.Delete(0);
if (odSelected in State) and (odFocused in State) then
begin
Brush.Color:=clBlack;
Font.Color:=clWhite;
end
else Begin
Brush.Color:=clWhite;
Font.Color:=clBlack;
end;
for i := 0 to TempStrings.Count-1 do
begin
TempRect.Top:=Rect.Top+HeightOfText*(i+1);
TempRect.Bottom:=TempRect.Top+HeightOfText;
TextRect(TempRect,0,TempRect.Top,TempStrings.Strings[i]);
end;
finally
TempStrings.Free;
end;
end;
end;
//onMeasureItem事件。
procedure TFrm_Message.LB_HistoryMeasureItem(Control: TWinControl;
Index: Integer; var Height: Integer);
var
TempStrings:TStringList;
begin
TempStrings:=TStringList.Create ;
try
TempStrings.Text := (Control as TListBox).Items[index];
Height := TempStrings.Count* HeightOfText;
finally
TempStrings.Free;
end;
end;
History就是一个Listbox,Style:=lbOwnerDrawVariable。
原理是listbox每画一个item的时候,先调用onMeasureItem事件得到每一个item的高度,然后调用onDrawItem事件,去画每一个item.画的时候要分清楚当前item的状态。
//Form的OnCreate事件。
procedure TFrm_Message.FormCreate(Sender: TObject);
begin
HeightOfText := LB_History.Canvas.TextHeight('A');
end;
//onDrawItem事件。
procedure TFrm_Message.LB_HistoryDrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
TempStrings:TStringList;
TempRect:TRect;
i:integer;
begin
with (Control as TListBox).Canvas do
Begin
TempStrings:=TStringList.Create ;
try
TempStrings.Text := (Control as TListBox).Items[index];
//用蓝色来画标题
if (odSelected in State) and (odFocused in State) then
begin
Brush.Color:=$00996633;
Font.Color:=clWhite;
end
else Begin
Brush.Color:=$00CF9030;
Font.Color:=clWhite;
end;
TempRect.Left:=Rect.Left;
TempRect.Top:=Rect.Top;
TempRect.Right:=Rect.Right;
TempRect.Bottom:=Rect.Top+HeightOfText;//HeightOfText在From的Private里定义了,是一个integer
TextRect(TempRect,0,TempRect.Top,TempStrings.Strings[0]);
TempStrings.Delete(0);
if (odSelected in State) and (odFocused in State) then
begin
Brush.Color:=clBlack;
Font.Color:=clWhite;
end
else Begin
Brush.Color:=clWhite;
Font.Color:=clBlack;
end;
for i := 0 to TempStrings.Count-1 do
begin
TempRect.Top:=Rect.Top+HeightOfText*(i+1);
TempRect.Bottom:=TempRect.Top+HeightOfText;
TextRect(TempRect,0,TempRect.Top,TempStrings.Strings[i]);
end;
finally
TempStrings.Free;
end;
end;
end;
//onMeasureItem事件。
procedure TFrm_Message.LB_HistoryMeasureItem(Control: TWinControl;
Index: Integer; var Height: Integer);
var
TempStrings:TStringList;
begin
TempStrings:=TStringList.Create ;
try
TempStrings.Text := (Control as TListBox).Items[index];
Height := TempStrings.Count* HeightOfText;
finally
TempStrings.Free;
end;
end;
Rect: TRect; State: TOwnerDrawState);
begin
with ListBox1 do
begin
Canvas.FillRect(Rect);
Canvas.Draw(Rect.Left + 2, Rect.Top + 2, Image1.Picture.Bitmap);
Canvas.TextOut(Rect.Left + 20, Rect.Top + 2, Items[Index]);
end;
end;