关于Listbox自绘的问题我没有弄明白,我希望您可以帮助我一下,最好能给我做出来一个案例来看看,我要实现的是要有图标,有两行的字体,而且当鼠标划过的时候能够出现不同的界面,就像QQ一样,谢谢了,出来以后另有重分相赠送,呵呵就让给100分

解决方案 »

  1.   

    先回贴,现吃饭。还是那天的代码,Look!
    procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    //ListBox.OnDrawItem事件
    var
      ImgRect, MemoRect: TRect;
      Cnvs: TCanvas;
      B: TBitmap;
      S, Memo: string;
      iPos: Integer;
    begin
      Cnvs := ListBox1.Canvas;
      ImgRect := Rect;
      ImgRect.Right := ImgRect.Left + (ImgRect.Bottom - ImgRect.Top); //画图区域  if odSelected in State then
      begin
        Cnvs.Brush.Color := clSkyBlue;
        Cnvs.Pen.Color := clNavy;
      end
      else
      begin
        Cnvs.Brush.Color := ListBox1.Color;
        Cnvs.Pen.Color := ListBox1.Color;
      end;
      Cnvs.Brush.Style := bsSolid;
      Cnvs.Rectangle(Rect);  Cnvs.Brush.Style := bsClear;
      if ImageList.Count > 0 then
      begin
        B := TBitmap.Create;
        try
          ImageList.GetBitmap(0, B);
          B.PixelFormat := pf24bit;
          B.Transparent := True;
          InflateRect(ImgRect, -2, -2);
          Cnvs.StretchDraw(ImgRect, B);
        finally
          B.Free;
        end;
      end;  Rect.Left := ImgRect.Right;
      MemoRect := Rect;
      MemoRect.Top := (Rect.Top + Rect.Bottom) div 2;
      Rect.Bottom := MemoRect.Top;
      S := ListBox1.Items[Index];  iPos := Pos(#9, S);
      Memo := Copy(S, iPos + 1, Length(S)); //提取备注
      S := Copy(S, 1, iPos - 1); //提取名称
      Cnvs.Font.Assign(ListBox1.Font);
      DrawText(Cnvs.Handle, PChar(S), -1,
        Rect, DT_SingleLine or DT_VCENTER); //垂直、水平居中 画名字  Cnvs.Font.Color := clGrayText;
      DrawText(Cnvs.Handle, PChar(Memo), -1,
        MemoRect, DT_SingleLine or DT_VCENTER); //垂直、水平居中 画名字
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      ListBox1.Style := lbOwnerDrawVariable; //自己画每一项,项高度可调
      ListBox1.ItemHeight := 30;
      ListBox1.Clear;
      //名称+#9+备注
      ListBox1.Items.Add('yujinfree'#9 + '昨日足迹');
      ListBox1.Items.Add('blazingfire'#9 + '...该充电了...');
      ListBox1.Items.Add('yujinfree'#9 + '昨日足迹');
      ListBox1.Items.Add('blazingfire'#9 + '...该充电了...');
    end;
      

  2.   

    这个可就相当的麻烦,不懂的看看帮助吧unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ImgList;type
      TForm1 = class(TForm)
        ListBox1: TListBox;
        ImageList: TImageList;
        procedure FormCreate(Sender: TObject);
        procedure ListBox1DrawItem(Control: TWinControl; Index: Integer;
          Rect: TRect; State: TOwnerDrawState);
        procedure ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
      private
        PrevRect: TRect; //上次鼠标画过的区域 
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    begin
      ListBox1.Style := lbOwnerDrawVariable; //自己画每一项,项高度可调
      ListBox1.ItemHeight := 30;
      ListBox1.Clear;
      //名称+#9+备注
      ListBox1.Items.Add('yujinfree'#9 + '昨日足迹');
      ListBox1.Items.Add('blazingfire'#9 + '...该充电了...');
      ListBox1.Items.Add('yujinfree'#9 + '昨日足迹');
      ListBox1.Items.Add('blazingfire'#9 + '...该充电了...');
    end;procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    var
      ImgRect, MemoRect: TRect;
      Cnvs: TCanvas;
      B: TBitmap;
      S, Memo: string;
      iPos: Integer;
      MousePt: TPoint;
    begin
      Cnvs := ListBox1.Canvas;
      ImgRect := Rect;
      ImgRect.Right := ImgRect.Left + (ImgRect.Bottom - ImgRect.Top); //画图区域  MousePt := ListBox1.ScreenToClient(Mouse.CursorPos); ///&&鼠标位置
      if odSelected in State then
      begin
        Cnvs.Brush.Color := clSkyBlue;
        Cnvs.Pen.Color := clNavy;
      end
      else if PtInRect(Rect, MousePt) then ///&&鼠标选中项目
      begin
        Cnvs.Brush.Color := clYellow;
        Cnvs.Pen.Color := clOlive;
      end
      else
      begin
        Cnvs.Brush.Color := ListBox1.Color;
        Cnvs.Pen.Color := ListBox1.Color;
      end;
      Cnvs.Brush.Style := bsSolid;
      Cnvs.Rectangle(Rect);  Cnvs.Brush.Style := bsClear;
      if ImageList.Count > 0 then
      begin
        B := TBitmap.Create;
        try
          ImageList.GetBitmap(0, B);
          B.PixelFormat := pf24bit;
          B.Transparent := True;
          InflateRect(ImgRect, -2, -2);
          Cnvs.StretchDraw(ImgRect, B);
        finally
          B.Free;
        end;
      end;  Rect.Left := ImgRect.Right;
      MemoRect := Rect;
      MemoRect.Top := (Rect.Top + Rect.Bottom) div 2;
      Rect.Bottom := MemoRect.Top;
      S := ListBox1.Items[Index];  iPos := Pos(#9, S);
      Memo := Copy(S, iPos + 1, Length(S)); //提取备注
      S := Copy(S, 1, iPos - 1); //提取名称
      Cnvs.Font.Assign(ListBox1.Font);
      DrawText(Cnvs.Handle, PChar(S), -1,
        Rect, DT_SingleLine or DT_VCENTER); //垂直、水平居中 画名字  Cnvs.Font.Color := clGrayText;
      DrawText(Cnvs.Handle, PChar(Memo), -1,
        MemoRect, DT_SingleLine or DT_VCENTER); //垂直、水平居中 画名字
    end;procedure TForm1.ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    var
      ARect: TRect;
      i: Integer;
    begin
      i := ListBox1.ItemAtPos(Point(X, Y), True);
      if i > -1 then
      begin
        ListBox1.Perform(LB_GETITEMRECT, i, Longint(@ARect));
        if not(
          (PrevRect.Left = ARect.Left) and (PrevRect.Right = ARect.Right) and
          (PrevRect.Top = ARect.Top) and (PrevRect.Bottom = ARect.Bottom)) then
        begin
          InvalidateRect(ListBox1.Handle, @ARect, True);
          InvalidateRect(ListBox1.Handle, @PrevRect, True);
          PrevRect := ARect;
        end;
      end
      else
      begin
        InvalidateRect(ListBox1.Handle, @PrevRect, True);
        PrevRect := Rect(0, 0, 0, 0);
      end;
    end;end.
      

  3.   

    我放上去了,都好使,但是我想改变一下,想让图标和listbox和后面的问题之间有点距离应该如何弄呢。
      

  4.   

    在这个两个函数之前加上调整Rect,MemoRect的Left域的操作
      Inc(Rect.Left, 1);//+++如果要再大点可以把1改大点
      DrawText(Cnvs.Handle, PChar(S), -1,
        Rect, DT_SingleLine or DT_VCENTER); //垂直、水平居中 画名字  Cnvs.Font.Color := clGrayText;
      Inc(MemoRect.Left, 1);//+++
      DrawText(Cnvs.Handle, PChar(Memo), -1,
        MemoRect, DT_SingleLine or DT_VCENTER); //垂直、水平居中 画名字