Форум программистов CodeGuru
25 Июнь 2018, 19:34:14 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как запретить активацию окна  (Прочитано 22326 раз)
0 Пользователей и 1 Гость смотрят эту тему.
coolbuck
Новичок
*
Офлайн Офлайн

Сообщений: 4


Просмотр профиля
« : 03 Август 2010, 14:55:34 »

Добрый день! Подскажите, кто знает и может Улыбка
Нужно запретить активацию окна моего приложения. Приложение висит в трее и ходит по некоторым страницам в инете через контрол на основе IWebBrowser2. Проблема в том, что на некоторых страницах код javascript выводит окно приложения на передний план и оно совсем не дает работать. Пытался перехватывать WM_SIZE и опять скрывать окно приложения, но при этом окно, в котором была работа, теряет фокус. Как с этим бороться?
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #1 : 03 Август 2010, 19:41:29 »

Посмотрите в сторону WM_WINDOWPOSCHANGING, WM_ACTIVATE и WM_ACTIVATEAPP.

При помощи WM_WINDOWPOSCHANGING можно предотвратить развертывание окна, и.т.д. Это как минимум.
Надо его обрабатывать, менять то, что надо в структуре WINDOWPOS, переданной через lParam и не вызывать DefWindowProc.
Еще в WINDOWPOS в поле flags надо проставить флаг SWP_NOACTIVATE - тогда окно не будет активироваться.

Насчет WM_ACTIVATE и WM_ACTIVATEAPP в msdn написано:
Цитировать
If an application processes this message, it should return zero.
Попробуйте не вызывать DefWindowProc при обработке этих сообщений и возвращать из них 1.
Но это если с WM_WINDOWPOSCHANGING не прокатит (хотя должно прокатить).
Записан

coolbuck
Новичок
*
Офлайн Офлайн

Сообщений: 4


Просмотр профиля
« Ответ #2 : 04 Август 2010, 07:19:26 »

Перехват WM_WINDOWPOSCHANGING и установка флага SWP_NOACTIVATE действительно приводит к тому, что окно программы не выводится, но при этом предыдущее окно всё равно теряет фокус Грустный

Возврат 1 на события WM_ACTIVATE и WM_ACTIVATEAPP не дает вообще никакого видимого результата.
Насколько я знаю, оба эти события вызываются уже после того, как операционная система делает активным окно приложения.
Записан
Valery
Пользователь
***
Офлайн Офлайн

Сообщений: 83


Просмотр профиля
« Ответ #3 : 07 Август 2010, 15:35:35 »

если тебе не нужно окно может тогда попробовать консоль?
или попробуй хуки
С уважением Валерий
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #4 : 19 Август 2010, 23:51:58 »

если тебе не нужно окно может тогда попробовать консоль?

+1 или написать сервис.

или попробуй хуки

Точно, можно попробовать отслеживать последнее активное окно и возвращать ему фокус после попытки активизации своего окна.
Записан

coolbuck
Новичок
*
Офлайн Офлайн

Сообщений: 4


Просмотр профиля
« Ответ #5 : 20 Август 2010, 06:53:42 »

если тебе не нужно окно может тогда попробовать консоль?

IWebBrowser2 без окна не работает, насколько я знаю...

+1 или написать сервис.

Пожалуй, сервис я не осилю...

Точно, можно попробовать отслеживать последнее активное окно и возвращать ему фокус после попытки активизации своего окна.

Эту проблему я уже решил и без хуков. В обработчик WM_SIZE при попытке восстановления окна добавил
ShowWindow(SW_SHOWMINNOACTIVE); ShowWindow(SW_HIDE);

Теперь окно фокус не хватает, но есть ещё одна неприятная вешь - мигание: окно появляется на экране и тут же исчезает, все это ещё усугубляет эффект анимации при сворачивании окна.
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #6 : 21 Август 2010, 14:36:32 »

IWebBrowser2 без окна не работает, насколько я знаю...

Кстати да, возможно. Но можно попробовать не ActiveX control использовать, а создавать по UUID com-объект explorer-а, и как-то его юзать (надо разбираться тут).

+1 или написать сервис.

Пожалуй, сервис я не осилю...

Сервис просто написать - там пара функций всего, страничка кода, в msdn примеры сорцев есть.
Но я ступил что-то. Ведь окно приложения, наверно, еще для чего-то нужно ?


В общем, я немного поэкспериментировал.
Сделал mfc-приложение, document-view архитектура, single document, в качестве view - CHtmlView (обертка, работающая через тот же IWebBrowser2 и интерфейс, полученный через IWebBrowser2::get_Application).
Сделал кнопку в тулбаре. По ней пускал таймер на несколько секунд, в его обработчике делал Navigate2 на html-файлик на винте. В нем было что-то типа:

Код:
<html>
<body>
<script type="text/javascript">
window.focus();
</script>
</body>
</html>

Жал на кнопку, сворачивал окно. После загрузки страницы, оно разворачивалось.
Вроде заработало после того, как в главном окне приложения добавил обработчики WM_ACTIVATE и WM_NCACTIVATE:

Код:
void CMainFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
    CFrameWnd::OnActivate((nState == WA_ACTIVE) ? WA_INACTIVE : nState, pWndOther, bMinimized);
}

BOOL CMainFrame::OnNcActivate(BOOL bActive)
{
    return (BOOL)DefWindowProc(WM_NCACTIVATE, FALSE, 0L);
    // return CFrameWnd::OnNcActivate(bActive);
}

Фокус с предыдущего окна, не убирается. Но кнопка приложения на панели задач начинает мигать. Если окно будет скрыто, может все будет OK ?
Это все под XP тестил.
Записан

coolbuck
Новичок
*
Офлайн Офлайн

Сообщений: 4


Просмотр профиля
« Ответ #7 : 23 Август 2010, 07:29:47 »

У меня приложение тоже mfc, только multiple document, тоже работает с CHtmlView.
Скрипт тоже выполняет window.focus();

Метод не помог... Приложение выходит на передний план Грустный
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #8 : 24 Август 2010, 19:39:09 »

Ясно. Еще покопался в msdn.
Думается теперь, что надо реализовать свой интерфейс IDocHostUIHandler (его MSHTML запрашивает при инициализации или, как я понимаю, его еще можно установить через ICustomDoc::SetUIHandler). У него есть методы OnDocWindowActivate и OnFrameWindowActivate. Вот в них уже и рулить по ситуации.

Кстати, а студия какая используется ? Подозреваю, что 6-я ?
Т.к. в более поздних MFC у CHtmlView есть виртуальный метод OnDocWindowActivate - вызывается из IDocHostUIHandler::OnDocWindowActivate, т.е. там есть реализованный интерфейс IDocHostUIHandler.
Кстати, там же есть класс CDHtmlDialog, также использующий Web Browser Control (наверно, или хостящий MSHTML) и под него также есть реализация IDocHostUIHandler.

Это я к тому, что:
 - если используется достаточно новая MFC, то надо попробовать посмотреть в сторону OnDocWindowActivate/OnFrameWindowActivate.
 - если это  MFC 4.2 (не знаю, в MFC 7 есть ли то, что требуется), то поставить сорцы MFC поновее и посмотреть, как сделано там.

Записан

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!