Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Сокровищница
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  15:59[Войти] | [Зарегистрироваться]

Обсуждение материала
Превращаем главное скрытое окно программы в действительно главное окно программы
Полный текст материала


Другие публикации автора: Дмитрий Ларионов

Цитата или краткий комментарий:

«... Ни для кого думаю не секрет, что главным окном приложения, при подключении модуля Forms, является не ваша главная форма проекта, а невидимое окно создаваемое в TApplication. Если в ранних версиях Windows его почти не заметно, то в Windows Vista проявляется "левость" этого окна: когда вы сворачиваете программу, то в TaskBar'е, во всплывающем Preview, рисуется белое пятно с иконкой вашей программы, а не уменьшенная копия главного окна. Можно было бы сказать "спасибо, что не всегда", но мне это постоянно не давало покоя. Оно и раньше мне не нравилось, но все попытки избавиться или как-то обойти его терпели неудачу, а раз окно есть и оно, ни много ни мало, главное, windows справедливо рисует пустоту... Я не знаю исправлено ли это в новых версиях Delphi, а для Delphi <= 2006 главным и, кажется, единственным известным способом избавления от этого "позорного пятна" является сокрытие главного окна проекта, и перенос всего функционала на другую форму и присваивание этой форме стиля WS_EX_APPWINDOW. ...»


Важно:
  • Страница предназначена для обсуждения материала, его содержания, полезности, соответствия действительности и так далее. Смысл не в разборке, а в приближении к истине :о) и пользе для всех.
  • Любые другие сообщения или вопросы, а так же личные эмоции в адрес авторов и полемика, не относящаяся к теме обсуждаемого материала, будут удаляться без предупреждения авторов, дабы не мешать жителям нормально общаться.
  • При голосовании учитывайте уровень, на который расчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
  • Размер одного сообщений не должен превышать 5К. Если Вам нужно сказать больше, сделайте это за два раза. Или, что в данной ситуации правильнее, напишите свою статью.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила Королевства и уважайте друг друга.



Добавить свое мнение.

Результаты голосования
Оценка содержания

  Содержит полезные и(или) интересные сведения
[1]4100%
 
  Ничего особенно нового и интересного
[2]00%
 
  Написано неверно (обязательно укажите почему)
[3]00%
 
Всего проголосовали: 4

Оценка стиля изложения

  Все понятно, материал читается легко
[1]4100%
 
  Есть неясности в изложении
[2]00%
 
  Непонятно написано, трудно читается
[3]00%
 
Всего проголосовали: 4




Смотрите также материалы по темам:
[Окна, оконные сообщения] [Структура VCL-приложения]

Комментарии жителей
Отслеживать это обсуждение

Всего сообщений: 28

14-10-2010 10:00
сообщение от автора материала
Интересная статья и примеры. Но осталась масса не решенных проблем.
Извини, что сразу не ответил, но в упор не видел твоего сообщения, точнее не замечал на новостной, что появился новый комментарий.
Тема конечно интересная, но окончилась ничем. Ещё один комментарий был здесь: http://www.tdelphiblog.com/2010/01/2009.html (первый).
Например, главная форма  и одна модал.........
Даже смотреть не буду :) там полный тупик ни хуками ни хаками не решаемый. Так что даже не вздумай пользоваться...
 riff


28-09-2010 11:13
Интересная статья и примеры. Но осталась масса не решенных проблем.
Например, главная форма  и одна модальная. Потом "свернуть все окна" (кнопкой в панели задач), потом ещё раз нажать "свернуть все окна". Результат - главная форма не показывается при нажатии на кнопку приложения в панели задач. При множественных подобных манипуляциях, приложение вообще пропадает с панели задач.


16-11-2009 11:31
Если Вы дейсвительно имеетие жалание удалить статью, то всяко это не стоит обсуждать в обсуждении. Нужно просто связаться с Командой Королевства.

А вообще-то в удалении я смысла не вижу. Во-первых, даже устаревший материал представляет ценность. Во-вторых, "виндус 7" еще не стал общераспространенной ОС. И есть подозрение (или надежда ;-)), что станет не скоро.
 Geo


16-11-2009 05:03
сообщение от автора материала
Сказали, что статью скопировали на сайт http://www.interface.ru/home.asp?artId=21607 . В общем-то не жалко, но. Но уже давно хотел сказать, что может лучше вообще удалить эту статью от сюда? Так и не удалось справиться со всеми хоть и мелкими, но раздражающими глюками, глючками, и т.п... Я её доводил на работающем многооконном проекте, но либо кнопка в таскбаре не активизируется, либо главное окно по Z скачет, ... Вобщем выкинул.
А в виндус 7 главное окно стало и так нормально отображаться. Т.е. уже не актуально.
Давайте удалим её?
 riff


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
если нет желания ждать обновления, напишите в почту(адрес в модуле) и если гугл вас не выкенет в спам, то перешлю новую версию.
 riff


