Есть такая задача.
Работает программа. В фоновом режиме она проверяет наличие некоторых событий. Если событие есть, то показывается специальная форма-оповещение. Но форма эта должна отображаться в панели задач и не должна забирать на себя фокус. Кроме того:
— если форма на заднем фоне (на главным окном), то при наступлении события она должна показываться (не беря на себя фокус опять же)
— если форма оповещения свернута, то при наступлении события она должна показываться (не беря на себя фокус)
— если форма оповещения закрыта (но висит в памяти), то при наступлении события она должна показываться (не беря на себя фокус)
— если пользователь работает в другом приложении, то при наступлении события она должна показываться (не беря на себя фокус)
— форма не должна быть модальной или иметь признак "всегда сверху"
Что пока получилось:
— В панели задачи мы сидим.
— Первый показ окна оповещения срабатывает (после Create).
Не получилось:
— Второй и следующие показы не хотят показывать окно. Оно остается на заднем фоне.
Как в панель задач пихал окно писать не буду, оно вроде понятно.
Окно оповещения создается так:
Form.Create(nil);
Причем создается один раз и не уничтожается, пока не закроют программу. Так надо!
[Skip]
S>Показывается окно так: S> ShowWindow(Form.Handle, SW_SHOWNOACTIVATE); S> Form.Visible := True;
S>Первый показ происходит правильно, остальные — нет. Эксперименты с использование метода тыка не помогли.
Заменяем сие на это:
SetWindowPos (Form.Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
Form.Visible := True;
Re[2]: Всплавающее окно поверх всех программ без фокуса
Здравствуйте, Danchik, Вы писали:
D>Здравствуйте, shmelina, Вы писали:
D>[Skip]
S>>Показывается окно так: S>> ShowWindow(Form.Handle, SW_SHOWNOACTIVATE); S>> Form.Visible := True;
S>>Первый показ происходит правильно, остальные — нет. Эксперименты с использование метода тыка не помогли.
D>Заменяем сие на это: D>
D> SetWindowPos (Form.Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
D> Form.Visible := True;
D>
Если я работаю не своей программе, а в другой, то оповещение не появляется.
Re[3]: Всплавающее окно поверх всех программ без фокуса
Здравствуйте, Danchik, Вы писали:
D>Здравствуйте, shmelina, Вы писали:
D>[Skip]
S>>Если я работаю не своей программе, а в другой, то оповещение не появляется.
D>Попробуйте, забрать у окна овнера, может поможет: D>
Здравствуйте, Danchik, Вы писали:
D>Здравствуйте, shmelina, Вы писали:
D>[Skip]
D>Два варианта SetForegroundWindow или D>HWND_TOP заменить на HWND_TOPMOST
HWND_TOPMOST — не пойдет, т.к. если вдруг на модальном окне появится окно оповещения (закрывая модальное окно полностью), будет ощущение, что программа повисла, т.к. мышкой никуда не нажмешь.
SetForegroundWindow — берет на себя фокус.
Re: Всплавающее окно поверх всех программ без фокуса
Здравствуйте, shmelina, Вы писали:
S>Первый показ происходит правильно, остальные — нет. Эксперименты с использование метода тыка не помогли. S>Помогите пожалуйста.
Я в своем проекте делаю так:
PostMessage(Application->Handle, WM_SYSCOMMAND, SC_RESTORE, 1);
потом вот так:
Visible = true;
ShowWindow(Application->Handle, SW_HIDE);
Появляется окшко без фокуса и с в панели задач убирается кнопка.
наподобие OnScreenDisplay, если конечно не считать это "стрельбой из пушки по воробьям" ...
пример — окно статуса в Beeline GPRS Explorer, оно не реагирует на мышь (WS_EX_TOOLWINDOW), не уводит фокус с других окон и всегда поверх остальных (WS_EX_TOPMOST), полупрозрачное (если нужно).
есть код на C#, но функции из WinAPI, можно перевести при желании на bcb или найти готовое.
Re[2]: Всплавающее окно поверх всех программ без фокуса
наподобие OnScreenDisplay, если конечно не считать это "стрельбой из пушки по воробьям" ... R>пример — окно статуса в Beeline GPRS Explorer, оно не реагирует на мышь (WS_EX_TOOLWINDOW), не уводит фокус с других окон и всегда поверх остальных (WS_EX_TOPMOST), полупрозрачное (если нужно). R>есть код на C#, но функции из WinAPI, можно перевести при желании на bcb или найти готовое.
Боюсь такой вариант не пойдет. Окно не просто информационное, но и предназначено для работы. Там есть кнопки, таблица и т.п.
Re[7]: Всплавающее окно поверх всех программ без фокуса
Здравствуйте, shmelina, Вы писали:
S>Здравствуйте, Danchik, Вы писали:
D>>Здравствуйте, shmelina, Вы писали:
D>>[Skip]
D>>Два варианта SetForegroundWindow или D>>HWND_TOP заменить на HWND_TOPMOST
S>HWND_TOPMOST — не пойдет, т.к. если вдруг на модальном окне появится окно оповещения (закрывая модальное окно полностью), будет ощущение, что программа повисла, т.к. мышкой никуда не нажмешь.
Я в таких случаях ловил на таком окне WM_ENABLE и забирал TOPMOST
Re[8]: Всплавающее окно поверх всех программ без фокуса
D>>>Два варианта SetForegroundWindow или D>>>HWND_TOP заменить на HWND_TOPMOST
S>>HWND_TOPMOST — не пойдет, т.к. если вдруг на модальном окне появится окно оповещения (закрывая модальное окно полностью), будет ощущение, что программа повисла, т.к. мышкой никуда не нажмешь.
D>Я в таких случаях ловил на таком окне WM_ENABLE и забирал TOPMOST
Проблему вроде решил:
SetWindowPos(Form.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
SetWindowPos(Form.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW);
Form.Visible := True;
Но есть другая проблема.
Находясь в другом приложение появляется (без фокуса) форма оповещения. Но при закрытии ее крестиком всплывает приложение от оповещения.
Как быть?
Re[3]: Всплавающее окно поверх всех программ без фокуса
Здравствуйте, shmelina, Вы писали:
S>Окно не просто информационное, но и предназначено для работы. Там есть кнопки, таблица и т.п.
Это неправильно с точки зрения юзабилити. Нужно выводить информационное сообшение как baloon tooltip над значком в трее, а значок уже открывает "окно для работы". Примеры: подключение USB-устройства, подключение сетевого кабеля.
Re[4]: Всплавающее окно поверх всех программ без фокуса
Здравствуйте, wildwind, Вы писали:
W>Здравствуйте, shmelina, Вы писали:
S>>Окно не просто информационное, но и предназначено для работы. Там есть кнопки, таблица и т.п.
W>Это неправильно с точки зрения юзабилити. Нужно выводить информационное сообшение как baloon tooltip над значком в трее, а значок уже открывает "окно для работы". Примеры: подключение USB-устройства, подключение сетевого кабеля.
Делалось по аналогии с Outlook. Но вопрос не идеологии (на эту тему можно долго говорить), а в конкретной задаче.