Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 137

/ вопрос открыт /

Уважаемые эксперты!
У меня тут возник вопрос с интерфейсом моей программы. Мне нужно чтобы какая-либо TPanel крепилась к ближайшему элементу на форме. Ну, например, задуются случайные координаты для TPanel. Необходимо чтобы эта TPanel при запуске программы изменяла свои координаты так чтобы она крепилась к ближайшей границе какого-нибудь другого компонента, например к другой такой же TPanel.

Александр-446 Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Александр-446 (статус: Посетитель)
Вопрос отправлен: 21 октября 2006, 16:23
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Dron

Здравствуйте, Александр!
Я реализовал нечто подобное. Код модуля в приложении. А скриншот примерного расположения элементов в прикреплённом файле.
Однако метод не совсем доработан - иногда встречаются неправильные "прилипания". Но, думаю, сделав по аналогии, Вы разберётесь и доработаете его так, как Вам требуется.
Общая технология:
1) Для каждого элемента определить его положение относительно "двигаемого" элемента - слева от него, справа, сверху или снизу.
2) Для каждого элемента найти расстояние до нашего компонента.
3) Выбрать из расстояний наименьшее.
4) Прицепить наш компонент к тому элементу, расстояние до которого минимально.
Удачи!
К ответу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки ответа)

