| 
| 
 | Вопрос # 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;beginMemo1.Clear;{Êîîðäèíàòû
è ðàçìåðû
íàøåé
ïàíåëè}X:=Panel.Left;Y:=Panel.Top;W:=Panel.Width;H:=Panel.Height;SetLength(Dist,4);SetLength(Panels,4);{Îïðåäåëÿåì
ðàññòîÿíèÿ
äî êàæäîé
èç äðóãèõ
ïàíåëåé}For I:=1 To 4 DoBegin  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);varpt : TPoint;beginReleaseCapture;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]:Ок. Попробую сделать такую вещь. По-моему, это не очень сложно. С уважением. |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |