Версия для печати
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=1408Дмитрий Ларионов
дата публикации 16-08-2009 01:56
Превращаем главное скрытое окно программы в действительно главное окно программы
Ни для кого думаю не секрет, что главным окном приложения, при подключении модуля Forms, является не ваша главная форма проекта, а невидимое окно создаваемое в TApplication (далее AppОкно). Если в ранних версиях Windows его почти не заметно, то в Windows Vista проявляется "левость" этого окна: когда вы сворачиваете программу, то в TaskBar'е, во всплывающем Preview, рисуется белое пятно с иконкой вашей программы, а не уменьшенная копия главного окна. Можно было бы сказать "спасибо, что не всегда" (а, кстати говоря, могло бы и всегда рисоваться белое пятно, и только благодаря Windows этого не происходит. Windows видит, что главное окно нулевых размеров и для Preview берёт следующее видимое окно.), но мне это постоянно не давало покоя. Оно и раньше мне не нравилось (я почти, процентов на 95, уверен, что при желании можно было бы обойтись без него), но все попытки избавиться или как-то обойти его терпели неудачу, а раз окно есть и оно, ни много ни мало, главное, windows справедливо рисует пустоту...
Я не знаю исправлено ли это в новых версиях Delphi, а для Delphi <= 2006 главным и, кажется, единственным известным способом избавления от этого "позорного пятна" является сокрытие главного окна проекта, и перенос всего функционала на другую форму и присваивание этой форме стиля WS_EX_APPWINDOW.
begin
Application.Initialize;
Windows.SetWindowLong(Application.Handle, GWL_EXSTYLE,
Windows.GetWindowLong(Application.Handle, GWL_EXSTYLE) or
WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.ShowMainForm := False;
Application.Run;
end.
|
|
type
TForm2 = class(TForm)
private
protected
procedure CreateParams(var Params: TCreateParams); override;
public
end;
var
Form2: TForm2;
implementation
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW and not WS_EX_TOOLWINDOW;
end;
|
|
К сожалению это не решение проблемы, а лишь заплатка. Так, например, в программе, где не модальных форм больше чем одна, при переключении на другое окно, окно-заместитель-главного становится не активным, а вместе с ним и кнопка в TaskBare'е теряет "фокус". Назначать всем окнам программы стиль WS_EX_APPWINDOW тоже не выход.
Попытки манипулирования AppОкном всё же привели к несколько неожиданному, но желаемому результату. Я нашёл как справиться с этой занозой и при этом не придется ничего менять в программе (ну почти ничего).
Я сделал AppОкно ...барабанная дробь... "главным окном программы". Т.е. буквально. AppОкно теперь не нулевых размеров, а видно на экране и оно не пустое, а с функционалом главной формы проекта (точнее, с внедрённой в неё главной формы проекта). Для этого требуется совершить несколько простых действий.
- Подключить модуль AppEx.pas к проекту.
- В TForm1 (будем считать её гравной формой проекта) добавьте
type
TForm1 = class(TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
implementation
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style := WS_CHILD or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_VISIBLE or WS_TABSTOP;
Params.WndParent := Application.Handle;
end;
|
|
- Переключитесь в DPR и добавьте код:
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
ApplicationInitialize;
Application.Run;
ApplicationFinalize;
end.
|
|
- Во всех остальных не модальных формах проекта, если таковые имеются, надо добавить:
type
TForm2 = class(TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
end;
implementation
uses AppEx;
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := AppWnd;
end;
|
|
А лучше всего унаследовать все не модальные окна от базовой, а уже в базовой поправить CreateParams как в пункте 4.
К статье прилагаются примеры