2016-06-17 5 views
1

Я создал приложение SDI, используя шаблон Delphi Berlin VCL. Я могу создать дополнительные экземпляры, запрограммировав File | New следующим образом:SDI-приложение с несколькими экземплярами, отображаемыми на панели задач

procedure TSDIAppForm.FileNew1Execute(Sender: TObject); 
var 
    LNewDoc: TSDIAppForm; 
begin 
    LNewDoc := TSDIAppForm.Create(Application); 
    LNewDoc.Show; 
end; 

Только форма владельца отображается на панели задач. Кроме того, закрытие формы владельца закрывает все экземпляры. Как отключить дополнительные экземпляры, чтобы они работали независимо и отображались индивидуально на панели задач?

+0

Возможный дубликат [Как я могу получить кнопки панели задач для форм th не являются основной формой?] (http://stackoverflow.com/questions/5493591/how-can-i-get-taskbar-buttons-for-forms-that-arent-the-main-form) –

+0

Не полностью дубликат, потому что я также спрашивал о том, как получить несколько SDIAppForms, которые работают независимо. – Duns

+0

Дубликат [Delphi, как сделать независимые окна] (https://stackoverflow.com/questions/2618372/delphi-how-to-make-independent-windows/2619792#2619792) –

ответ

2

Закрытие TForm, которое назначается как Application.MainForm, выходит из приложения, то есть по дизайну.

Если вы хотите MainForm действовать как любое другое окно SDI и закрываться независимо друг от друга, не выходя из приложения, если другие окна SDI все еще открыты, вам придется создать отдельный TForm действовать как настоящий MainForm, а затем скрыть от пользователя (установите Application.ShowMainForm на false при запуске до того, как вызывается Application.Run()), а затем вы можете создать объекты TSDIAppForm по мере необходимости. Когда последний объект TSDIAppForm будет закрыт, вы можете закрыть MainForm или позвонить по телефону Application.Terminate(), чтобы выйти из приложения.

Чтобы дать каждому TSDIAppForm свою собственную кнопку на панели задач, вы должны переопределить виртуальный CreateParams() метод:

How can I get taskbar buttons for forms that aren't the main form?

Попробуйте это:

begin 
    Application.Initialize; 
    Application.MainFormOnTaskbar := True; 
    Application.CreateForm(TMyRealMainForm, MyRealMainForm); 
    Application.CreateForm(TSDIAppForm, SDIAppForm); 
    SDIAppForm.Visible := True; 
    Application.ShowMainForm := False; 
    Application.Run; 
end. 

procedure TSDIAppForm.CreateParams(var Params: TCreateParams); 
begin 
    inherited; 
    Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; 
    Params.WndParent := 0; 
end; 

procedure TSDIAppForm.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
    Action := caFree; 
end; 

procedure TSDIAppForm.FormDestroy(Sender: TObject); 
begin 
    if Screen.FormCount = 2 then // only this Form and the MainForm 
    Application.Terminate; 
end; 

procedure TSDIAppForm.FileNew1Execute(Sender: TObject); 
var 
    LNewDoc: TSDIAppForm; 
begin 
    LNewDoc := TSDIAppForm.Create(Application); 
    LNewDoc.Show; 
end; 
+0

Разработка моей SDI-программы немного дальше, Я добавил TAdvStringGrid из TMS Software и увидел, что это привело к созданию двух дополнительных форм. Таким образом, прекращение приложения, когда Screen.FormCount сокращено до 2, больше не работает. Поэтому я модифицировал FormDestroy следующим образом: 'procedure TSDIAppForm.FormDestroy (Отправитель: TObject); var I: Целое; NumAppSDIForms: Integer; начало NumAppSDIForms: = 0; для I: = 0 до Screen.FormCount - 1 do if Screen.Forms [I] .UnitName = 'SDIMAIN', затем Inc (NumAppSDIForms); , если NumAppSDIForms = 1, затем Application.Terminate; конец; ' – Duns

+0

@ У вас есть правильный jist. Я бы использовал 'if Screen.Forms [i] TSDIAppForm then', хотя. –