下面的代码简化了我在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;
答案 0 :(得分:2)
所需要的只是:
AForm := TForm(INTAComp.GetComponent);
SendMessage(AForm.Handle, WM_Close, 0, 0);
//AForm.Close;
但我仍然有兴趣知道是否有正式的方法来做到这一点,因为 我的解决方案&#34;感觉它正在围绕OTA和NTA服务进行最终运行。 Otoh,用户可以随时在屏幕上手动关闭表单,所以也许我一点也不担心