Może ktoś ma pomysł jak rozpoznać czy np. na obiekcie TButton znajduje się (umieszczony jest na nim) inny obiekt TButton? (czyli mamy obiekt na obiekcie).
TButton nie może być na obiekcie ponieważ na TButton nie da się nic położyć. Natomiast dwa obiekty typu TButton mogą być w tym samym miejscu np. na formie i efekt będzie taki, że jeden będzie zasłaniał drugi. W takim przypadku jedyne co mi przychodzi do głowy to sprawdzić czy położenie jednego nie pokrywa się z położeniem drugiego
Też tak myślałem, tylko co w przypadku gdy obiekt "górny" jest mniejszy od tego leżącego poniżej?
trzeba sprawdzić każdy przypadek - zasłania całość, zasłania część, itp
Połóż na formie 2 przyciski, jeden mniejszy, drugi większy. Poniższy kod pozwoli sprawdzić, czy jeden przycisk częściowo lub w całości przykrywa drugi (funkcja zwróci true).
procedure TForm1.Button1Click(Sender: TObject);
var
R: TRect;
begin
if IntersectRect(R, Button1.BoundsRect, Button2.BoundsRect)
then ShowMessage('Przyciski nakładają się na obszarze (x1='+IntToStr(R.Left)+', y1='+IntToStr(R.Top)+', x2='+IntToStr(R.Right)+', y2='+IntToStr(R.Bottom)+')')
else ShowMessage('Przyciski nie nakładają się');
end;
JaJanek napisał(a):
Też tak myślałem, tylko co w przypadku gdy obiekt "górny" jest mniejszy od tego leżącego poniżej?
To wtedy "R" będzie odpowiadało BoundsRect przycisku "górnego", bo cały obszar "górnego" przycisku jest obszarem wspólnym obu przycisków.
Dzięki za naprowadzenie na właściwy tor.
Pojawiła się kolejna niewiadoma. Jak rozpoznać wśród nakładających się obiektów, który jest na dole a który do góry.
Stworzyłem pętlę z myślą, że wyrzuci mi te obiekty do ListBox'a. Jednak nie tędy droga. Może ktoś ma jakiś pomysł. Poniżej kod:
procedure TForm1.Button11Click(Sender: TObject);
var
R: TRect;
I, I2 : Integer;
Nazwa: TComponentName;
begin
ListBox1.Items.Clear;
for I:=0 to Pred(Form1.Panel5.ControlCount) do
for I2:=0 to Pred(Form1.Panel5.ControlCount) do
if I > 0 then if I2 >= 1 then
if Form1.Panel5.Controls[I] is TMemo then if Form1.Panel5.Controls[I2] is TMemo then
if form1.Panel5.Controls[I].top <= 100 then if form1.Panel5.Controls[I2].top <= 100 then //obszar mniejszy niż 100
if form1.Panel5.Controls[i].name <> form1.Panel5.Controls[i2].name then
begin
if IntersectRect(R, form1.Panel5.Controls[i].BoundsRect, form1.Panel5.Controls[i2].BoundsRect) then
begin
// nakładają się
if ListBox1.Items.IndexOf(form1.Panel5.Controls[i].name) = -1 then
ListBox1.Items.Add(form1.Panel5.Controls[i].name);
end
else // obszar > 100
begin
// nie nakładają się
end;
end;
end;
Jeżeli masz ustalony punkt, w którym znajduje się dany komponent, to możesz skorzystać z FindVCLWindow, która zwróci instancję komponentu; Podaną metodę możesz wykorzystać dla wszystkich komponentów dziedziczących po klasie TWinControl
, czyli np. dla przycisków;
Nie wiem do czego obecny kod służy, ale sformatuj go, bo jest nieczytelny; Po drugie, aby skrócić nieco kod i wykluczyć ciągłe rzutowanie za pomocą operatora Is - zadeklaruj sobie dwie zmienne, do których wrzucisz instancje komponentów w pętli:
procedure TForm1.Button11Click(Sender: TObject);
var
I, I2: Integer;
memFirst, memSecond: TMemo;
begin
for I := 1 to Panel5.ControlCount - 1 do
for I2 := I + 1 to Panel5.ControlCount - 1 do
if (Panel5.Controls[I] is TMemo) and (Panel5.Controls[I2] is TMemo) then
begin
memFirst := Panel5.Controls[I] as TMemo;
memSecond := Panel5.Controls[I2] as TMemo;
// dalsze instrukcje i operowanie na zmiennych memFirst i memSecond
end;
end;
Pisane z palca, ale powinno działać; Zwróć uwagę na indeksację obu pętli.