5,388
社区成员
发帖
与我相关
我的任务
分享
unit fuImageListView;
interface
uses
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;
implementation
uses
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.