26-08-2009 06:14
сообщение от автора материала
Нашёл ещё один неприятный глюк:
*  Запустите мой демонстрационный проект.
*  Создайте несколько Form2
*  Щёлкните по Form1 чтобы она оказалась на верху.
*  Щёлкните по любой из созданных Form2
На верх(над Form1) вылезают ВСЕ Form2, а не только та по которой щёлкнули. Я вобщем нашёл способ как с этим справиться. Но чего-то мне не найти в модуле forms.pas от D2009 как с этим справились борландовцы. Вопрос к тем у кого D2007-2009 у вас формы подобным образом не перекрывают главную форму?
 riff


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

//------------- процедура WMActivateApp --------
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;

 riff


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 при сворачивании/разворачивании).

Спасибо всем участвовавшим в обсуждении, вы направили меня на путь истинный.
 riff


24-08-2009 11:39
Архив с примерами обновлён до версии 1.3


21-08-2009 09:30
riff
Вышли еще раз пожалуйста, я в первом сообщении название почтовика написал с ошибкой.


21-08-2009 01:57
сообщение от автора материала
>>>Незнаю как в висте
У меня виста, под неё и подгонял
>>>но в семерке работают отлично!
У тебя тоже наверно дельфи 2006 или turbo, в них компилировалось нормально, а вот у Pythona, например delphi 7, по его словам глючило.
Я ему переслал переделанный вариант, он сказал что стало нормально.
Сейчас тебе тоже послал обновление, проверь на своей виндоус7, если там всё нормально, то от первоначального варианта модулей окончательно откажусь.

>>>Во время закрытия формы её клиентская часть становится прозрачной и на мгновение немного увеличеной а-ля "экранная лупа".
Это не совсем баг был, просто form1 уничтожается до уничтожения Application.Handle, а Application.Handle не имеет background'а, можно было бы попробовать прорисовкой в wm_paint поправить.
 riff


20-08-2009 17:11
Автору Огромный респект за статью с примером! Незнаю как в висте но в семерке эффекты сворачивания/разворачивания и отображения маленьких окон в панели задач работают отлично!
Вот только при закрытии формы виден небольшой баг. Во время закрытия формы её клиентская часть становится прозрачной и на мгновение немного увеличеной а-ля "экранная лупа".


18-08-2009 06:20
сообщение от автора материала
>>>у меня Delphi 7.0
ай, не заметил.
 riff


18-08-2009 06:17
сообщение от автора материала
Python: Не указал версию дельфи и винды.
Впрочем это уже не важно, т.к. я всё переделал, больше не надо ни какие процедуры перекрывать.
Сейчас отправил в королевство версию 1.2. Когда обновят, её посмотри у себя пожалуйста.
 riff


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), написанное в статье и комментариях ранее стало почти не актуально. Сейчас проверю на глюки и чуть позже отправлю обновлённый архив.
 riff


17-08-2009 09:26
>>> В чём подвох?
Обратная совместимость.

>>> она просто делает тоже что и в начале статьи
Вместо Application используется MainForm. Там даже функция такая есть - ChangeAppWindow.


17-08-2009 07:38
сообщение от автора материала
>>>  Application.MainFormOnTaskbar := True;
А чем объясняется введение столь странной переменной? Ну т.е. понятно что она делает, но почему они просто не сделали это на постоянной основе? В чём подвох? Или она просто делает тоже что и в начале статьи, т.е. убирает стиль WS_EX_APPWINDOW у Application.Handle и назначает этот стиль главной форме проекта?
 riff


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))?
 riff


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 виноват.
  б. Борландовцы должны были оставить главную форму главной, но сделать невидимую форму-владельца для всех остальных окон(форм). Что я и реализовал.
  
Обновление модулей будет примерно в понедельник или во вторник (исправил ещё несколько недочётов).
 riff


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Какой месяц идет после марта?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.

Оценка содержания
 
Содержит полезные и(или) интересные сведения
 
Ничего особенно нового и интересного
 
Написано неверно (обязательно укажите почему)


Оценка стиля изложения
 
Все понятно, материал читается легко
 
Есть неясности в изложении
 
Непонятно написано, трудно читается

Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования