Formuła typu image1.width:=form1.width; nie robi nic ani wewnątrz OnResize […]
Pisałem o ClientWidth
i ClientHeight
. Poza tym to działa:
procedure TMainForm.FormResize(Sender: TObject);
begin
Image.Width := ClientWidth;
Image.Height := ClientHeight;
end;
U mnie śmiga bez problemu.
[…] ani wewn. ChangeBounds. Tak jakby rozmiary okna były jeszcze niedostępne w momencie ich wywoływania (tylko chwilę potem, już po narysowaniu wszystkiego) Nie wiem...
Nowe wymiary okna są dostępne zarówno w zdarzeniu OnResize
, jak i w metodzie ChangeBounds
. W przypadku tego drugiego, jeśli już nadpisujemy tę metodę, to bieżące wymiary są dostępne przed wywołaniem wersji bazowej (za pomocą inherited
), a nowe tuż po tym wywołaniu:
procedure TMainForm.ChangeBounds(ALeft, ATop, AWidth, AHeight: Integer; AKeepBase: Boolean);
begin
// tu jeszcze masz dostęp do starych rozmiarów
inherited ChangeBounds(ALeft, ATop, AWidth, AHeight, AKeepBase);
// a tutaj już do nowych
end;
Problem jednak jest taki, że ta metoda może być wywoływana wielokrotnie zanim obiekt komponentu zostanie utworzony w pamięci, dlatego trzeba to najpierw sprawdzić, zanim zacznie się korzystać z referencji kontrolki.
Drugi problem jest taki, że komponent z obrazkiem nie zostanie dopasowany do rozmiarów okna po pokazaniu okna na ekranie. Formularz się otworzy, ale kontrolka nadal będzie posiadać domyślne wymiary (te z designera) i dopiero wtedy podczas rozciągania okna zacznie ona się zachowywać tak jak chcemy (czyli dopasowywać swój rozmiar do klienta).
Wszystko dlatego, że metoda ChangeBounds
okna jest wywoływana podczas ładowania danych formularza (wtedy jeszcze Image
nie istnieje), ale nie jest wołana podczas wczytywania danych komponentu Image
. Aby to zabezpieczyć, wystarczy nadpisać jeszcze jedną metodę – Loaded
– która wywoływana jest tuż po załadowaniu i skonfigurowaniu formularza, i w niej wywołać ChangeBounds
, przekazując bieżące wymiary.
Cały kod niżej, a w załączniku masz projekt do przetestowania lokalnie:
type
TMainForm = class(TForm)
Image: TImage;
protected
procedure Loaded(); override;
procedure ChangeBounds(ALeft, ATop, AWidth, AHeight: Integer; AKeepBase: Boolean); override;
end;
{..}
procedure TMainForm.Loaded();
begin
inherited Loaded();
ChangeBounds(Left, Top, Width, Height, True);
end;
procedure TMainForm.ChangeBounds(ALeft, ATop, AWidth, AHeight: Integer; AKeepBase: Boolean);
begin
inherited ChangeBounds(ALeft, ATop, AWidth, AHeight, AKeepBase);
if Assigned(Image) then
Image.BoundsRect := Self.ClientRect;
end;