下面的代码是从我在设计时做的事情简化而来的。D7的BPL。
更新:自从发布这篇文章以来,我找到了一种方法来完成我想要的事情,即只需向表单发送一条WM_Close消息,但我仍然有兴趣知道是否有更"官方"的方法可以做到这一点,因为使用WM_Close似乎有可能使 IDE 出错。
我试图在这段代码中做的所有导致我问题的事情是关闭在 IDE 中打开的所有文件,,然后打开特定的 .恰好具有关联的 pas 文件。Dfm 文件。 我不想要 .Dfm 要在屏幕上打开,所以我正在尝试关闭它,而不关闭 .Pas文件也是 - 我只想要IDE表单设计器和这个表单。
最终,我发现了如何通过 OTA + NTA 服务在我的 .BPL的代码,天真地,但由于缺乏任何其他明显的方法,我尝试调用.通过此片段关闭它。
AForm := TForm(INTAComp.GetComponent);
AForm.Close;
但是,窗体不会关闭。 我已经从 CPU 窗口跟踪到 TCustomForm.Close显然,它没有关闭的原因是它的可见属性已经是 False。 这也是在AForm.Close之前评估Visible的回报。
在AForm.Close之前评估其各种其他属性告诉我,- 它的主人是零但是- 它有一个显然有效的窗口句柄//啊![便士掉落的声音...见上文更新]
我敢说这与 IDE 的窗体设计器的工作方式有关。
我的问题很简单:我需要在我的代码中做什么才能关闭表单,就像我简单地单击其框架上的 [x] 按钮时所做的那样?
顺便说一句,我已经确认我通过 AForm 获得的表单实例 := [...] 是屏幕上的实例,方法是在 OI 中更改屏幕上实例的标题。
procedure TOTAForm.CloseAForm;
var
IServices : IOTAServices;
IActionServices : IOTAActionServices;
IModuleServices : IOTAModuleServices;
IEditorServices : IOTAEditorServices60;
IModule : IOTAModule;
i : Integer;
IEditor : IOTAEditor;
ISourceEditor : IOTASourceEditor;
IFormEditor : IOTAFormEditor;
IComponent : IOTAComponent;
INTAComp : INTAComponent;
AForm : TForm;
begin
IServices := BorlandIDEServices as IOTAServices;
IServices.QueryInterface(IOTAACtionServices, IActionServices);
if IActionServices <> Nil then begin
IServices.QueryInterface(IOTAModuleServices, IModuleServices);
IModuleServices.CloseAll;
if IActionServices.OpenFile(EditorFileName) then begin
IModule := IModuleServices.Modules[0];
ISourceEditor := Nil;
for i := 0 to IModule.ModuleFileCount - 1 do begin
IEditor := IModule.ModuleFileEditors[i];
IEditor.QueryInterface(IOTAFormEditor, IFormEditor);
if IFormEditor <> Nil then begin
IComponent := IFormEditor.GetRootComponent;
IComponent.QueryInterface(INTAComponent, INTAComp);
AForm := TForm(INTAComp.GetComponent);
AForm.Close;
end;
end;
end;
end;
end;
它所需要的只是:
AForm := TForm(INTAComp.GetComponent);
SendMessage(AForm.Handle, WM_Close, 0, 0);
//AForm.Close;
但我仍然有兴趣知道是否有官方方法可以做到这一点,因为我的"解决方案"感觉就像是在围绕 OTA 和 NTA 服务进行最终运行。 Otoh,用户始终可以在屏幕上手动关闭表单,所以也许我什么都不担心