Jak rozpoznać, czy jeden Button nachodzi na drugi?

0

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).

2

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

0

Też tak myślałem, tylko co w przypadku gdy obiekt "górny" jest mniejszy od tego leżącego poniżej?

0

trzeba sprawdzić każdy przypadek - zasłania całość, zasłania część, itp

1

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.

0

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;
0

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1