|
Вопрос # 137/ вопрос открыт / |
|
Уважаемые эксперты!
У меня тут возник вопрос с интерфейсом моей программы. Мне нужно чтобы какая-либо TPanel крепилась к ближайшему элементу на форме. Ну, например, задуются случайные координаты для TPanel. Необходимо чтобы эта TPanel при запуске программы изменяла свои координаты так чтобы она крепилась к ближайшей границе какого-нибудь другого компонента, например к другой такой же TPanel.
 |
Вопрос задал: Александр-446 (статус: Посетитель)
Вопрос отправлен: 21 октября 2006, 16:23
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: Dron
Здравствуйте, Александр!
Я реализовал нечто подобное. Код модуля в приложении. А скриншот примерного расположения элементов в прикреплённом файле.
Однако метод не совсем доработан - иногда встречаются неправильные "прилипания". Но, думаю, сделав по аналогии, Вы разберётесь и доработаете его так, как Вам требуется.
Общая технология:
1) Для каждого элемента определить его положение относительно "двигаемого" элемента - слева от него, справа, сверху или снизу.
2) Для каждого элемента найти расстояние до нашего компонента.
3) Выбрать из расстояний наименьшее.
4) Прицепить наш компонент к тому элементу, расстояние до которого минимально.
Удачи! К ответу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки ответа)
Приложение: Переключить в обычный режим- unit Unit1;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, ExtCtrls;
-
- type
- TForm1 = class(TForm)
- Panel1: TPanel;
- Panel2: TPanel;
- Panel3: TPanel;
- Panel4: TPanel;
- Panel: TPanel;
- Memo1: TMemo;
- Button1: TButton;
- procedure Button1Click(Sender: TObject);
- function GetDistTo(X,Y,W,H: Integer; PanelT: TPanel): Integer;
- procedure PanelMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
- function TForm1.GetDistTo(X,Y,W,H: Integer; PanelT: TPanel): Integer;
- var W1,H1,X1,Y1,L: Integer;
- begin
- W1:=PanelT.Width;
- H1:=PanelT.Height;
- X1:=PanelT.Left;
- Y1:=PanelT.Top;
- If (X1+W1) < X Then {Ïàíåëü
ñëåâà îò
íàøåé}
- L:=X-X1-W1;
- If (X+W) < X1 Then {ñïðàâà}
- L:=X1-W-X;
- If (Y1+H) < Y Then {ñâåðõó}
- L:=Y-H-Y1;
- If (Y+H) < Y1 Then {ñíèçó}
- L:=Y1-H-Y;
- Result:=L;
- end;
-
- procedure TForm1.Button1Click(Sender: TObject);
- Var X,Y,W,H,I,Min,MinI: Integer;
- Dist: Array Of Integer;
- Panels: Array Of Integer;
- begin
- Memo1.Clear;
- {Êîîðäèíàòû
è ðàçìåðû
íàøåé
ïàíåëè}
- X:=Panel.Left;
- Y:=Panel.Top;
- W:=Panel.Width;
- H:=Panel.Height;
- SetLength(Dist,4);
- SetLength(Panels,4);
- {Îïðåäåëÿåì
ðàññòîÿíèÿ
äî êàæäîé
èç äðóãèõ
ïàíåëåé}
- For I:=1 To 4 Do
- Begin
- Dist[I-1]:=GetDistTo(X,Y,W,H,TPanel(FindComponent('Panel'+IntToStr(I))));
- Panels[I-1]:=I;
-
Memo1.Lines.Add('Ðàññòîÿíèå
äî Panel'+IntToStr(I)+': '+IntToStr(Dist[I-1]));
- End;
- {Òåïåðü
íàõîäèì
êðàò÷àéøåå
ðàññòîÿíèå}
- MinI:=0;
- Min:=Dist[0];
- For I:=0 To 4-1 Do
- If Dist[I] < Min Then
- Begin
- Min:=Dist[I];
- MinI:=I;
- End;
- X:=TPanel(FindComponent('Panel'+IntToStr(MinI+1))).Left;
- Y:=TPanel(FindComponent('Panel'+IntToStr(MinI+1))).Top;
- W:=TPanel(FindComponent('Panel'+IntToStr(MinI+1))).Width;
- H:=TPanel(FindComponent('Panel'+IntToStr(MinI+1))).Height;
-
- If Panel.Left > X+W Then {äâèãàåì
âëåâî}
- Panel.Left:=X+W;
- If Panel.Left+Panel.Width < X Then
{äâèãàåì
âïðàâî}
- Panel.Left:=X-Panel.Width;
-
-
- If Panel.Top > Y+H Then {ââåðõ}
- Panel.Top:=Y+H;
- If Panel.Top+Panel.Height < Y Then {âíèç}
- Panel.Top:=Y-Panel.Height;
- end;
-
- procedure TForm1.PanelMouseDown(Sender: TObject; Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- var
- pt : TPoint;
- begin
- ReleaseCapture;
- SendMessage(Panel.Handle, WM_SYSCOMMAND, 61458, 0);
- {$IFNDEF WIN32}
- GetCursorPos(pt);
- SendMessage(Panel.Handle,
- WM_LBUTTONUP,
- MK_CONTROL,
- Longint(pt));
- {$ENDIF}
- Button1.Click;
- end;
-
- end.
 |
Ответ отправил: Dron (статус: Студент)
Время отправки: 21 октября 2006, 18:37
Оценка за ответ: 5
|
Мини-форум вопроса
Всего сообщений: 3; последнее сообщение — 21 октября 2006, 17:53; участников в обсуждении: 2.
|
Dron (статус: Студент), 21 октября 2006, 17:20 [#1]:
А компоненты однородные? Т.е. все TPanel или могут быть кнопки и всё что угодно?
Также желательно, чтобы компоненты были заранее известны и имели имена одного шаблона (например, "Panel_N"), где N = 1, 2, 3...
С уважением.
|
|
Александр-446 (статус: Посетитель), 21 октября 2006, 17:30 [#2]:
Однородные и все содержат имена одного шаблона. Точно как ты говоришь.
|
|
Dron (статус: Студент), 21 октября 2006, 17:53 [#3]:
Ок. Попробую сделать такую вещь. По-моему, это не очень сложно.
С уважением.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|