2

我正在使用对接模块在 Delphi (BDS 2006) 和 JVCL 库中编程。我有一个问题 - 如果控件具有属性DragKind = dkDockDragMode = dmAutomatic,那么 TJvDockServer 组件莫名其妙地认为控件既是客户端又提供对接。这是错误的,因为我发现,JVCL 的对接功能通常只控制包含组件类 TJvDockClient 的类 TForm。我想知道是否有可能以某种方式阻止 TJvDockServer 停靠类与 TForm 不同的控件?在 Delphi 中,每个事件的典型停靠期间称为 OnGetSiteInfo 停靠,并且可以过滤客户端,但在 TJvDockServer 中没有此类事件。

4

2 回答 2

2

属性 DragKind 和 DragMode 是标准 VCL 属性。对接是内置在 VCL 中的,从外观上看,它似乎在不涉及任何绝地代码的情况下工作得很好。

VCL 中已经内置了停靠表单以外的其他内容的能力。因此,您发现这种莫名其妙的情况向我表明您认为 Jedi 添加了对 VCL 的对接。不,它只是添加了一些漂亮的东西,比如“标签式笔记本对接”和带有假窗口标题栏的“联合区域”。

话虽如此,Forms 也是从 TCustomControl 继承的,实际上任何 TCustomControl 都可以停靠。就像 VCl 让您可以拖动和停靠并降落在 TPanel 上一样。好吧,这是一个古怪的功能,你的面板可以在运行时变成你的表单,但如果你不相信我,试试看。是 VCL 对你这样做,而不是 Jedi。

如果以你的智慧,你想阻止任何不是 TForm 的东西,我认为你可以。你肯定能对吗? 更新。是的你可以。OnDockOver 可以很好地阻止停靠在您想要阻止停靠的任何面板上。Jedi JvDockPanel 的诀窍在于您在设计时看不到它们,因此您需要通过在运行时将它们连接到代码中来访问它们的事件。

就像普通的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 的 hack 来实际处理事件。

更新之前认为没有办法阻止这一点。但是我错了。弄清楚了。

于 2012-08-31T20:38:50.060 回答
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;

http://issuetracker.delphi-jedi.org/view.php?id=5271

http://issuetracker.delphi-jedi.org/view.php?id=5974

于 2012-09-05T06:02:05.917 回答