【问题标题】:Sharing ICustomHelpViewer between main application and DLL在主应用程序和 DLL 之间共享 ICustomHelpViewer
【发布时间】:2014-10-07 15:14:52
【问题描述】:

这是我的问题。

我有一个加载 DLL 的应用程序。我有源代码并控制主应用程序和 DLL。我希望 DLL 使用与主应用程序中使用的帮助查看器相同的帮助查看器(由 System.HelpIntfs.RegisterViewer 注册)。

现在,我相信如果 DLL 和主应用程序都“与运行时包链接”,那几乎可以自动完成 (IIRC)。为了这个问题,让我们假设这个选项不在讨论范围内(政治......)

我首先研究了在 System.HelpIntfs 单元中手动分配 HelpManager: IHelpManager 变量的可能性。但是该变量似乎无法访问(它位于实现部分,似乎没有任何程序允许设置它)。

然后我查看了 TApplication。手动分配FHelpSystem : IHelpSystem 可以解决我的问题,但该变量只能通过只读属性访问。

我曾考虑将主应用程序的 ICustomHelpViewer 传递给 DLL 并使用它调用 RegisterViewer,但后来我开始担心它会“损坏”,并且在 DLL 卸载时它可能会“关闭”。

然后我考虑创建另一个 ICustomHelpViewer,我将它传递给我的 DLL,它将所有相关调用映射到应用程序的 ICustomHelpViewer。我想我应该转发除ShutDownSoftShutDownNotifyId 之外的所有呼叫。我说的对吗?

还有更好的选择吗?

【问题讨论】:

  • 我想我会这样做: 1. 不要在 DLL 中包含帮助查看器单元,这样就不会注册帮助管理器。 2. 为 DLL 的Application 对象添加一个OnHelp 事件处理程序。 3. 将OnHelp 事件处理程序委托给主机可执行文件的Application.HelpCommand

标签: delphi delphi-xe4


【解决方案1】:

(写到一半的时候,我想到了这个选项。我想我还是会发布这个问题,看看是否有更好的建议。)

所以,我选择的选项实际上是设置 TApplication.FHelpSystem。作为一个老前辈,我并没有马上想到私有变量不再那么私有了。

在我的主应用程序中,我调用 System.HelpIntfs.GetHelpSystem 来获取对我传递给我的 DLL 的主应用程序帮助系统的引用。

在我的 DLL 中,我通过 RTTI 设置了 TApplication 的 FHelpSystem。我使用以下功能:

procedure SetRttiField(AInstance : TObject; const AFieldName : string; AValue : TValue);
var
  vRTTI : TRttiContext;
  vRTTIType : TRttiType;
  vRttiField : TRttiField;
begin
  vRTTI := TRttiContext.create;

  vRttiType := vRTTI.GetType(AInstance.ClassInfo);
  if not Assigned(vRttiType) then
    EXIT;

  vRttiField := vRTTIType.GetField(AFieldName);
  if not Assigned(vRttiField) then
    EXIT;

  vRttiField.SetValue(AInstance, AValue);
end;

然后这样称呼它:

SetRttiField(Application, 'FHelpSystem', TValue.From(aHelpSystem))

【讨论】:

  • 您不需要 RTTI。您可以使用助手破解它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
  • 1970-01-01
  • 2017-09-11
相关资源
最近更新 更多