前几天有人做了个360的界面 他说自己的没立体感。我叫他用GDI+画一个半透明的边框 他好像没理会。
故今天心血来潮 写了个浏览文件夹图片的类。给大家分享
借助gdi+库(该库的delphi单元在本站有下载,“阿发伯”提供)和Tpaintbox
下面是代码unit fuImageListView;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls,Gdiplus;const
   imgRectWidth = 110;
   imgRectHeight = 150;
   imgWidth = 60;
   imgHeight =90;
   ImgOffSetX =  (imgRectWidth -  imgWidth) div 2;
   ImgOffsetY =   6;type
  PImageItem=^TImageItem;
  TImageItem=record
    fileName:string;
    Rect:TRect;
    ImgRect:TRect;
    RGN:HRGN;
    Name:string;
  end;  TImageListView=class
  private
    FPaintBox: TPaintBox;
    FLookDir: string;
    FList : TList;
    FFocusItem:PImageItem;
    FSelectItem:PImageItem;
    procedure SetLookDir(const Value: string);
    function getCount: Integer;
    function GetItems(index: Integer): PImageItem;
    procedure SetFocusItem(const Value: PImageItem);
    procedure SetSelectItem(const Value: PImageItem);
  protected
    procedure DrawImageList;
    procedure DrawImage(const G:TGpGraphics;const P:PImageItem);
    procedure PaintBoxPaint(Sender: TObject);
    procedure PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure PaintBoxMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
    function GetFocusItem(const X,Y : Integer):PImageItem;  public
    property PaintBox : TPaintBox read FPaintBox;
    constructor Create(const aPaintBox:TPaintBox);
    destructor Destroy; override;
    property LookDir : string read FLookDir write SetLookDir;
    property Count : Integer read getCount;
    procedure Delete(const Index:Integer);
    procedure Clear;
    property  Items[index:Integer]: PImageItem read GetItems;
    property  FocusItem:PImageItem read FFocusItem write SetFocusItem;
    property  SelectItem:PImageItem read FSelectItem write SetSelectItem;
  end;implementationuses
   Math;{ TImageListView }procedure FillRectangle(const GDIgraphics:TGPGraphics;const X1,Y1:Integer;const X2:Integer;const Y2:Integer;
     const Color:TColor;const penWidth:Integer ;  const FillMode:Boolean;
     const AlphaBlendValue:Byte );
var
  SB: TGPSolidBrush;
  P:TGpPen;
  gdiColor:Cardinal;
  left,right,top, bottom:Integer;
begin
   left  := min(X1,X2);
   right := Max(x1,X2);
   top := min (Y1,Y2);
   bottom := Max(Y1,Y2) ;
  gdiColor := ARGBFromTColor(Color);
  gdiColor := (gdiColor and $FFFFFF) or (AlphaBlendValue shl 24);
  try
          GDIgraphics.SmoothingMode:= smAntiAlias;
          if FillMode then
          begin
             SB := TGPSolidBrush.Create(gdiColor);
             try
                  GDIgraphics.FillRectangle(sb,left,top,right-left,bottom-top);
             except             end;
             SB.Free;
          end else
          begin
            P := TGpPen.Create(gdiColor,penWidth);
            try
                  GDIgraphics.DrawRectangle(P,left,top,right-left,bottom-top);
            except            end;            p.Free;
          end;
  except  end;end;procedure TImageListView.Clear;
begin
      while Count>0 do
      Delete(0);
end;constructor TImageListView.Create(const aPaintBox: TPaintBox);
begin
   FPaintBox := aPaintBox;
   aPaintBox.OnPaint := PaintBoxPaint;
   aPaintBox.OnMouseMove := PaintBoxMouseMove;
   aPaintBox.OnMouseDown := PaintBoxMouseDown;
   FList := TList.Create;
   if FPaintBox.Parent <> nil then
   FPaintBox.Parent.DoubleBuffered := True;
end;procedure TImageListView.Delete(const Index: Integer);
var
  P:PImageItem;
begin
   P := Flist.Items[index];
   DeleteObject(p.RGN);
   Dispose(P);
   Flist.Delete(index);
end;destructor TImageListView.Destroy;
begin
  Clear;
  Flist.Free;
  inherited;
end;procedure TImageListView.DrawImage(const G: TGpGraphics; const P: PImageItem);
var
  image : TGpImage;
  rt: TGPRectF;
  aZoom:Real;
  strFormat: TGpStringFormat;
  font: TGpFont;
  rect1 :TGpRectF;
