2

下面的代码是我在 D7 的设计时 .BPL 中所做的简化的。

更新:自从发布此消息以来,我找到了一种方法来做我所追求的,即只需向表单发送 WM_Close 消息,但我仍然有兴趣知道是否有更“官方”的方式来做到这一点,因为使用 WM_Close 似乎有可能使 IDE 出错。

我在这段代码中试图做的所有导致我出现问题的事情是关闭在 IDE 中打开的所有文件,然后打开一个特定的 .Pas 文件,该文件恰好有一个关联的 .Dfm 文件。我不希望 .Dfm 中定义的表单在屏幕上打开,所以我试图关闭它,而不关闭 .Pas 文件 - 我只想要 IDE 表单设计器和这个表单.

最终,我发现了如何在我的 .BPL 代码中通过 OTA + NTA 服务获取表单,并且天真地但因为想要任何其他明显的方式来做到这一点,我尝试通过这个片段调用 .Close 。

AForm := TForm(INTAComp.GetComponent);
AForm.Close;

但是,窗体不会关闭。我已经从 CPU 窗口追踪到 TCustomForm.Close,显然它没有关闭的原因是它的 Visible 属性已经是 False。这也是在 AForm.Close 返回之前评估 Visible 的内容。

在 AForm.Close 之前评估它的其他各种属性告诉我 - 它的所有者是 Nil 但是 - 它有一个明显有效的窗口句柄 // Arrghh![一分钱下降的声音......见上面的更新]

我敢说这与 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;
4

1 回答 1

2

它所需要的只是:

AForm := TForm(INTAComp.GetComponent);
SendMessage(AForm.Handle, WM_Close, 0, 0);
//AForm.Close;

但我仍然想知道是否有官方的方式来做到这一点,因为我的“解决方案”感觉就像是围绕 OTA 和 NTA 服务进行最终运行。Otoh,用户总是可以在屏幕上手动关闭表单,所以也许我什么都不担心

于 2014-12-09T18:43:17.717 回答