2013-03-10 50 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