отображение модальных диалоговых форм
Есть приложение БД, выполняющее много довольно продолжительных SQL запросов (по 30-40 сек), после чего выводит результат на экран – либо в основной форме, либо в диалоговом окне (модальном)
Пример: после добавления к проекту шаблона диалогового окна New-->Standard Dialog, и убирания его из списка автоматически создаваемых форм имеем в проекте примерно следующее:
[...выполнение SQL транзакции ...]
try
{
Dlg = new TDlg(this);
Dlg->ShowModal();
}
__finally
{
delete Dlg;
}
Проблема: на период выполнения транзакции приложение «подвисает» переставая перерисовывать экран, если в это время переключится на другую задачу, а затем снова на данное приложение, то очень часто возникает ситуация при котором диалоговое окно отображается позади основной формы :), при этом главная ведет себя так, как если бы отображала модальное окно, т.е. не реагирует на нажатия кнопок и т.д...получить же модальную форму на передний план после этого можно лишь переключившись на задачу по Alt-Tab.
Подскажите как побороть, кто знает.
Спасибо.
очень часто возникает ситуация при котором диалоговое окно отображается позади основной формы :)
Это известный глюк VCL. Происходит он от того, что настоящее окно главное приложения TApplication::Handle фактически скрыто от системы и пользователя. Еще в VCL по каким-то причинам используется не полноценная модальность, а ее эмуляция.
Вторая причина связана с тем, что в Windows 2000 и старше при отсутствии ответа от приложения в течение некоторого времени (задается в реестре), оболочка подменяет оконную процедуру окна, с тем, чтобы его можно было двигать или закрыть. Майкрософт исходит из того, что все окна являются полноценными, когда на самом деле это не так. В данном случае подмена оконной процедуры является саботажем против работы VCL. Подобные глюки проявляются в работе любой VCL-программы, например, Бата или TOAD.
Для решения проблемы, конечно, можно попробовать порыться в исходниках VCL, но с другой стороны, может, будет разумным разрешить причину подвисания приложения, а не бороться со следствиями. Для начала попробовать вызывать Application -> ProcessMessages после каждого длительного запроса (если их несколько). Если не поможет - придется выносить выполнение запросов в отдельный поток.