2013-03-10 78 views
1

我正在制作从TScrollBox派生的自定义组件,该自定义组件显示存储在字符串属性中的图像文件的缩略图。它运行良好,直到Scrollbox在运行时调整大小。我尝试覆盖Risize方法,但是当我在运行时将图像添加到组件后,添加两个到三个图像后,它出错(无效的指针操作)。见下面重写自定义组件中的TScrollBox OnResize事件

type 
    TViewer = class(TScrollBox) 
    private 
    { Private declarations } 
    fColumns: Integer; 
    fImages : TStrings; 
    fThumbWidth: Integer; 
    fThumbHeight: Integer; 
    procedure SetColumns(Value: Integer); 
    procedure SetImages(Value: TStrings); 
    procedure SetThumbWidth(Value: Integer); 
    procedure SetThumbHeight(Value: Integer); 
    function GetColumns: Integer; 
    function GetThumbWidth: Integer; 
    function GetThumbHeight: Integer; 
    protected 
    { Protected declarations } 
    procedure LinesChanged(Sender: TObject); 
    procedure UpdateViewer; 
    procedure ClearViewer; 
    **//procedure Resize;override;** 
    public 
    { Public declarations } 
    constructor Create(AOwner: TComponent);override; 
    destructor Destroy;override; 
    published 
    { Published declarations } 
    property Columns : Integer read GetColumns write SetColumns default 5; 
    property Images : TStrings read fImages write SetImages; 
    property ThumbHeight: Integer read GetThumbHeight write SetThumbHeight default 100; 
    property ThumbWidth: Integer read GetThumbWidth write SetThumbWidth default 100; 
    property OnImageClick: TNotifyEvent read fOnImageClick write fOnImageClick; 
    end; 

procedure Register; 

implementation 

procedure TViewer.ClearViewer; 
var 
I: Integer; 
begin 
for I := ControlCount-1 downto 0 do 
    TPanel(Components[I]).Free; 
end; 

procedure TViewer.UpdateViewer; 
var 
I,X,Y,C, D: Integer; 
Thumb, btnPnl: TPanel; 
img: TImage; 
btn1, btn2, btn3, btn4: TSpeedButton; 
begin 
self. 
ClearViewer; 
    X:= 0; 
    Y:= 0; 
    C:= 1; 
    D:= 5; 
    Thumb:= nil; 
    for I := 0 to fimages.Count - 1 do 
    begin 
    if fileExists(fimages[I]) then 
    begin 
    Thumb:= TPanel.Create(self); 
    Thumb.Parent:= self; 
    thumb.Tag:= I; 

    Thumb.Caption:= ''; 
    Thumb.Left:= X + D; 
    Thumb.Top:= Y + D; 
    Thumb.Width:= fThumbWidth; 
    Thumb.Height:= fThumbHeight; 
    img:= TImage.Create(Thumb); 
    img.Parent:= Thumb; 
    img.Tag:= I; 
    img.Align:= alClient; 
    img.Stretch:= true; 
    img.OnClick:= fOnImageClick; 
    img.Picture.LoadFromFile(fImages[I]); 
    end; 
    X:= X + Thumb.Width + D; 
    if C = fColumns then 
    begin 
    X:= 0; 
    Y:= Y + Thumb.Height + D; 
    C:= 0; 
    end 
    else 
    Inc(C); 
    end; 
end; 


procedure TViewer.SetImages(Value: TStrings); 
begin 
    fImages.Assign(Value); 
    UpdateViewer; 
end; 

procedure TViewer.SetColumns(Value: Integer); 
begin 
if fColumns <> value then 
    fColumns:= Value; 
end; 

procedure TViewer.SetThumbWidth(Value: Integer); 
begin 
if fThumbWidth <> Value then 
    fThumbWidth:= Value; 
end; 
procedure TViewer.SetThumbHeight(Value: Integer); 
begin 
if fThumbHeight <> Value then 
    fThumbHeight:= Value; 
end; 

function TViewer.GetColumns: Integer; 
begin 
result:= fColumns; 
end; 

function TViewer.GetThumbWidth: Integer; 
begin 
    result:= fThumbWidth; 
end; 

function TViewer.GetThumbHeight: Integer; 
begin 
    result:= fThumbHeight; 
end; 

procedure TViewer.LinesChanged(Sender: TObject); 
begin 
    UpdateViewer; 
end; 

**{procedure TViewer.Resize; 
begin 
    inherited; 
    UpdateViewer; 
end;}** 

constructor TViewer.Create(AOwner: TComponent); 
begin 
    inherited Create(aOwner); 
    DoubleBuffered:= True; 
    fImages := TStringList.Create; 
    TStringList(fImages).OnChange := LinesChanged; 
    fThumbHeight:= 100; 
    fThumbWidth:= 100; 
    fColumns:= 5; 
end; 

destructor TViewer.Destroy; 
begin 
    fImages.Free; 
    inherited; 
end; 
+0

我修复了这一行 - TPanel(Components [I])。 (控制[I])。 – JakeSays 2013-03-10 13:53:23

回答

4

我的代码的代码

for I := ControlCount-1 downto 0 do 
    TPanel(Components[I]).Free; 

是有问题的。实际上,ControlCountControls,因为ComponentCountComponents。你不能混合它们!

你应该这样做:

for I := ControlCount-1 downto 0 do 
    Controls[I].Free; 

不过,我不认为这是问题。

+0

另外,我强烈建议不要做某些东西,除非组件被加载; 'csLoading'值不在'ComponentState'中! [+1] – TLama 2013-03-10 14:20:57

+0

我在设计时并没有做任何事情,它在运行时都是如此,我是否仍然需要考虑这一点? – JakeSays 2013-03-10 15:09:30

+0

但它是负责释放其他控件/组件的父控件吗?它应该不是*主人*? – 2013-03-10 15:42:43