这是我的问题。
我有一个加载DLL的应用程序。我有源和控制主应用程序和DLL。我希望DLL使用与主应用程序中使用的相同的帮助查看器(由System.HelpIntfs.RegisterViewer注册)。
现在,我相信如果DLL和主应用程序都“与运行时包”链接,那么这将自动完成(IIRC)。为了这个问题,让我们假设这个选项不在桌面上(政治......)
我首先研究了在System.HelpIntfs单元中手动分配HelpManager: IHelpManager
变量的可能性。但是变量似乎不可访问(它在实现部分中,并且似乎没有任何过程允许设置它)。
然后我看了TApplication。手动分配FHelpSystem : IHelpSystem
将解决我的问题,但该变量只能通过只读属性访问。
我考虑过将主应用程序的ICustomHelpViewer传递给DLL并用它调用RegisterViewer,但后来我开始担心它会“损坏”,并且当DLL卸载时它可能会“关闭”。
然后我考虑创建另一个ICustomHelpViewer,我将传递给我的DLL,它只是将所有相关调用映射到应用程序的ICustomHelpViewer。我想我应该转发除ShutDown
,SoftShutDown
和NotifyId
之外的所有电话。我是对的吗?
还有更好的选择吗?
答案 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))