Проектирование графического интерфейса пользователя______________269

Например, прием контейнером Panell любой панели, кроме Рапе16, обеспечи-
вается оператором:

Accept = Source->Control != Panel6;

Параметр Accept будет равен true — значению по умолчанию, только если пе-
ретаскивается не Panel6. Почти того же результата вы достигали ранее в обработ-
чике события OnGetSiteInfo. Но если вы проведете соответствующие эксперимен-
ты, то заметите различие в поведении перетаскиваемого объекта. При использова-
нии события OnGetSiteInfo рамка перетаскиваемого компонента не изменяется
попадая в контейнер, т.е. пользователь видит, что данное окно в этот контейнер не
может быть встроено. Если он отпустит перетаскиваемый компонент над контейне-
ром, то он разместится поверх контейнера в виде плавающего окна. Если же вы ис-
пользуете событие OnDockOver, то рамка перетаскиваемого окна при перемеще-
нии над контейнером ведет себя так, как будто окно можно встроить. Но если вы
отпускаете окно над контейнером, то оно не только не встроится, но просто не
сдвинется с прежнего места. Поэтому лучше для отказа от размещения использо-
вать событие OnGetSiteInfo, которое не вводит пользователя в заблуждение. А со-
бытие OnDockOver можно использовать для других целей, например, для инфор-
мации пользователя о том, что встраивать окно в этот контейнер нельзя, или, как
описано ниже, для управления встраиванием.

Объект перетаскивания Source типа TDragDockObject имеет свойство Do-
ckRect типа TRect, описывающее перемещаемую рамку. Вы можете управлять ею.
Например, если вы хотите, чтобы ваша Рапе15 вела себя наподобие панели Micro-
soft Office, которая может прижиматься к одной из сторон окна или перемещаться
в середине окна в виде квадратной панели, вы можете, установив предварительно в
форме вашего приложения DockSite равным true, написать обработчик события
OnDockOver в виде:

int x = ClientOrigin.x;

int у = ClientOrigin.y;

if (Source->Control == PanelS)
{
if (Source->DockRect-Left <= x)

Source->DockRect = Rect(x,y,x+25,y+ClientHeight);

else if (Source->DockRect.Right >= x+ClientWidth)

Source->DockRect = Rect(x+ClientWidth-25,y,x+ClientWidth,y+

ClientHeight) ;

else if (Source->DockRect.Top <= y)

Source->DockRect = Rect(x,y,x+ClientWidth,y+25);

else if (Source->DockRect.Bottom >= y+ClientHeight)

Source->DockRect = Rect(x,y+ClientHeight-25,x+ClientWidth,y+

ClientHeight);

else Source->DockRect = Rect(Source->DockRect .'Left,Source->

DockRect.Top, Source->DockRect.Left+100,
Source->DockRect.Top+100) ;

В этом коде x и у — это не параметры Х и Y, передаваемые в обработчик через
заголовок процедуры, а координаты левого верхнего угла клиентской области фор-
мы. A ClientWidth и ClientHeight — это ширина и высота ее клиентской области.

Если в процессе буксировки панели Рапе15 ее координаты выходят за пределы
клиентской области формы, то панель вытягивается вдоль соответствующего края
приемника, а ее ширина равна 25. При перемещении панели внутри окна она пред-
ставляется квадратом со стороной 100.

Еще одно событие, возникающее в компоненте-приемнике — OnDockDrop.
Это событие возникает в момент окончания перетаскивания клиента над приемни-
ком. Оно аналогично событию OnDragDrop в технологии Drag&Drop. Заголовок
соответствующего обработчика имеет вид: