我使用对接模块在Delphi(BDS 2006)和JVCL库中编程。我有一个问题 - 如果控件具有属性DragKind = dkDock
和DragMode = dmAutomatic
,那么莫名其妙的TJvDockServer组件将控件作为客户端并提供对接。这是错误的,因为,正如我所发现的,JVCL的对接函数通常只控制包含组件类TJvDockClient的类TForm。我想知道是否有可能以某种方式阻止TJvDockServer对接其类与TForm不同的控件?在Delphi中典型的每个事件对接期间称为OnGetSiteInfo dock,可以过滤客户端,但TJvDockServer中没有此类事件。
答案 0 :(得分:2)
属性DragKind和DragMode是标准的VCL属性。对接内置于VCL中,从查看它看起来,如果不涉及任何Jedi代码,它似乎工作得很好。
在VCL中已经内置了除表单之外的其他东西的功能。因此,你发现这个莫名其妙的建议我,你认为绝地增加了与VCL的对接。不,它只是添加了一些漂亮的东西,如“标签式笔记本对接”和“联合区域”与假窗口标题栏。
话虽如此,Forms也是继承自TCustomControl,事实上任何TCustomControl都可以停靠。就像VCl一样,你可以拖动和停靠在TPanels之上。好吧,这是一个古怪的功能,你的面板可以在运行时变成你的形式,但如果你不相信我,试试吧。这是VCL对你做的,而不是绝地。
如果你的智慧,你想阻止任何不是TForm的东西,我认为你可以。 你肯定可以吗?的更新即可。是的你可以。 OnDockOver可以在任何要阻止停靠的面板上阻止停靠。 Jedi JvDockPanels的技巧是你在设计时没有看到它们,所以你需要在运行时通过代码挂钩来访问它们。
就像普通的TPanels一样,JvDockPanels有一个TPanel.OnDockOver事件,如果你想检查对接的东西,并将Accept设置为false,它将被阻止对接。
好的,这有效:
type
TCustomControlAccess = class(TCustomControl);
procedure TMainForm.FormCreate(Sender: TObject);
begin
TCustomControlAccess(dockServer.TopDockPanel).OnDockOver := MyDockOverEvent;
TCustomControlAccess(dockServer.CustomDockPanel).OnDockOver := MyDockOverEvent;
...
end;
JvDockPanel.OnDockOver面板事件会触发,但你需要像上面的hack那样求助于实际处理事件。
更新以前认为无法阻止此操作。但是我错了。想出来了。
答案 1 :(得分:0)
虽然我无法准确再现您在Delphi XE2中的行为,但通常我似乎设法阻止JediVCL组件的VCL-frag-n-drop。
也许这不是最好的方式,但我不知道哪个是框架创建者的原创想法。
http://wiki.delphi-jedi.org/wiki/JVCL_Help:TJvDockServer声明只有表格才能停靠。没有强制执行,只是硬连线的JVCL检查例程总是被调用。
unit JvDockSupportControl;
....
TJvDockCustomControl = class(TJvCustomControl)
....
protected
procedure GetSiteInfo(Client: TControl; var InfluenceRect: TRect;
MousePos: TPoint; var CanDock: Boolean); override;
...........
function TJvDockCustomControl.GetJvDockManager: IJvDockManager;
begin
// Result := IJvDockManager(DockManager);
DockManager.QueryInterface(IJvDockManager, Result);
end;
procedure TJvDockCustomControl.GetSiteInfo(Client: TControl; var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
var jdm: IJvDockManager; idm: IDockManager;
begin
idm := DockManager;
if nil <> idm then
idm.QueryInterface(IJvDockManager, jdm);
if nil = jdm
then CanDock := false
else jdm.GetSiteInfo(Client,InfluenceRect, MousePos, CanDock);
end;
unit JvDockTree;
.....
procedure TJvDockTree.GetSiteInfo(Client: TControl;
var InfluenceRect: TRect; MousePos: TPoint; var CanDock: Boolean);
begin
CanDock := IsDockable(DockSite, Client);
If CanDock then begin
GetWindowRect(DockSite.Handle, InfluenceRect);
InflateRect(InfluenceRect, DefExpandoRect, DefExpandoRect);
end;
end;