2014-12-09 1 views
2

Код ниже упрощен от того, что я делаю во время разработки .BPL для D7.Как закрыть (в коде) форму, открытую IDE, без закрытия связанного файла .Pas

Обновление: После публикации этого вопроса я нашел один способ сделать то, что мне нужно, а именно просто отправить форму сообщения WM_Close, но мне все равно было бы интересно узнать, есть ли более «официальная «способ сделать это, потому что использование WM_Close похоже на то, что у него есть потенциал для неправильной установки среды IDE.

Все, что я пытаюсь сделать в этом коде, что вызывает у меня проблему, заключается в том, чтобы закрыть все файлы, открытые в IDE, , а затем открыть определенный .Pas-файл, который имеет связанный с ним файл .Dfm. Я не хочу, чтобы форма, определенная в .Dfm, открывалась на экране, поэтому я пытаюсь ее закрыть, без, закрывая файл .Pas. Я просто хочу, чтобы конструктор формы IDE и эта форма из путь.

В конце концов, я узнал, как получить форму через службы OTA + NTA в моем коде .BPL и, наивно, но не желая каких-либо других очевидных способов сделать это, я попытался позвонить. Закройте его, по этому фрагменту.

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

Однако форма делает не близко. Я проследил в TCustomForm.Close из окна CPU и, очевидно, причина, по которой он не закрывается, заключается в том, что его свойство Visible уже является False. Это то, что оценивает Visible до возвращения AForm.Close.

Оценка различных других свойств до AForm.Close сообщает мне, что - ее владелец Nil BUT - у него есть, по-видимому, действительная ручка окна // Arrghh! [звук падения пенни ... см. обновление выше]

Я смею сказать, что это связано с тем, как работает дизайнер форм IDE.

Мой вопрос просто: Что мне нужно сделать в моем коде, чтобы закрыть форму, , как это происходит, когда я просто нажимаю на кнопку [x] на своем фрейме?

Btw, я подтвердил, что экземпляр формы, которую я получаю через 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; 

ответ

2

Все это нужно было:

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

Но я бы до сих пор интересно узнать, есть ли официальный способ сделать это, потому что мое «решение» чувствует, как она делает конец - обойти службы OTA и NTA. Otoh, пользователь всегда может закрыть форму вручную, на экране, так что, может быть, я ничего не беспокоюсь

+0

Я думаю, что проверенный листинг будет лучше там. Если у вас есть 'TForm', вы бы просто не сделали« Form.Close »? –

+0

@DavidHeffernan: Да, это то, что я пробовал в первую очередь, но, как я объяснил (погребенный в теле q), это просто не сработало, причина, по-видимому, в том, что свойство Visible формы было ложным, несмотря на то, что форма на экране отображается на экране. Насколько я могу судить, пытаясь проследить объектный код TForm.Close в окне CPU, спустя некоторое время после CloseQuery, код замечает это и отказывается от своей попытки. – MartynA