Windows для профессионалов


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


Чтобы упростить перенос таких приложений в Win32, Microsoft и пошла на эти ухищрения. А поскольку в 16-разрядной Windows нет новых элементов управления, то проблемы их переноса тоже нет, и Microsoft ничего подобного для них делать не стала.

Сразу после запуска DIPS получает описатель окна элемента управления LisrView рабочего стола:

// окно ListView рабочего стола - "внук" окна ProgMan

hwndLV = GetFirstChild(GetFirstChild(hindWindow(__TEXT("ProgHan"), NULL)));

Этот код сначала ищет окно класса ProgMan. Даже несмотря на то что никакой Program Manager не запускается, новая оболочка по-прежнему создает окно этого класса — для совместимости с приложениями, рассчитанными на старые версии Windows. У окна ProgMan единственное дочернее окно класса SHELLDLL_DefView, у которого тоже одно дочернее окно — класса SysListView32. Оно-то и служит элементом управления ListView рабочего стола. (Кстати, всю эту информацию я выудил благодаря Spy++.)

Получив описатель окна ListView, я определяю идентификатор создавшего его потока, для чего вызываю GetWindowThreadProcessId. Этот идентификатор я передаю функции SetDIPSHook, реализованной в DIPSLib.cpp. Последняя функция устанавливает ловушку WH_GETMESSAGE для данного потока и вызывает:

PostThreadMessage(dwThreadId, WM_NULL, 0, 0);

чтобы разбудить поток Windows Explorer. Поскольку для него установлена ловушка WH_GETMESSAGE, операционная система автоматически внедряет мою DIPSLib.dll в адресное пространство Explorer и вызывает мою функцию GetMsgProc. Та сначала проверяет, впервые ли она вызвана, и, если да, создает скрытое окно с заголовком "Richter DIPS". Возьмите на заметку что это окно создается потоком, принадлежащим Explorer. Пока окно создается, поток DIPS.exc возвращается из функции SetDIPSHook и вызывает:

GetMessage(&msg, NULL, 0, 0);

Этот вызов "усыпляет"- поток до появления в очереди какого-нибудь сообщения Хотя DIPS,exe сам не создает ни одного окна, у него всс же есть очередь сообщений, и они помещаются туда исключительно в результате вызовов PostThreadMessage. Взгляните на код GetMsgProc в DIPSLih.cpp: сразу после обращения к CreateDialog стоит вызов PostThreadMessage, который вновь пробуждает поток DIPS exe.


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



Книжный магазин