Вопрос пользователя связан с необходимостью оптимизации процесса перетаскивания вкладок в компоненте TPageControl в среде Delphi 2009. Пользователь уже реализовал возможность перетаскивания вкладок, но хочет добавить функционал отстыковки форм, при этом желательно избегать использования модификаторов клавиш Shift или Ctrl для запуска операции отстыковки.
Решение проблемы
Для решения проблемы пользователя предлагается создать кастомный объект перетаскивания, который будет обрабатывать сообщения мыши в процессе перетаскивания. Если курсор мыши покидает область вкладок, процесс перетаскивания будет отменён, и начнётся операция отстыковки формы.
В примере кода ниже представлена реализация такого объекта:
type
TConvertDragToDockHelper = class(TDragControlObjectEx)
strict private
fPageControl: TPageControl;
fPageControlTabArea: TRect;
protected
procedure WndProc(var AMsg: TMessage); override;
public
constructor Create(AControl: TControl); override;
end;
constructor TConvertDragToDockHelper.Create(AControl: TControl);
var
Item0Rect, ItemLastRect: TRect;
begin
inherited;
fPageControl := AControl as TPageControl;
if fPageControl.PageCount > 0 then begin
// Получение прямоугольников первого и последнего вкладки
fPageControl.Perform(TCM_GETITEMRECT, 0, LPARAM(@Item0Rect));
fPageControl.Perform(TCM_GETITEMRECT, fPageControl.PageCount - 1,
LPARAM(@ItemLastRect));
// Вычисление области валидной для перетаскивания (включая некоторый отступ вокруг вкладок)
fPageControlTabArea := Rect(
Min(Item0Rect.Left, ItemLastRect.Left) - MarginX,
Min(Item0Rect.Top, ItemLastRect.Top) - MarginY,
Max(Item0Rect.Right, ItemLastRect.Right) + MarginX,
Max(Item0Rect.Bottom, ItemLastRect.Bottom) + MarginY);
end;
end;
procedure TConvertDragToDockHelper.WndProc(var AMsg: TMessage);
var
MousePos: TPoint;
CanUndock: boolean;
begin
inherited;
if AMsg.Msg = WM_MOUSEMOVE then begin
MousePos := fPageControl.ScreenToClient(Mouse.CursorPos);
// Отмена перетаскивания, если курсор вне области вкладок с отступами
// Опционально начало отстыковки прикреплённой формы (может быть отменено с помощью [ESC])
if not PtInRect(fPageControlTabArea, MousePos) then begin
fPageControl.EndDrag(False);
CanUndock := fPageControl.DockSite and (fPageControl.ActivePage <> nil)
and (fPageControl.ActivePage.ControlCount > 0)
and (fPageControl.ActivePage.Controls[0] is TForm)
and (TForm(fPageControl.ActivePage.Controls[0]).DragKind = dkDock);
if CanUndock then
fPageControl.ActivePage.Controls[0].BeginDrag(False);
end;
end;
end;
Данный класс наследуется от TDragControlObjectEx, чтобы автоматически освобождаться. Затем, в обработчике события начала перетаскивания для TPageControl, необходимо создать экземпляр этого класса:
procedure TForm1.PageControlStartDrag(Sender: TObject; var ADragObject: TDragObject);
begin
// Не отменять перетаскивание, если оно не разрешено для компонента TPageControl
if (ADragObject = nil) and fPageControl.DockSite then
ADragObject := TConvertDragToDockHelper.Create(fPageControl);
end;
Таким образом, перетаскивание вкладок будет автоматически отменено, когда курсор выйдет за пределы области вкладок, и начнётся операция отстыковки формы, если это возможно.
Подтверждённый ответ
Предложенное решение позволяет пользователю перетаскивать вкладки и отстыковывать формы, не используя модификаторы клавиш. Отстыковка активируется автоматически, когда курсор мыши покидает область вкладок.
Альтернативный ответ
В альтернативном ответе пользователь предложил свой вариант решения, который также позволяет перетаскивать вкладки и отстыковывать формы, но с использованием двойного клика по вкладке для запуска операции отстыковки. Это решение также включает в себя создание кастомного объекта перетаскивания, который обрабатывает сообщения мыши для корректного отображения процесса перетаскивания или отстыковки в зависимости от положения курсора.
Заключение
Оптимизация процесса перетаскивания вкладок с возможностью отстыковки форм в TPageControl в Delphi 2009 достигается путём создания кастомного объекта перетаскивания, который обрабатывает сообщения мыши и автоматически переключается между режимами перетаскивания и отстыковки в зависимости от положения курсора.
Вопрос связан с оптимизацией процесса перетаскивания вкладок и добавлением функции отстыковки форм в компоненте TPageControl для Delphi 2009, без использования модификаторов клавиш.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.