Конференция "WinAPI" » ShowModal у TCustomForm
 
  • Внук © (29.12.12 21:46) [0]
    Делает все остальные кона приложения Disabled, в том числе и главное невидимое окно объекта Application.
     Каковы могут быть нежелательные последствия, если после вызова модальной формы я буду делать главное окно Enabled? Пока, кроме некорректного поведения при минимизации модальной формы, других глюков не нашел (а этот мне как раз на руку). Подскажите, кто в курсе, какие еще могут быть подводные камни.
  • брат Птибурдукова (29.12.12 22:50) [1]
    Тоже имел проблемы с минимизацией (если я правильно помню, наличие/отсутствие проблем зависит от MainFormOn ToolBar), других не заметил.
  • Игорь Шевченко © (29.12.12 23:55) [2]
    Изучай

    procedure TApplication.WndProc(var Message: TMessage);

    по-моему граблей там будет достаточно
  • Внук © (30.12.12 01:13) [3]
    >>Игорь Шевченко ©   (29.12.12 23:55) [2]
     Я только этим и занимаюсь последнюю неделю. Пока граблей не нашел, все работает. Если интересно решение напишу позже
  • Anatoly Podgoretsky © (30.12.12 15:24) [4]
    ShowModal должен быть открыт/показ до конца, иначе возможны проблемы, поэтому нужды в управление главной формой нет.
  • Германн © (31.12.12 03:21) [5]

    > Anatoly Podgoretsky ©   (30.12.12 15:24) [4]
    >
    > ShowModal должен быть открыт/показ до конца, иначе возможны
    > проблемы, поэтому нужды в управление главной формой нет.
    >
    >

    Почему именно должен?
  • Anatoly Podgoretsky © (01.01.13 01:08) [6]
    > Германн  (31.12.2012 03:21:05)  [5]

    Потому что Modal, а не Show
    Это по определению

    Вот определение из дурипедии
    --------------------------------------------------------------------------------------------------------------
    Также существует разновидность окон (называемых модальными), которые
    «монополизируют» фокус пользовательского внимания, и продолжить работу с
    программой можно лишь после закрытия (выполнения запроса) такого
    «модального» окна.
    --------------------------------------------------------------------------------------------------------------
  • Германн © (01.01.13 02:39) [7]

    > Anatoly Podgoretsky ©   (01.01.13 01:08) [6]
    >
    > > Германн  (31.12.2012 03:21:05)  [5]
    >
    > Потому что Modal, а не Show
    > Это по определению
    >
    > Вот определение из дурипедии
    > --------------------------------------------------------
    > ------------------------------------------------------
    > Также существует разновидность окон (называемых модальными),
    >  которые
    > «монополизируют» фокус пользовательского внимания, и продолжить
    > работу с
    > программой можно лишь после закрытия (выполнения запроса)
    > такого
    > «модального» окна.
    > --------------------------------------------------------
    > ------------------------------------------------------

    Но всё вышесказанное относится только к пользователю, а не к программисту - автору программы. А сабж как раз о том что может сделать автор программы и на что он может нарваться.
  • Внук © (01.01.13 03:14) [8]
    Я, видимо, должен пояснить, особенно в свете [3], про решение, о котором речь.
    В силу разных причин сложилась ситуация, когда есть главная форма программы, а поверх нее открыта модальная форма. Требуется при минимизации модальной формы минимизировать приложение, причем не так, чтобы свернутые окна отображались внизу десктопа, а "по-настоящему", чтобы в наличии имелась только кнопка на панели задач. А при разворачивании чтобы все разворачивалось как надо.
    По-хорошему, надо менять интерфейс, но опять же по ряду причин это пока не вариант.
    Свернуть-то совсем не проблема, хотя есть нюансы в версиях Windows, более поздних, чем XP. А вот корректно развернуть совсем непросто. Как одно из решений - посылать WM_ENABLE окну объекта Application сразу после входа в локальную петлю обработки сообщений в ShowModal (скажем,  в событии OnShow).
    Никаких удовлетворительных решений проблемы разворачивания в сети не нашел, даже намеков на решения.
  • брат Птибурдукова (01.01.13 12:18) [9]

    > Внук ©   (01.01.13 03:14) [8]
    Посмотри в сторону Application.MainFormOnTaskBar. Там в одном случае окна показываются через SetWindowPos (и глючат как ты описал), а в противном — через ShowWindow (и разворачивание отрабатывает корректно). Могу после седьмого числа покопаться в истории, если до тех пор не найдёшь решения.
  • Игорь Шевченко © (02.01.13 19:55) [10]
    Внук ©   (01.01.13 03:14) [8]


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


    Наверное потому, что гланды вырезают через предназначенное для этого отверстие.

    С новым годом!
  • Внук © (09.01.13 17:33) [11]
    Ну вот теперь, после тестов на реальных рабочих местах, рассказываю результат и предысторию борьбы.

    Пусть есть Form1 - главная форма приложения. И Form2 открывается модально поверх Form1. Надо, соответственно, минимизировать приложение при минимизации Form2 и корректно его потом разворачивать.

    На системах под управлением WinXP SP3 и более ранних достаточно было тупо сделать
    procedure TForm2.WMSysCommand(var Msg: TWMSysCommand);
    begin
       if Msg.CmdType and $FFF0 = SC_MINIMIZE then
         Application.Minimize
       else
         inherited;
    end;
    На Win7 и выше при разворачивании таким образом свернутого приложения форма Form2 уходила на задний план и приложение "повисало". BringToFront тут мало поможет, потому что теоретически поверх Form2 в момент минимизации может быть открыто еще n модальных форм или просто какой-нибудь MessageBox, а свернуть приложение можно через Win+D (свернуть все окна, показать десктор и т.д.). Причем на XP, где вроде бы все корректно работало, при Win+D тоже начинало глючить.
    Начал с изучения, в чем разница между сворачиванием обычным и через Win+D.
  • Внук © (09.01.13 17:52) [12]
    Выяснилось вот что. При сворачивании через щелчок по кнопке на панели задач система посылает WM_APPACTIVATE (в смысле deactivate) и потом WM_SYSCOMMAND в смысле минимизации, но! Последнее сообщение посылается только живым (Enabled) окнам верхнего уровня (не имеющим родителей). А с точки зрения Windows у Delphi-приложения таким окном (если не предпринимать специальных ухищрений), является только невидимое окно объекта Application, которое при ShowModal за каким-то хреном аффтары переводят в разряд дохлых (Disabled). То есть сворачивание через щелчок по таскбару при открытом модальном окне + сразу затем Win+D, и здравствуйте, глюки.
  • Внук © (09.01.13 18:00) [13]
    Не помогли поэтому и Application.OnModalBegin,  Application.ModalLevel, на которые рассчитывал.
    Думал, придется ShowModal переписывать. А получилось решить вот так.
    procedure TForm2.WMSysCommand(var Msg: TWMSysCommand);
    begin
       if Msg.CmdType and $FFF0 = SC_MINIMIZE then
       begin
         EnableWindow(Application.Handle, true);
         Application.Minimize
       end
       else
         inherited;
    end;

    Сам не нашел никаких отрицательных побочных эффектов, работает на всех версиях Windows, до которых удалось дотянуться. Есть одна машина под XP? на которой не работает, но там не работает никакой вариант, даже тот, который 3 года работал у всех до этих переделок. Грешу на то, что там используется удаленный рабочий стол, ну и хрен с ней.
    Поэтому просьба :) Кому не лень, попробовать повесить программу минимизацией при использовании данного решения, или найти иной глюк любым способом, потому что у меня фантазия кончилась. Хочется статистики.
  • Внук © (09.01.13 18:01) [14]
    Ну и эта... Вдруг еще кому пригодится.
  • Внук © (09.01.13 23:40) [15]
    >>брат Птибурдукова   (01.01.13 12:18) [9]
    Кстати, спасибо за информацию...
    Но проект пишется на D2006, там MainFormOnTaskBar нету
  • Германн © (10.01.13 00:41) [16]

    > Но проект пишется на D2006, там MainFormOnTaskBar нету

    Разве? В Д2007 есть, а это почти одна и та же версия.
  • Внук © (21.02.13 20:57) [17]
    Нашел глюк :)

    Не передавайте в MessageBox в качестве параметра Handle disabled-окна (в данном случае я пытался передать Application.Handle). MessageBox позволяет щелкнуть на другую форму, а себя отправить на задний план. Понятно, что это легко исправить, но факт - глюк есть. Их не могло не быть :)
  • Игорь Шевченко © (21.02.13 21:12) [18]
    И, наверное, не всегда стоит вызывать Application.MessageBox ?
  • брат Птибурдукова (21.02.13 21:44) [19]

    > Внук ©   (21.02.13 20:57) [17]
    Гансмокер об энтом писал
 
Конференция "WinAPI" » ShowModal у TCustomForm
Есть новые Нет новых   [134427   +34][b:0][p:0.001]