Изменение порядка окон в мультиформном приложении

У меня есть приложение с несколькими немодальными формами, каждая со своим значком. Мне нужны значки всех форм на панели задач, которые не исчезают при сворачивании / восстановлении, и после некоторого тестирования это мое решение.

Приложение

Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;

TForm1 - основная форма с одним TButton

procedure TForm1.btn1Click(Sender: TObject);
begin
  TForm2.Create(Application).Show;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetWindowLong(Handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
  Application.OnRestore := FormShow;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  ShowWindow(Application.Handle, SW_HIDE);
end;

TForm2

procedure TForm2.FormCreate(Sender: TObject);
begin
  SetWindowLong(Handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
end;

Это создаст 2 значка на панели задач и 2 окна в Alt + Tab, оба работают, как ожидалось, за исключением одного ... при переключении приложения все предыдущие окна приложений перемещаются перед текущим окно приложения, а не только одно окно.

Например, у моего приложения есть основная форма и другая немодальная форма. Если я в Google Chrome и нажимаю Alt + Tab, тогда это будет appper, и это нормально.

введите описание изображения здесь

Но это переместит все окна моих приложений до Google Chrome и на следующую Alt + Tab Я вижу это, поэтому мне нужно нажать Alt + 2x Tab, чтобы вернуться в Chrome.

введите описание изображения здесь

Я хотел бы добиться такого поведения, как если бы у меня было больше приложений, а не одно с несколькими окнами.

введите описание изображения здесь

Я не уверен, как именно это работает, но я предполагаю, что в фоновом режиме есть несколько списков, один для всех приложений и один для окон приложения, поэтому, когда я переключаю приложение, оно перемещается в списке перед предыдущим а значит и все его окна.

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


person Triber    schedule 13.12.2017    source источник
comment
Как вы создали эти окна? Вы указали владельца?   -  person whosrdaddy    schedule 13.12.2017
comment
TForm.Create(Application), но я не думаю, что этот владелец что-то изменит   -  person Triber    schedule 13.12.2017


Ответы (1)


Теперь, когда я лучше понимаю вашу проблему, проблема в том, что TApplication также имеет окно и играет роль в поведении, которое вы видите. Решение довольно простое: убедитесь, что ВСЕ окна верхнего уровня имеют WS_EX_APPWINDOW EXCEPT TApplication. Вторая проблема заключается в том, что TApplication является родителем этих окон, а не рабочим столом, поэтому вам нужно указать это.

Форма 1:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
  strict protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Unit2;

{ TForm1 }

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  // make desktop the owner, not the TApplication window
  Params.WndParent := GetDesktopWindow;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 SetWindowLong(Application.Handle, GWL_EXSTYLE,  GetWindowLong(Application.Handle,GWL_EXSTYLE) and not WS_EX_APPWINDOW or WS_EX_TOOLWINDOW);
 Form2 := TForm2.Create(Application);
 Form2.Show;
end;

end.

Форма 2:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm2 = class(TForm)
  strict protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

{ TForm2 }

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  // make desktop the owner, not the TApplication window
  Params.WndParent := GetDesktopWindow;
end;

end.
person whosrdaddy    schedule 14.12.2017