如何关闭(在代码中)IDE已打开的表单,而不关闭其关联的.Pas文件

时间:2014-12-09 17:37:26

标签: forms delphi ide designer toolsapi

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

更新:自发布此消息后,我找到了一种方法来完成我之后的工作,即只是发送一个WM_Close消息,但我仍然有兴趣知道是否有更多"官方"这样做的方法,因为使用WM_Close似乎有可能错误地使用IDE。

我试图在此代码中尝试做的就是关闭所有在IDE中打开的文件, 然后打开一个特定的.Pas文件,恰好有一个关联的.Dfm文件。我不希望.Dfm中定义的表单在屏幕上打开,所以我试图关闭它,没有关闭.Pas文件 - 我只是想要IDE表单设计器和此表单。

最终,我发现如何通过我的.BPL代码中的OTA + NTA服务获取表单,并且天真但是由于缺少任何其他明显的方法,我尝试过调用。通过这个片段关闭它。

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

但是,表单关闭。我已经从CPU窗口跟踪了TCustomForm.Close 并且显然它没有关闭的原因是它的可见属性已经是假的。这是在AForm.Close返回之前评估Visible的原因。

在AForm之前评估其他各种属性。关闭告诉我 - 它的主人是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;

1 个答案:

答案 0 :(得分:2)

所需要的只是:

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

但我仍然有兴趣知道是否有正式的方法来做到这一点,因为 我的解决方案&#34;感觉它正在围绕OTA和NTA服务进行最终运行。 Otoh,用户可以随时在屏幕上手动关闭表单,所以也许我一点也不担心