将 JEDI VCL 库与 Delphi 一起使用,我在主窗体上放置了一个 JvDockServer,在另一个应该停靠到主窗体上,我有使用停靠样式 JvDockVIDVCStyle 的 JvDockClient。
虽然停靠效果很好,但我希望在客户端表单从停靠模式更改为非停靠(浮动)模式时收到通知。
更新JVCL 现在已修改为包含内置的此功能!现在,当您停靠表单时,会触发 TForm 的内置事件。查看 JEDI JVCL 中的 DockingInCode 演示,该演示现在(截至 2012 年 3 月 27 日)包含 Docking 和 Undocking 事件触发的示例。现在在停靠时会触发 TForm.OnEndDock,就像TForm.OnUnDock
在取消停靠时一样。对不起名字,那些区域已经在TForm
我没有选择它们!
由于历史原因,旧答案:
当表单浮动时,您希望收到通知。TForm 已经有OnUnDock
and OnEndDock
,但是当您使用 Jedi VCL Dock Manager 停靠和取消停靠时,这些(遗憾地)不会被触发。
我能想到的最好的方法是修改 JVCL。
修改JvDockSupportControl.pas,方法TJvDockCustomControl.WndProc:
procedure TJvDockCustomControl.WndProc(var Msg: TMessage);
var
CMUnDockClient: TCMUnDockClient;
DockableForm: TJvDockableForm;
allow:Boolean;
begin
if Msg.Msg = CM_UNDOCKCLIENT then
begin
CMUnDockClient := TCMUnDockClient(Msg);
// new code starts here
if CMUnDockClient.Client is TForm then begin
allow := true;
if Assigned(TForm(CMUnDockClient.Client).OnUnDock) then
TForm(CMUnDockClient.Client).OnUnDock(Self,CMUnDockClient.Client,TWinControl(nil),allow);
// if not allow then
// exit; // currently JvDocking has already deleted you from the dock tree, so we can't honor this.
end;
// new code ends here
if CMUnDockClient.Client is TJvDockableForm then
begin
...
不幸的是,这是对组件设计的疏忽,如果您将其登录到Jedi Bug Tracker并在此处发布指向它的链接。遗憾的是,JvDocking 的内部结构很复杂,但上面的 hack 可能会让你从今天开始。
编辑 JVCL 的替代方法是根据您喜欢使用的 Dock 样式制作自己的样式,并向其中添加 OnDock 和 OnFloat 事件。例如,如果您使用 VID (Visual Interdev) 停靠样式,请将 JvDockVIDStyle.pas 复制到您自己的单元中,然后将其重命名为其他名称。
在代码中找到这个过程:
procedure TJvDockVIDTree.WindowProc(var Msg: TMessage);
将现有代码保留在该函数中,并在底部添加以下内容:
if (Msg.msg =CM_UNDOCKCLIENT)and Assigned(FOnUndock) then
FOnUndock( TObject(Msg.Client))
我认为我应该将上面的内容写一个更好的版本并将其放入 JVCL JvDocking 中,因为它是一个直观的东西。此外,可能应该使 OnEndDock 起作用。OnStartDock 与 JvDocking 不兼容,所以我不能添加它。