-
Делает все остальные кона приложения Disabled, в том числе и главное невидимое окно объекта Application. Каковы могут быть нежелательные последствия, если после вызова модальной формы я буду делать главное окно Enabled? Пока, кроме некорректного поведения при минимизации модальной формы, других глюков не нашел (а этот мне как раз на руку). Подскажите, кто в курсе, какие еще могут быть подводные камни.
-
Тоже имел проблемы с минимизацией (если я правильно помню, наличие/отсутствие проблем зависит от MainFormOn ToolBar), других не заметил.
-
Изучай
procedure TApplication.WndProc(var Message: TMessage);
по-моему граблей там будет достаточно
-
>>Игорь Шевченко © (29.12.12 23:55) [2] Я только этим и занимаюсь последнюю неделю. Пока граблей не нашел, все работает. Если интересно решение напишу позже
-
ShowModal должен быть открыт/показ до конца, иначе возможны проблемы, поэтому нужды в управление главной формой нет.
-
> Anatoly Podgoretsky © (30.12.12 15:24) [4] > > ShowModal должен быть открыт/показ до конца, иначе возможны > проблемы, поэтому нужды в управление главной формой нет. > >
Почему именно должен?
-
> Германн (31.12.2012 03:21:05) [5]
Потому что Modal, а не Show Это по определению Вот определение из дурипедии -------------------------------------------------------------------------------------------------------------- Также существует разновидность окон (называемых модальными), которые «монополизируют» фокус пользовательского внимания, и продолжить работу с программой можно лишь после закрытия (выполнения запроса) такого «модального» окна. --------------------------------------------------------------------------------------------------------------
-
> Anatoly Podgoretsky © (01.01.13 01:08) [6] > > > Германн (31.12.2012 03:21:05) [5] > > Потому что Modal, а не Show > Это по определению > > Вот определение из дурипедии > -------------------------------------------------------- > ------------------------------------------------------ > Также существует разновидность окон (называемых модальными), > которые > «монополизируют» фокус пользовательского внимания, и продолжить > работу с > программой можно лишь после закрытия (выполнения запроса) > такого > «модального» окна. > -------------------------------------------------------- > ------------------------------------------------------
Но всё вышесказанное относится только к пользователю, а не к программисту - автору программы. А сабж как раз о том что может сделать автор программы и на что он может нарваться.
-
Я, видимо, должен пояснить, особенно в свете [3], про решение, о котором речь. В силу разных причин сложилась ситуация, когда есть главная форма программы, а поверх нее открыта модальная форма. Требуется при минимизации модальной формы минимизировать приложение, причем не так, чтобы свернутые окна отображались внизу десктопа, а "по-настоящему", чтобы в наличии имелась только кнопка на панели задач. А при разворачивании чтобы все разворачивалось как надо. По-хорошему, надо менять интерфейс, но опять же по ряду причин это пока не вариант. Свернуть-то совсем не проблема, хотя есть нюансы в версиях Windows, более поздних, чем XP. А вот корректно развернуть совсем непросто. Как одно из решений - посылать WM_ENABLE окну объекта Application сразу после входа в локальную петлю обработки сообщений в ShowModal (скажем, в событии OnShow). Никаких удовлетворительных решений проблемы разворачивания в сети не нашел, даже намеков на решения.
-
> Внук © (01.01.13 03:14) [8] Посмотри в сторону Application.MainFormOnTaskBar. Там в одном случае окна показываются через SetWindowPos (и глючат как ты описал), а в противном — через ShowWindow (и разворачивание отрабатывает корректно). Могу после седьмого числа покопаться в истории, если до тех пор не найдёшь решения.
-
Внук © (01.01.13 03:14) [8]
> Никаких удовлетворительных решений проблемы разворачивания > в сети не нашел, даже намеков на решения.
Наверное потому, что гланды вырезают через предназначенное для этого отверстие.
С новым годом!
-
Ну вот теперь, после тестов на реальных рабочих местах, рассказываю результат и предысторию борьбы.
Пусть есть 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.
-
Выяснилось вот что. При сворачивании через щелчок по кнопке на панели задач система посылает WM_APPACTIVATE (в смысле deactivate) и потом WM_SYSCOMMAND в смысле минимизации, но! Последнее сообщение посылается только живым (Enabled) окнам верхнего уровня (не имеющим родителей). А с точки зрения Windows у Delphi-приложения таким окном (если не предпринимать специальных ухищрений), является только невидимое окно объекта Application, которое при ShowModal за каким-то хреном аффтары переводят в разряд дохлых (Disabled). То есть сворачивание через щелчок по таскбару при открытом модальном окне + сразу затем Win+D, и здравствуйте, глюки.
-
Не помогли поэтому и 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 года работал у всех до этих переделок. Грешу на то, что там используется удаленный рабочий стол, ну и хрен с ней. Поэтому просьба :) Кому не лень, попробовать повесить программу минимизацией при использовании данного решения, или найти иной глюк любым способом, потому что у меня фантазия кончилась. Хочется статистики.
-
Ну и эта... Вдруг еще кому пригодится.
-
>>брат Птибурдукова (01.01.13 12:18) [9] Кстати, спасибо за информацию... Но проект пишется на D2006, там MainFormOnTaskBar нету
-
> Но проект пишется на D2006, там MainFormOnTaskBar нету
Разве? В Д2007 есть, а это почти одна и та же версия.
-
Нашел глюк :)
Не передавайте в MessageBox в качестве параметра Handle disabled-окна (в данном случае я пытался передать Application.Handle). MessageBox позволяет щелкнуть на другую форму, а себя отправить на задний план. Понятно, что это легко исправить, но факт - глюк есть. Их не могло не быть :)
-
И, наверное, не всегда стоит вызывать Application.MessageBox ?
-
> Внук © (21.02.13 20:57) [17] Гансмокер об энтом писал
-
> Внук © (09.01.13 23:40) [15] > >>брат Птибурдукова (01.01.13 12:18) [9] > Кстати, спасибо за информацию... > Но проект пишется на D2006, там MainFormOnTaskBar нету
очень многое, в этом вопросе, зависит от версии Делфи, они за последние лет несколько раз переделывали механизм.
-
>Внук © (09.01.13 18:00) [13] > EnableWindow(Application.Handle, true); Вот спасибо, выручил. Такая же фигня в Delphi XE3 на Win 7, после Application.Minimize открывается главная форма, приходилось повторно кликать по кнопке приложения.
-
>>Игорь Шевченко © (21.02.13 21:12) [18] >>И, наверное, не всегда стоит вызывать Application.MessageBox ?
Самое удивительно, что нет. Все нормально работает, если написать Application.MessageBox, и начинает глючить, если MessageBox(Application.Handle, ...)
Кстати, само по себе это ценное знание, полученное из всех этих экспериментов: если в стандартном приложении вызвать модальную форму, а из нее MessageBox(Application.Handle, ...), то окно сообщения легким щелчком мыши можно отправить на задний план, за форму, и получить эффект подвисания. Не знал.
-
Саш, так це боян - так и модалочку можно спрятать и даже обычный диалог. Суть проста - Application.MessageBox дергает ЦВС, в котором (из-за ровно написанного VCL кода) твоя окошка падает за основное окно по Z (улыбаемся и машем, так сказать)
-
Ну вот, век живи... Уроды, чо.
-
Разговор на древнем языке энтов :))) Начало - 29.12.12, сейчас уже 22.03.15
|