begin
    image := TGpImage.Create(p.fileName);
    if image.Width * image.Height >0 then
    begin
          g.InterpolationMode := imHighQualityBicubic;          aZoom :=  Min( imgWidth/image.Width,imgHeight/image.Height);
          rt.Width :=image.Width*aZoom;
          rt.Height :=image.Height*azoom;
          rt.X := (imgWidth-image.Width*aZoom) / 2 + p.ImgRect.Left;
          rt.Y := (imgHeight-image.Height*aZoom) / 2 +p.ImgRect.top;
          g.DrawImage(image,rt,  0, 0, image.Width, image.Height, utPixel);
          try
                  font := TGpFont.Create('arial', 10, []);
                  strFormat := TGpStringFormat.Create([]);
                  strFormat.Alignment := saCenter;
                 // strFormat.
                 
                //  g.DrawString(p.Name, font, Brushs[$99000000],p.Rect.Left+imgRectWidth /2, p.Rect.Bottom-20, strFormat);
                rect1.X :=p.Rect.Left;
                rect1.Y :=  p.Rect.Bottom-55;
                rect1.Width :=imgRectWidth-4;
                rect1.Height := 55;                    g.DrawString(p.Name,   font,  Brushs[$F0000000],    rect1,  strFormat)          except          end;
          if Assigned(font) then          font.Free;
          if Assigned(strFormat) then          strFormat.Free;          if FocusItem= P then
           begin
              FillRectangle(G, p.Rect.Left+2,p.Rect.Top+2,
               p.Rect.Right-2,p.Rect.Bottom-2,RGB(209,229,252),1,True,20); //画半透明填充框
               FillRectangle(G, p.Rect.Left+2,p.Rect.Top+2,
                p.Rect.Right-2,p.Rect.Bottom-2,RGB(209,229,252),1,False,$FF);  //画不透明外框
           end;
           if FSelectItem=p then
           begin
             FillRectangle(G, p.Rect.Left+2,p.Rect.Top+2,
               p.Rect.Right-2,p.Rect.Bottom-2,RGB(32,97,193),1,True,20); //画半透明填充框
              FillRectangle(G, p.Rect.Left+2,p.Rect.Top+2,
                p.Rect.Right-2,p.Rect.Bottom-2,RGB(32,97,193),1,False,120); //画半透明外框
           end;
    end;
    image.Free;end;procedure TImageListView.DrawImageList;
var
  RowCount,ColCount:Integer;
  P:PImageItem;
  K:Integer;
  I , J :Integer;begin
   if Assigned(FPaintBox) then
   begin
      ColCount := (FPaintBox.Width -25) div imgRectWidth;
      if ColCount > 0 then
      begin
         RowCount :=  Flist.Count div ColCount;
         if  Flist.Count mod ColCount<>0 then
         Inc(RowCount);
         FPaintBox.Height := RowCount* imgRectHeight;         K := 0 ;
         for I:= 0 to RowCount - 1 do
            for J := 0 to ColCount - 1 do
            begin
                P := Flist.Items[K];
                P^.Rect.Left := J*imgRectWidth;
                P^.Rect.Top := I*imgRectHeight;
                p^.Rect.Right := P^.Rect.Left + imgRectWidth;
                p^.Rect.Bottom := P^.Rect.Top +  imgRectHeight;
                P^.ImgRect := Rect(P^.Rect.Left+ImgOffSetX,P^.Rect.Top + ImgOffsetY,
                                        P^.Rect.Right-ImgOffSetX,P^.Rect.Bottom - ImgOffsetY) ;
                P^.RGN := CreateRectRgn(P^.ImgRect.Left,P^.ImgRect.Top,P^.ImgRect.Right,P^.ImgRect.Bottom );
                Inc(K);
                if K>=Flist.Count  then
                   Break;
            end;      end;
   end;
end;function TImageListView.getCount: Integer;
begin
   Result := FList.Count;
end;function TImageListView.GetFocusItem(const X, Y: Integer): PImageItem;
var
  I:Integer;
begin
  Result := nil;
  for I := 0 to FList.Count - 1 do
  begin
    if ptinregion(Items[i].RGN,X,Y) then
    begin
      Result :=Items[i];
      Break;
    end;
    
  end;end;function TImageListView.GetItems(index: Integer): PImageItem;
begin
    Result := FList.Items[index];
end;procedure TImageListView.PaintBoxMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 SelectItem:=  GetFocusItem(x,y);
end;procedure TImageListView.PaintBoxMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);begin
  FocusItem:=  GetFocusItem(x,y);  
end;
procedure TImageListView.PaintBoxPaint(Sender: TObject);
var
    G: TGpGraphics;
    I:Integer;
begin
           G := TGpGraphics.Create(FPaintBox.Canvas.Handle);
           for I := 0 to FList.Count - 1 do
              DrawImage(G,FList.Items[i]);
           G.Free;
end;procedure TImageListView.SetFocusItem(const Value: PImageItem);
begin
  if FFocusItem <> Value then
  begin
    FFocusItem := Value;
    FPaintBox.Repaint;
  end;
  end;procedure TImageListView.SetLookDir(const Value: string);
var
    SearchRec   :   TSearchRec;
    Attr   :   integer;
    Found   :   integer;
    ExtFileName:string;
    temstr:string;
    P:PImageItem;
begin
    FLookDir := Value;
    Clear;
    temstr:=Value+ '*.*';
    Attr   :=   faAnyFile;
    Found   :=   FindFirst(temstr,   Attr,   SearchRec);
    while   Found   =   0   do 
    begin 
        ExtFileName:=LowerCase(ExtractFileExt(SearchRec.Name)); 
        if   (ExtFileName= '.bmp')   or   (ExtFileName= '.jpg')   or   ((ExtFileName= '.jpeg'))   then
        begin
          New(P);
          P^.fileName :=  FLookDir+SearchRec.Name;
          P^.Name := SearchRec.Name;
          FList.Add(P)
        end;
        Found   :=   FindNext(SearchRec);
    end; 
    FindClose(SearchRec);
    DrawImageList;
end;procedure TImageListView.SetSelectItem(const Value: PImageItem);
begin
  if FSelectItem <> Value then
  begin
    FSelectItem := Value;
    FPaintBox.Repaint;
  end;end;end.
调用的时候很简单,窗体上方一个TScrollBox然后在里面放一个TPaintBox设置PaintBox的Align为altop
创建上面的类,并设置LOOKDIR属性,就能看见图片信息,选中和Focus看看效果