Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Утилита для сохранения позиций элементов на рабочем столе - часть 4


Очередь сообщений я использую для синхронизации потоков. В этом нет ничего противозаконного, и иногда гораздо проще синхронизировать потоки именно так, не прибегая к объектам ядра — мьютексам, семафорам, событиям и т. д. (В Windows очень богатый API; пользуйтесь этим.)

Когда поток DIPS.exe пробуждается, он узнает, что серверное диалоговос окно уже создано, и обращается к FindWmdow, чтобы получить его описатель. С этого момента для оргапичации взаимодействия между клиентом (утилитой DIPS) и сервером (скрытым диалоговым окном) можно использовать механизм оконных сообщений. Поскольку это диалоговое окно создано потоком, выполняемым в контексте процесса Explorer, нас мало что ограничивает в действиях с Explorer.

Чтобы сообщить своему диалоговому окну сохранить или восстановить позиции ярлыков на экране, достаточно послать сообщение:

// сообщаем окну DIPS, c каким окном ListView работать

// и что делать: сохранять или восстанавливать позиции ярлыков

SendMessage(hwndDIPS, WM_APP, (WPARAM) hwndLV, fSave);

Процедура диалогового окна проверяет сообщение WM_APP. Когда она принимает это сообщение, параметр wParam содержит описатель нужного элемента управления ListView, a lParam — булево значение, определяющее, сохранять текущие позиции ярлыков в реестре или восстанавливать.

Так как здесь используется SendMessage, а не PostMessage, управление не передается до завершения операции. Если хотите, определите дополнительные сообщения для процедуры диалогового окна — это расширит возможности программы в управлении Explorer. Закончив, я завершаю работу сервера, для чего посылаю ему сообщение WM_CLOSE, которое говорит диалоговому окну о необходимости самоуничтожения.

Наконец, перед своим завершением DIPS вновь вызывает SetDlPSHook, но на этот раз в качестве идентификатора потока передается 0 Получив нулевое значение, функция снимает ловушку WH_GETMESSAGE. А когда ловушка удаляется, операционная система автоматически выгружает DIPSLib.dll из адресного пространства процесса Explorer, и это означает, что теперь процедура диалогового окна болыпе не принадлежит данному адресному пространству Поэтому важно уничтожить диалоговое окно заранее — до снятия ловушки. Иначе очередное сообщение, направленное диалоговому окну, вызовет нарушение доступа. И тогда Explorer будет аварийно завершен операционной системой — с внедрением DLL шутки плохи!

Dips

DIPSLib




Начало  Назад  Вперед