![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Окно StayOnTop [D5]
harisma © (2010-06-25 16:48:00)Есть многооконное хост-приложение, к которому подгружаются библиотеки в DLL. В каждой библиотеке есть отдельный поток (помимо всего остального) с формой, которая при выполнении потока отображается поверх всех модальных форм хост-приложения.
Когда выполнение потока в одной библиотеке заканчивается, соответственно форма разрушается и управление передается на следующую библиотеку, где запускается такой же поток с такой же формой, которая опять же отображается поверх всех модальных форм хост-приложения и т. д.
Данный процесс инициируется пользователем и жизненно необходим для работы всего приложения.
Так вот вопрос и собственно проблема: Как сделать так, чтобы эта форма, которая должна находиться поверх всех модальных окон моего приложения, тем самым перекрывая доступ пользователю к элементам управления приложения до завершения работы потока, влияла только на мое приложение, а не на все открытые окна в ОС? А то получается, что запустил процесс в своем приложении, перключился в другую программу и работаешь там себе, а в это время поток в одной библиотеке завершил работу, управление передалось в следующую библиотеку и вновь форма отображения процесса выполнения потока вылезла на передний план операционки, став главным активным окном. Мне же надо, чтобы эта форма не перехватывала управление на себя, а спокойно в фоновом режиме работало себе, не давая в то же самое время пользователю извне вмешаться в работу приложения.
Ну, что-то типа такого. Простите зе несколько невнятное описание, но думаю суть понятна.
harisma (2010-06-30 10:42:00) [1]
> Deltas © (29.06.10 19:16) [6]
Ваш ответ понятен. Спасибо. Будем думать, как это побороть :)
Deltas (2010-06-29 19:16:00) [2]Если Вы посмотрите исходный код
ShowModal(), то увидите, что эта функция уже используетDisableTaskWindows()иEnableTaskWindows(). Но, функцияDisableTaskWindows()вызываетEnumThreadWindows()для перечисления всех окон потока (!!!). Таким образом,DisableTaskWindows()может заблокировать только окна потока, из которого была вызвана. Поэтому
> Если я правильно понял, то перед вызовом метода этой формы
> ShowModal я должен сделать вызов DisableTaskWindows(0),
> а после ее закрытия (метод Free) вызвать EnableTaskWindows().
> И все?
не даст желаемого результата, потому что у Вас окна в DLL создаются в своих потоках, если я правильно понял. Вместо этого, как вариант, перед созданием окна "блокирующего другие окна приложения", можно отправить сообщение главному окну приложения, в обработчике которого вызватьDisableTaskWindows(). Тогда все окна главного потока будут заблокированы.
Но, в Вашей модели приложения, с моей точки зрения, изначально заложена мина. Дело в том, что компоненты VCL не потокобезопасны, другими словами, концепция Borland такова, что все окна и визуальные компоненты должны работать только в главном потоке. Кстати, это ограничение введено Borland, потому что на уровне Win API окна могут быть созданы различными потоками.
harisma (2010-06-29 18:36:00) [3]
> Расширенный стиль окна WS_EX_TOPMOST не блокирует другие
> окна приложения. Если есть исходный код библиотеки, то можно
> перед отображением окна вызвать функцию DisableTaskWindows()
> из Forms.pas:
> WindowList := DisableTaskWindows(0);
> В этом случае, при разрушении окна (WM_DESTROY) или закрытии
> окна (WM_CLOSE), нужно вызвать
> EnableTaskWindows(WindowList);
А можно вот это поподробнее?
Если я правильно понял, то перед вызовом метода этой формы ShowModal я должен сделать вызов DisableTaskWindows(0), а после ее закрытия (метод Free) вызвать EnableTaskWindows(). И все? Больше ничего делать не надо?
Deltas (2010-06-26 20:19:00) [4]
> Как сделать так, чтобы эта форма, которая должна находиться
> поверх всех модальных окон моего приложения, тем самым перекрывая
> доступ пользователю к элементам управления приложения
Расширенный стиль окна WS_EX_TOPMOST не блокирует другие окна приложения. Если есть исходный код библиотеки, то можно перед отображением окна вызвать функцию DisableTaskWindows() из Forms.pas:
WindowList := DisableTaskWindows(0);
В этом случае, при разрушении окна (WM_DESTROY) или закрытии окна (WM_CLOSE), нужно вызвать
EnableTaskWindows(WindowList);
_Юрий (2010-06-26 15:04:00) [5]видимо, просто не нужно эту форму делать активной при показе
~AQUARIUS~ (2010-06-26 00:06:00) [6]http://www.transl-gunsmoker.ru/2010/06/blog-post_11.html
Игорь Шевченко (2010-06-25 19:40:00) [7]
> Как сделать так, чтобы эта форма, которая должна находиться
> поверх всех модальных окон моего приложения, тем самым перекрывая
> доступ пользователю к элементам управления приложения до
> завершения работы потока, влияла только на мое приложение,
> а не на все открытые окна в ОС?
SetWindowPos (Handle, HWND_TOP, ...