Delphi拖拽可以“提升”吗?对接?
我有一个 TPageControl
,其页面都是使用 ManualDock()
附加的各种表单。用户应该能够通过拖动选项卡来重新排列选项卡,这已经可以使用了。然而,也应该可以取消停靠的表单。
现在我有以下代码:
procedure TMainForm.PageControlMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (Button = mbLeft) and (Shift * [ssShift, ssCtrl] = [])
and PageControl.DockSite
then begin
PageControl.BeginDrag(False, 32);
end;
end;
如果按住 Shift 或 Ctrl 键,则将启动停靠操作,否则可以通过拖动来重新排列选项卡他们。
不过,使用按键作为修饰符很尴尬。有没有办法在鼠标光标位于页面控件的选项卡区域之外时取消活动的拖动操作,并开始停靠子窗体?这是 Delphi 2009 的情况。
I have a TPageControl
whose pages are all various forms that are attached using ManualDock()
. The user should be able to rearrange the tabs by dragging them, which works already. It should however also be possible to undock the docked forms.
For now I have the following code:
procedure TMainForm.PageControlMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if (Button = mbLeft) and (Shift * [ssShift, ssCtrl] = [])
and PageControl.DockSite
then begin
PageControl.BeginDrag(False, 32);
end;
end;
If either the Shift or the Ctrl key are held down, then a docking operation will be started, otherwise the tabs can be rearranged by dragging them.
Using the keys as modifiers is awkward though. Is there any way to cancel the active drag operation when the mouse cursor is outside of the tab area of the page control, and start docking the child form? This is with Delphi 2009.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我现在有一个适合我的解决方案,所以我会回答自己 - 也许有人也有这个用途。
让我们从一个小示例应用程序开始,该应用程序创建一个带有 8 个停靠表单的
TPageControl
,并使用允许运行时对选项卡重新排序的代码。选项卡将实时移动,当取消拖动时,活动选项卡索引将恢复为其原始值:将其粘贴到编辑器中并运行它,所有必要的组件及其属性将在运行时创建和设置。
请注意,只有双击选项卡才能取消停靠表单。这也有点难看,无论距选项卡的距离如何,拖动光标都会显示直到释放鼠标左键。当鼠标位于页面控制选项卡区域之外且有几个像素边距时,如果自动取消拖动并取消停靠表单,效果会更好。
这可以通过在页面控件的
OnStartDrag
处理程序中创建自定义DragObject
来实现。在这个对象中,鼠标被捕获,因此拖动时的所有鼠标消息都可以在其中处理。当鼠标光标位于选项卡影响矩形之外时,拖动将被取消,并且会启动活动页面控制表中表单的停靠操作:该类源自
TDragControlObjectEx
,而不是源自TDragControlObject
这样它就会被自动释放。现在,如果在示例应用程序中创建了 TPageControl 的处理程序(并为页面控制对象设置):那么当鼠标移动到距离选项卡足够远时,选项卡拖动将被取消,并且如果活动页面是一个可停靠表单,然后将启动它的停靠操作,仍然可以使用 ESC 键取消。
I have a solution now which works for me, so I'll answer myself - maybe somebody has a use for this too.
Let's start with a small sample application that creates a
TPageControl
with 8 docked forms, with code to allow for runtime reordering of the tabs. Tabs will be moved live, and when the dragging is canceled the active tab index will revert to its original value:Paste this into the editor and run it, all necessary components and their properties will be created and set up at runtime.
Note that undocking the forms is possible only by double-clicking the tabs. It's also somewhat ugly that the drag cursor will be shown until the left mouse button is released, regardless of the distance from the tabs. It would be much better if the dragging was automatically canceled and the form be undocked instead, when the mouse is outside of the page control tab area with a few pixels margin.
This can be achieved by creating a custom
DragObject
in theOnStartDrag
handler of the page control. In this object the mouse is captured, so all mouse messages while dragging can be handled in it. When the mouse cursor is outside of the tab influence rectangle the dragging is canceled, and a docking operation for the form in the active page control sheet is started instead:The class descends from
TDragControlObjectEx
instead of fromTDragControlObject
so that it will be automatically freed. Now if a handler for theTPageControl
in the sample application is created (and set for the page control object):then the tab dragging will be canceled when the mouse moves far enough away from the tabs, and if the active page is a dockable form then a docking operation for it will be started, which can still be canceled with the ESC key.