Приложение:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, StdCtrls, ExtCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. Panel1: TPanel;
  12. Panel2: TPanel;
  13. Panel3: TPanel;
  14. Panel4: TPanel;
  15. Panel: TPanel;
  16. Memo1: TMemo;
  17. Button1: TButton;
  18. procedure Button1Click(Sender: TObject);
  19. function GetDistTo(X,Y,W,H: Integer; PanelT: TPanel): Integer;
  20. procedure PanelMouseDown(Sender: TObject; Button: TMouseButton;
  21. Shift: TShiftState; X, Y: Integer);
  22. private
  23. { Private declarations }
  24. public
  25. { Public declarations }
  26. end;
  27.  
  28. var
  29. Form1: TForm1;
  30.  
  31. implementation
  32.  
  33. {$R *.dfm}
  34.  
  35. function TForm1.GetDistTo(X,Y,W,H: Integer; PanelT: TPanel): Integer;
  36. var W1,H1,X1,Y1,L: Integer;
  37. begin
  38. W1:=PanelT.Width;
  39. H1:=PanelT.Height;
  40. X1:=PanelT.Left;
  41. Y1:=PanelT.Top;
  42. If (X1+W1) < X Then {&#207;&#224;&#237;&#229;&#235;&#252; &#241;&#235;&#229;&#226;&#224; &#238;&#242; &#237;&#224;&#248;&#229;&#233;}
  43. L:=X-X1-W1;
  44. If (X+W) < X1 Then {&#241;&#239;&#240;&#224;&#226;&#224;}
  45. L:=X1-W-X;
  46. If (Y1+H) < Y Then {&#241;&#226;&#229;&#240;&#245;&#243;}
  47. L:=Y-H-Y1;
  48. If (Y+H) < Y1 Then {&#241;&#237;&#232;&#231;&#243;}
  49. L:=Y1-H-Y;
  50. Result:=L;
  51. end;
  52.  
  53. procedure TForm1.Button1Click(Sender: TObject);
  54. Var X,Y,W,H,I,Min,MinI: Integer;
  55. Dist: Array Of Integer;
  56. Panels: Array Of Integer;
  57. begin
  58. Memo1.Clear;
  59. {&#202;&#238;&#238;&#240;&#228;&#232;&#237;&#224;&#242;&#251; &#232; &#240;&#224;&#231;&#236;&#229;&#240;&#251; &#237;&#224;&#248;&#229;&#233; &#239;&#224;&#237;&#229;&#235;&#232;}
  60. X:=Panel.Left;
  61. Y:=Panel.Top;
  62. W:=Panel.Width;
  63. H:=Panel.Height;
  64. SetLength(Dist,4);
  65. SetLength(Panels,4);
  66. {&#206;&#239;&#240;&#229;&#228;&#229;&#235;&#255;&#229;&#236; &#240;&#224;&#241;&#241;&#242;&#238;&#255;&#237;&#232;&#255; &#228;&#238; &#234;&#224;&#230;&#228;&#238;&#233; &#232;&#231; &#228;&#240;&#243;&#227;&#232;&#245; &#239;&#224;&#237;&#229;&#235;&#229;&#233;}
  67. For I:=1 To 4 Do
  68. Begin
  69. Dist[I-1]:=GetDistTo(X,Y,W,H,TPanel(FindComponent('Panel'+IntToStr(I))));
  70. Panels[I-1]:=I;
  71. Memo1.Lines.Add('&#208;&#224;&#241;&#241;&#242;&#238;&#255;&#237;&#232;&#229; &#228;&#238; Panel'+IntToStr(I)+': '+IntToStr(Dist[I-1]));
  72. End;
  73. {&#210;&#229;&#239;&#229;&#240;&#252; &#237;&#224;&#245;&#238;&#228;&#232;&#236; &#234;&#240;&#224;&#242;&#247;&#224;&#233;&#248;&#229;&#229; &#240;&#224;&#241;&#241;&#242;&#238;&#255;&#237;&#232;&#229;}
  74. MinI:=0;
  75. Min:=Dist[0];
  76. For I:=0 To 4-1 Do
  77. If Dist[I] < Min Then
  78. Begin
  79. Min:=Dist[I];
  80. MinI:=I;
  81. End;
  82. X:=TPanel(FindComponent('Panel'+IntToStr(MinI+1))).Left;
  83. Y:=TPanel(FindComponent('Panel'+IntToStr(MinI+1))).Top;
  84. W:=TPanel(FindComponent('Panel'+IntToStr(MinI+1))).Width;
  85. H:=TPanel(FindComponent('Panel'+IntToStr(MinI+1))).Height;
  86.  
  87. If Panel.Left > X+W Then {&#228;&#226;&#232;&#227;&#224;&#229;&#236; &#226;&#235;&#229;&#226;&#238;}
  88. Panel.Left:=X+W;
  89. If Panel.Left+Panel.Width < X Then {&#228;&#226;&#232;&#227;&#224;&#229;&#236; &#226;&#239;&#240;&#224;&#226;&#238;}
  90. Panel.Left:=X-Panel.Width;
  91.  
  92.  
  93. If Panel.Top > Y+H Then {&#226;&#226;&#229;&#240;&#245;}
  94. Panel.Top:=Y+H;
  95. If Panel.Top+Panel.Height < Y Then {&#226;&#237;&#232;&#231;}
  96. Panel.Top:=Y-Panel.Height;
  97. end;
  98.  
  99. procedure TForm1.PanelMouseDown(Sender: TObject; Button: TMouseButton;
  100. Shift: TShiftState; X, Y: Integer);
  101. var
  102. pt : TPoint;
  103. begin
  104. ReleaseCapture;
  105. SendMessage(Panel.Handle, WM_SYSCOMMAND, 61458, 0);
  106. {$IFNDEF WIN32}
  107. GetCursorPos(pt);
  108. SendMessage(Panel.Handle,
  109. WM_LBUTTONUP,
  110. MK_CONTROL,
  111. Longint(pt));
  112. {$ENDIF}
  113. Button1.Click;
  114. end;
  115.  
  116. end.


Ответ отправил: Dron (статус: Студент)
Время отправки: 21 октября 2006, 18:37
Оценка за ответ: 5


Мини-форум вопроса

Всего сообщений: 3; последнее сообщение — 21 октября 2006, 17:53; участников в обсуждении: 2.
Dron

Dron (статус: Студент), 21 октября 2006, 17:20 [#1]:

А компоненты однородные? Т.е. все TPanel или могут быть кнопки и всё что угодно?
Также желательно, чтобы компоненты были заранее известны и имели имена одного шаблона (например, "Panel_N"), где N = 1, 2, 3...
С уважением.
Александр-446

Александр-446 (статус: Посетитель), 21 октября 2006, 17:30 [#2]:

Однородные и все содержат имена одного шаблона. Точно как ты говоришь.
Dron

Dron (статус: Студент), 21 октября 2006, 17:53 [#3]:

Ок. Попробую сделать такую вещь. По-моему, это не очень сложно.
С уважением.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:49
Выполнено за 0.02 сек.