Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 11.07.17 13:23
Оценка:
Есть программка-уведомление, которая создаёт значок в трее и при нажатии на оный показывает диалог. Требуется, чтобы при закрытии диалога он бы просто прятался, а при щелчке по значку в трее снова вылезал.

Добавил обработку WM_CLOSE и WM_SYSCOMMAND+SC_CLOSE, где прописал скрытие окна ShowWindow(SW_HIDE); на щелчок трей-значка прописал показ окна ShowWindow(SW_SHOW). Проблема: когда окно показывается после такого скрытия, оно выводится в каком-то неактивном виде: содержимое диалога не отрисовывается (пустое серое поле), окно не реагирует на большинство событий (например, движение курсора мыши поверх окна не приводит к приходу сообщений в оконную функцию, не подсвечивается кнопка закрытия). Первый щелчок мышью в любом месте окна "активизирует" это окно (сам щелчок при этом "съедается" и не обрабатывается по назначению), после чего оно отрисовывается полностью и начинает корректно работать и реагировать на события.

Для эксперимента добавил обычную кнопку, которая так же скрывает окно через SW_HIDE — с ней такой проблемы нет, только с кнопкой закрытия окна. Прошу помощи, почему такое может происходить и как сие побороть. Гугление ничего не дало.

Тестовый проект (VS 2015)

P.S. Вместо скрытия-показа диалога можно, конечно, его уничтожать его и заново создавать. Не исключено, что это решило бы проблему, но мне не хотелось костылить дополнительное скрытое окно исключительно для обработки событий от трей-значка. Кроме того, хочется понять, что же я делаю неправильно.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re: Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: Alexander G Украина  
Дата: 11.07.17 13:56
Оценка: 6 (1)
Здравствуйте, CaptainFlint, Вы писали:

https://github.com/CaptainFlint/test_hide_on_close/blob/master/Source.cpp

INT_PTR CALLBACK DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
...
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}


DialogProc — это не оконная процедура.
Оттуда DefWindowProc не вызывают.
Для подавления стандартной обработки возвращают не-нуль.
Русский военный корабль идёт ко дну!
Re[2]: Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 11.07.17 14:12
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>DialogProc — это не оконная процедура.

AG>Оттуда DefWindowProc не вызывают.
AG>Для подавления стандартной обработки возвращают не-нуль.

Вот чёрт, сначала было обычное окно, потом переделывал в диалог и не обратил внимания, что они ведут себя настолько по-разному.
return TRUE в нужных местах тут же всё пофиксил. Спасибо!
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[2]: Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: CEMb  
Дата: 12.07.17 02:35
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>
AG>        return DefWindowProc(hWnd, message, wParam, lParam);
Раз такое дело, то спрошу заодно: есть такая функция DefDlgProc, зачем она нужна? Обычно для диалогов всегда в кастомных обработчиках возвращают 0. Думаю, тут есть какие-то тонкости.
Re[3]: Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: Alexander G Украина  
Дата: 12.07.17 04:43
Оценка: 6 (1)
Здравствуйте, CEMb, Вы писали:

CEM>[/ccode]Раз такое дело, то спрошу заодно: есть такая функция DefDlgProc, зачем она нужна? Обычно для диалогов всегда в кастомных обработчиках возвращают 0. Думаю, тут есть какие-то тонкости.


Не для вызова из DialogProc

The DefDlgProc function must not be called by a dialog box procedure; doing so results in recursive execution.


А вот для чего
Another different type of dialog procedure
Русский военный корабль идёт ко дну!
Re[4]: Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: CEMb  
Дата: 12.07.17 06:08
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>А вот для чего

AG>Another different type of dialog procedure

эх, что-то я опять протупил, мне стоило самому до этого додуматься
под эту же ситуацию попадают диалоги, которым сделали SetWindowLongPtr(..., DWLP_DLGPROC, ...);
Re[5]: Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: Alexander G Украина  
Дата: 12.07.17 06:35
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>под эту же ситуацию попадают диалоги, которым сделали SetWindowLongPtr(..., DWLP_DLGPROC, ...);


Ну, то уже такое. Лучше будет делать CallWindowProc на том, что вернулось из SetWindowLongPtr.
Универсально для разных сабклассов, плюс пытаемся поддерживать цепочку сабклассов.
Русский военный корабль идёт ко дну!
Re[6]: Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: CEMb  
Дата: 12.07.17 08:23
Оценка:
Здравствуйте, Alexander G, Вы писали:

CEM>>под эту же ситуацию попадают диалоги, которым сделали SetWindowLongPtr(..., DWLP_DLGPROC, ...);


AG>Ну, то уже такое. Лучше будет делать CallWindowProc на том, что вернулось из SetWindowLongPtr.


Да, но в случае, если он потерялся, я раньше звал DefWindowProc. Ну, правда, он никогда не терялся, но порядок нужен

AG>Универсально для разных сабклассов, плюс пытаемся поддерживать цепочку сабклассов.


Такое сложное у меня тока один раз было, при перехвате MFС-шных контролов и теоретическом переключении схемы отображения (MFC так не делает, оно не смотрит, что там в DWLP_WNDPROC, и тупо перетирает значения. Приходилось следить ещё за этим. Т.е. я делаю SetWindowLong, снимаю MFC-обработчик, ставлю свой, потом щёлкают схему, MFC идёт, не глядя убирает мой, ставит штатный, ждёт полного переколбаса системы, ставит свой обратно)
Re[7]: Скрытие окна вместо закрытия: окно неактивно при восстановлении
От: Alexander G Украина  
Дата: 12.07.17 08:29
Оценка:
Здравствуйте, CEMb, Вы писали:


CEM>Да, но в случае, если он потерялся,




Тогда уж быть перфекционистом до конца: звать GetClassName, GetClassInfoEx, и вызывать WNDCLASSEX::lpfnWndProc через CallWindowProc
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.