Hint от Toolbar выводит на передний план Form1

Shouldercannon

Well-Known Member
25.05.2010
128
0
#1
Открыл все три формы. На двух из них есть ToolBar с одной кнопкой имеющей Hint. При наведении курсора мыши на кнопку в Toolbar, после вывода Hint все остальные формы становятся позади основной (Form1) и причём вывести их можно на передний план только по клику на заголовоке, а не на теле формы. Даже если на Form2 навести курсор на кнопку ToolBar, то после вывода Hint снова на переднем плане Form1. Что за баг такой? И почему при двух открытых формах (Form1, Form2) при нажатии на кнопку в Form2 при показе Form3, Form2 уходит на задний план за Form1 и Form3, Должно же быть так: поверх Form1 Form2, а поверх Form2 Form3?
 

Вложения

VahaC

Well-Known Member
10.01.2007
116
0
#2
Это не баг, а происходит следующее из-за вот этого

Код:
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
Params.WndParent := GetDesktopWindow;
end;
так как видимо после выполнения этого кода, каждое окна трактируется как "независимое приложение"

можете сами убедится в етом исправив выше приведённый код на следующий

Код:
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited;
end;
 

Shouldercannon

Well-Known Member
25.05.2010
128
0
#3
Проблема заключалась в Params.WndParent := GetDesktopWindow;.
Убрав Params.WndParent := GetDesktopWindow; появилась новая проблема. Открыты две формы, каждая из них имеет кнопку на панели задач. Если свернуть вторую форму, то всё нормально как были две кнопки на панели задач так и остались, но если свернуть первую (основную), то на панели задач остаётся кнопка только главной формы, а второй нет. Может есть альтернатива Params.WndParent := GetDesktopWindow;, менее проблематичная?

Пересмотрим систему. Убираем procedure CreateParams(var Params: TCreateParams); override; и переходим на
Код:

Код:
procedure TForm2.FormCreate(Sender: TObject);
begin
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
end;
Теперь осталось решить проблему сворачиваниях всех открытых форм при сворачивании Form1 (Главной формы).

P.S. А если использовать мультипоточность?
 

sinkopa

Well-Known Member
17.06.2009
344
9
#4
Пересмотрим систему. Убираем procedure CreateParams(var Params: TCreateParams); override; и переходим на
Код:
Код:
procedure TForm2.FormCreate(Sender: TObject);
begin
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
end;
Теперь осталось решить проблему сворачиваниях всех открытых форм при сворачивании Form1 (Главной формы).
По любому в оконнном Delphi приложении Одна форма (рожденная первой) становится Главным Окном Приложения... т.е. Главное окно "свернули" - значит хотели "свернуть" весь аппликэйшн... логика так сказать "дружелюбного интерфейса приложения"... :)
Возможно Вашу проблему решит следующий подход:
1. Создаем еще один юнит с формой, которая станет главным окном приложения но... показываться пользователю не будет... :)
Код:
unit uMainForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AppEvnts;

type
TMainAppForm = class(TForm)
ApplicationEvents1: TApplicationEvents; // Кидаем на форму ApplicationEvents
procedure FormCreate(Sender: TObject);
procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
private
{ Private declarations }
procedure AppMinimize(Sender: TObject);
public
{ Public declarations }
end;

var
MainAppForm: TMainAppForm;
AppStarted: Boolean = False; // Флаг. Нужен чтобы определить момент когда стартовать Form1 вместо главной (невидимой) формы
implementation

uses Unit1, Unit2, Unit3;

{$R *.dfm}

{ TMainAppForm }

procedure TMainAppForm.AppMinimize(Sender: TObject); 
begin
ShowWindow(Self.Handle, SW_HIDE);
end;

procedure TMainAppForm.FormCreate(Sender: TObject);
begin
// Заставляет Главную (невидимую) форму 
// всегда оставаться всего лишь значком приложения в панели задач...
// типа как MSWord, Excel и др. серверные приложения...
Application.OnMinimize := AppMinimize;
Application.OnRestore := AppMinimize;
Application.Minimize;
AppMinimize(Self);
end;

procedure TMainAppForm.ApplicationEvents1Idle(Sender: TObject;
var Done: Boolean);
begin
// Стартуем Form1 в качестве "псевдоглавной" формы.
if not AppStarted then
begin
AppStarted := True;
Form1.Show;
end;
end;

end.
2. Чтобы она стала главной - "рождаем" ее первой
Код:
program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3},
uMainForm in 'uMainForm.pas' {MainAppForm};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TMainAppForm, MainAppForm); // Главное окно приложения
Application.ShowMainForm := False; // разрешаем быть невидимой
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TForm3, Form3);
Application.Run;
end.
3. Остальные формы в соответствии с Вашим же предложением:
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
SetWindowLong(Handle, GWL_EXSTYLE,
GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
end;
ну и далее... в общем мысль ясна я думаю? ;)
PS. Если вам не нравится лишняя кнопка на панели задач... можно поместить ее в виде значка в трэй...