 |  | |  | |
Превращаем главное скрытое окно программы в действительно главное окно программы | Полный текст материала
Другие публикации автора: Дмитрий Ларионов
Цитата или краткий комментарий: «... Ни для кого думаю не секрет, что главным окном приложения, при подключении модуля Forms, является не ваша главная форма проекта, а невидимое окно создаваемое в TApplication. Если в ранних версиях Windows его почти не заметно, то в Windows Vista проявляется "левость" этого окна: когда вы сворачиваете программу, то в TaskBar'е, во всплывающем Preview, рисуется белое пятно с иконкой вашей программы, а не уменьшенная копия главного окна. Можно было бы сказать "спасибо, что не всегда", но мне это постоянно не давало покоя. Оно и раньше мне не нравилось, но все попытки избавиться или как-то обойти его терпели неудачу, а раз окно есть и оно, ни много ни мало, главное, windows справедливо рисует пустоту... Я не знаю исправлено ли это в новых версиях Delphi, а для Delphi <= 2006 главным и, кажется, единственным известным способом избавления от этого "позорного пятна" является сокрытие главного окна проекта, и перенос всего функционала на другую форму и присваивание этой форме стиля WS_EX_APPWINDOW. ...» |
Важно:- Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
- Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
- При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
- Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.
Добавить свое мнение.
| | Содержит полезные и(или) интересные сведения | [1] | 4 | 100% | | | | Ничего особенно нового и интересного | [2] | 0 | 0% | | | | Написано неверно (обязательно укажите почему) | [3] | 0 | 0% | | Всего проголосовали: 4 | | | Все понятно, материал читается легко | [1] | 4 | 100% | | | | Есть неясности в изложении | [2] | 0 | 0% | | | | Непонятно написано, трудно читается | [3] | 0 | 0% | | Всего проголосовали: 4 |
[Окна, оконные сообщения] [Структура VCL-приложения]
Отслеживать это обсуждение 
Всего сообщений: 2814-10-2010 10:00сообщение от автора материала Интересная статья и примеры. Но осталась масса не решенных проблем.
Извини, что сразу не ответил, но в упор не видел твоего сообщения, точнее не замечал на новостной, что появился новый комментарий.
Тема конечно интересная, но окончилась ничем. Ещё один комментарий был здесь: http://www.tdelphiblog.com/2010/01/2009.html (первый).
Например, главная форма и одна модал.........
Даже смотреть не буду :) там полный тупик ни хуками ни хаками не решаемый. Так что даже не вздумай пользоваться... |
|
28-09-2010 11:13 Интересная статья и примеры. Но осталась масса не решенных проблем.
Например, главная форма и одна модальная. Потом "свернуть все окна" (кнопкой в панели задач), потом ещё раз нажать "свернуть все окна". Результат - главная форма не показывается при нажатии на кнопку приложения в панели задач. При множественных подобных манипуляциях, приложение вообще пропадает с панели задач. |
|
16-11-2009 11:31Если Вы дейсвительно имеетие жалание удалить статью, то всяко это не стоит обсуждать в обсуждении. Нужно просто связаться с Командой Королевства.
А вообще-то в удалении я смысла не вижу. Во-первых, даже устаревший материал представляет ценность. Во-вторых, "виндус 7" еще не стал общераспространенной ОС. И есть подозрение (или надежда ;-)), что станет не скоро. |
|
16-11-2009 05:03сообщение от автора материала Сказали, что статью скопировали на сайт http://www.interface.ru/home.asp?artId=21607 . В общем-то не жалко, но. Но уже давно хотел сказать, что может лучше вообще удалить эту статью от сюда? Так и не удалось справиться со всеми хоть и мелкими, но раздражающими глюками, глючками, и т.п... Я её доводил на работающем многооконном проекте, но либо кнопка в таскбаре не активизируется, либо главное окно по Z скачет, ... Вобщем выкинул.
А в виндус 7 главное окно стало и так нормально отображаться. Т.е. уже не актуально.
Давайте удалим её? |
|
15-09-2009 13:26Примеры обновлены до версии 1.5. |
|
02-09-2009 10:17Попробовал применить к своему проекту в D7, сразу же обнаружился следующий глюк под ХР.
У меня сначала отображается главная форма, а на ее фоне модальная форма ввода логина и пароля. Так вот, при щелканье по кнопке моего приложения в таскбаре, главное окно так и остается висеть не сворачиваясь, а модальное окошко пропадает, видимо прячется за него. Затем при щелчке по главной форме, модальная выпрыгивает наверх.
Модуль проекта:
begin
Application.Initialize;
Application.CreateForm(TMain, Main);
App.Initialize;
Main.Logon;
Application.Run;
end.
Урезанный вариант процедуры Login:
procedure TMain.Logon;
Show;
Application.ProcessMessages;
Login := TLogin.Create(Self);
try
if Login.ShowModal <> mrOk then Application.Terminate;
finally
Login.Free;
end;
end;
Это пока что единственное, что сразу бросилось в глаза. |
|
27-08-2009 03:21сообщение от автора материала Справился с ранее перечисленными проблемами (надеюсь не наделал новых).
Выслал в королевство версию 1.4
если нет желания ждать обновления, напишите в почту(адрес в модуле) и если гугл вас не выкенет в спам, то перешлю новую версию. |
|
26-08-2009 06:14сообщение от автора материала Нашёл ещё один неприятный глюк:
* Запустите мой демонстрационный проект.
* Создайте несколько Form2
* Щёлкните по Form1 чтобы она оказалась на верху.
* Щёлкните по любой из созданных Form2
На верх(над Form1) вылезают ВСЕ Form2, а не только та по которой щёлкнули. Я вобщем нашёл способ как с этим справиться. Но чего-то мне не найти в модуле forms.pas от D2009 как с этим справились борландовцы. Вопрос к тем у кого D2007-2009 у вас формы подобным образом не перекрывают главную форму? |
|
25-08-2009 11:44сообщение от автора материала sergeymit: спасибо за баг.
Есть ещё одна похожая проблема:
* в моём примере, если у вас на экране две формы (Form1 и Form2)
* перекройте их окном другой программы
* затем щёлкните по одной из форм(не по кнопке в taskbar'e). Вторая не выйдет на передний план.
Чтобы это исправить их обе, надо:
1. ---------------------
procedure TAppEx.MainFormWndProc(var Message: TMessage);
begin
case Message.Msg of
WM_DESTROY:
begin
DefMainFormWndProc := nil;
end;
WM_ACTIVATE:
with TWMActivate(Message) do
begin
if (Active in [WA_ACTIVE, WA_CLICKACTIVE]) then
begin
if IsWindowEnabled(Application.MainForm.Handle) then
SetActiveWindow(Application.MainForm.Handle)
else
SetActiveWindow(Application.Handle);
end;
end;
WM_SYSCOMMAND:
2.--------------
TAppEx = class(TObject)
private
procedure WMActivateApp(var Message: TWMActivateApp); message WM_ACTIVATEAPP;
implementation
type
TMainHandles = array[0..1] of THandle;
function GetMainWindows(Handle: HWND; Info: Pointer): BOOL; stdcall;
begin
if (Handle = Application.Handle)
or ((Application.MainForm <> nil) and (Handle = Application.MainForm.Handle)) then
if TMainHandles(Info^)[0] = 0 then
TMainHandles(Info^)[0] := Handle
else
TMainHandles(Info^)[1] := Handle;
Result := True;
end;
procedure TAppEx.WMActivateApp(var Message: TWMActivateApp);
var
wnds: TMainHandles;
I: Integer;
LastHandle: THandle;
begin
inherited;
with Message do
begin
if Active then
begin
FillChar(wnds, sizeof(wnds), 0);
Windows.EnumWindows(@GetMainWindows, Longint(@wnds));
LastHandle := 0;
for I := 0 to high(wnds) do
begin
if wnds[I] <> 0 then
Windows.SetWindowPos(wnds[I], LastHandle, 0, 0, 0, 0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
LastHandle := wnds[i];
end;
end
end;
end; |
|
25-08-2009 08:53Рекомендую пробежаться по этому.
В частности.
Мне лениво смотреть, кто там виноват, но явно есть подводные камни. |
|
25-08-2009 08:10Обновлённый пример замечательно работает в Delphi 6, спасибо!
Единственное замечание: при работе с модальными формами пример ведёт себя малость странно:
1) открываем модальный диалог поверх главной формы;
2) переключаемся на другое приложение;
3) переключаемся обратно на нашу форму,
и видим, что активно якобы только главное окно, а модального вообще не видно. Это только видимость, если кликнуть на главном окне - модальное появится, но всё равно неприятно.
Тут: http://www.installationexcellence.com/articles/VistaWithDelphi/Index.html#Strange%20Activation описана эта ситуация и предложен вариант исправления ошибки.
В том коде, который выложен, требуется модифицировать MainFormWndProc, например так:
procedure TAppEx.MainFormWndProc(var Message: TMessage);
begin
case Message.Msg of
WM_DESTROY:
begin
DefMainFormWndProc := nil;
end;
WM_Activate:
with TWMActivate(Message) do
begin
if (Active = WA_ACTIVE) and not IsWindowEnabled(Application.MainForm.Handle) then
begin
SetActiveWindow(Application.Handle);
Message.Result := 0;
Exit;
end;
end;
WM_SYSCOMMAND:
begin
и дальше без изменений |
|
24-08-2009 15:02сообщение от автора материала >>>Архив с примерами обновлён до версии 1.3
Спасибо.
Для всех: повторю на всякий случай. Модули полностью переделаны. Описание в статье больше не актуально, как-нибудь позже перепишу её. Переделано по аналогии с D2009 (скрываем Application.Handle с TaskBar'a, выводим на её место главную форму проекта + немного изменяем поведение application.Handle при сворачивании/разворачивании).
Спасибо всем участвовавшим в обсуждении, вы направили меня на путь истинный. |
|
24-08-2009 11:39Архив с примерами обновлён до версии 1.3 |
|
21-08-2009 09:30riff
Вышли еще раз пожалуйста, я в первом сообщении название почтовика написал с ошибкой. |
|
21-08-2009 01:57сообщение от автора материала >>>Незнаю как в висте
У меня виста, под неё и подгонял
>>>но в семерке работают отлично!
У тебя тоже наверно дельфи 2006 или turbo, в них компилировалось нормально, а вот у Pythona, например delphi 7, по его словам глючило.
Я ему переслал переделанный вариант, он сказал что стало нормально.
Сейчас тебе тоже послал обновление, проверь на своей виндоус7, если там всё нормально, то от первоначального варианта модулей окончательно откажусь.
>>>Во время закрытия формы её клиентская часть становится прозрачной и на мгновение немного увеличеной а-ля "экранная лупа".
Это не совсем баг был, просто form1 уничтожается до уничтожения Application.Handle, а Application.Handle не имеет background'а, можно было бы попробовать прорисовкой в wm_paint поправить. |
|
20-08-2009 17:11Автору Огромный респект за статью с примером! Незнаю как в висте но в семерке эффекты сворачивания/разворачивания и отображения маленьких окон в панели задач работают отлично!
Вот только при закрытии формы виден небольшой баг. Во время закрытия формы её клиентская часть становится прозрачной и на мгновение немного увеличеной а-ля "экранная лупа". |
|
18-08-2009 06:20сообщение от автора материала >>>у меня Delphi 7.0
ай, не заметил. |
|
18-08-2009 06:17сообщение от автора материала Python: Не указал версию дельфи и винды.
Впрочем это уже не важно, т.к. я всё переделал, больше не надо ни какие процедуры перекрывать.
Сейчас отправил в королевство версию 1.2. Когда обновят, её посмотри у себя пожалуйста. |
|
18-08-2009 05:23Процедуру procedure GetBorderIconStyles(var Style, ExStyle: Cardinal); override; я бы окаймил директивами условной компиляции - чтобы не вылезала при компиляции под старыми версиями Delphi (у меня Delphi 7.0).
Какие-то менюшки болтаются на главном окне приложения. Стоило бы удалить.
Поведение окошек приложения по-прежнему весьма "странное". То есть при сворачивании окон приложения они сворачиваются над системным треем. По-прежнему существует "главная" форма приложения, при закрытии которой закрывается все приложение. Я решал все эти проблемы, правда, довольно непристойным способом. У меня при сворачивании любого окна приложения сворачивалось все приложение, а при закрытии любого окна приложение продолжало работать, закрываясь только после закрытия всех окон приложения.
Вроде бы, пока все. |
|
18-08-2009 03:22сообщение от автора материала Как знал, что не надо было статью ввиде статьи оформлять. У себя переделал модули (сделал по аналогии с forms.pas из Delphi 2009), написанное в статье и комментариях ранее стало почти не актуально. Сейчас проверю на глюки и чуть позже отправлю обновлённый архив. |
|
17-08-2009 09:26>>> В чём подвох?
Обратная совместимость.
>>> она просто делает тоже что и в начале статьи
Вместо Application используется MainForm. Там даже функция такая есть - ChangeAppWindow. |
|
17-08-2009 07:38сообщение от автора материала >>> Application.MainFormOnTaskbar := True;
А чем объясняется введение столь странной переменной? Ну т.е. понятно что она делает, но почему они просто не сделали это на постоянной основе? В чём подвох? Или она просто делает тоже что и в начале статьи, т.е. убирает стиль WS_EX_APPWINDOW у Application.Handle и назначает этот стиль главной форме проекта? |
|
17-08-2009 07:35Не знаю, может это и оффтопик, но вот тут разбираются этот и некоторые другие вопросы, касающиеся работы Delphi-приложений в Vista. |
|
17-08-2009 06:10 Application.MainFormOnTaskbar := True;
B Delphi 2007 и выше. |
|
17-08-2009 01:35сообщение от автора материала прочел програмку. идея захватывает. знаю что сейчас прыгнет. посмотрю - если не разобъется - буду рукоплескать наряду вместе с остальным залом.
В TurboDelphi и в Windows Vista всё выглядит прилично. Хотелось бы что бы отозвались пользователи ранних/новых дельфи и/или предыдущих Windows как у них работает.
А не следует ли внедрение немодальных форм в TAplication реализовать в модуле Forms? Один раз на все случаи жизни. Точнее, переписать метод TCustomForm.CreateParams(var Params: TCreateParams);
Ради одного CreateParams не следует (кстати, на всякий случай, в коде для главной формы две процедуры перекрываются).
А всё остальное, ...ну можно конечно Forms переделать, но 1.пока что поддаётся хуками справиться, 2.народ не одобрит влезание в forms (скажет вирус написал, как в новости на главной странице :)) 3.в forms придётся копаться/разбираться/править от ~семи дельфей.
Борландовцы здесь опять напортачили, не могли что-ли сделать Application доступным для правки (имею ввиду создание своего дочернего TMyApplication=class(TApplication))? |
|
16-08-2009 23:17А не следует ли внедрение немодальных форм в TAplication реализовать в модуле Forms? Один раз на все случаи жизни. Точнее, переписать метод TCustomForm.CreateParams(var Params: TCreateParams); |
|
16-08-2009 15:43как перед прыжком из под купола цирка.
прочел програмку. идея захватывает. знаю что сейчас прыгнет. посмотрю - если не разобъется - буду рукоплескать наряду вместе с остальным залом. |
|
16-08-2009 09:54сообщение от автора материала Вы знаете, я начал понимать зачем сделали это главное не видимое окно :) (это правда не значит, что я теперь их поддерживаю).
В windows, не побоюсь этого сказать, не до конца продумана работа с окнами:
* Можно создать окно(форму) не принадлежайшее ни кому. Но в этом случае
a. появляется кнопка в TaskBar'e
b. нельзя разом свернуть все окна программы
* Можно создать окно, принадлежайшее другому окну, в этом случае
a. окно исчезает с экрана, если владельза свернули (это плюс)
b. окно ПОСТОЯННО будет выше своего владельца (т.е. вы ни как не сможете вывести владельца на передний план) (это минус).
* Вот тут как раз не хватает промежуточного варианта, где бы и владелец был и окна(формы) могли свободно перемещаться по Z-order'у.
Борландовцы выкрутились тем, что создали невидимого владельца всех окон проекта, которые в свою очередь могут свободно перемещаться по Z-order'у, так как они являюся все как бы равноправными (но потом вляпались в Vist'у).
А чтобы главная форма проекта казалась главной формой запущенной программы они часть сообщений перехватывают, часть перенаправляют, и т.д.
Моё мнение что
а. Microsoft виноват.
б. Борландовцы должны были оставить главную форму главной, но сделать невидимую форму-владельца для всех остальных окон(форм). Что я и реализовал.
Обновление модулей будет примерно в понедельник или во вторник (исправил ещё несколько недочётов). |
|
|
|