在主应用程序和DLL之间共享ICustomHelpViewer

时间:2014-10-07 15:14:53

标签: delphi delphi-xe4

这是我的问题。

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

现在,我相信如果DLL和主应用程序都“与运行时包”链接,那么这将自动完成(IIRC)。为了这个问题,让我们假设这个选项不在桌面上(政治......)

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

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

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

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

还有更好的选择吗?

1 个答案:

答案 0 :(得分:0)

(通过写我的问题,我想到了这个选项。我以为我仍然会发布问题,看看是否有更好的选择。)

所以,我选择的选项实际上是设置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))