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


Пример внедрения DLL


Допустим, Вы хотите создать подкласс от экземпляра окна, порожденного другим процессом. Это, как Вы помните, позволит изменять поведение окна Все, что от Вас для этого требуется, — вызвать функцию SetWindowLongPtr, чтобы заменить адрес оконной процедуры в блоке памяти, принадлежащем окну, новым — указывающим на Вашу функцию WndProc. В документации Platform SDK утверждастся, что приложение

не может создать подкласс окна другого процесса Это не совсем верно Проблема создания подкласса окна из другого процесса па самом деле сводится к преодолению границ адресного пространства

Вызывая SetWindowLongPtr для создания подкласса окна (как показано ниже), Вы говорите системе, что все сообщения окну, на которое указывает hwnd, следует направлять не обычной оконной процедуре, а функции MySubclassProc

SetWindowLongPtr(hwnd, GWLP_WNDPROC, MySubclassProc);

Иными словами, когда системе надо передать сообщение процедуре WndProc указанного окна, она находит ее адрес и вызывает напрямую В нашем примере система видит, что с окном сопоставлен адрес функции MySubclassProc, и поэтому вызывает именно ее, а нс исходную оконную процедуру

Проблема с созданием подкласса окна, принадлежащего другому процессу, состоит в том, что процедура подкласса находится в чужом адресном пространстве Упрощенная схема приема сообщений оконной процедурой представлена па рис 22.1 Процесс А создает окно На адресное пространство этого процесса проецируется файл User32.dlI Эта проекция User32.dll О1вечает за прием и диспетчеризацию сообщений (синхронных и асинхронных), направляемых любому из окон, созданных потоками процесса А Обнаружив кякое-то сообщение, она определяет адрес процедуры WndProc окна и вызывает ее, передавая описатель окна, сообщение и параметры wParam и lParam Когда WndProc обработает сообщение, Uscr32 dll вернется в начало цикла и будет ждать следующее оконное сообщение

rihter22-1.jpg

Рис. 22-1. Поток процесса В пытается создать подкласс окна, сформированного потоком процесса А

Теперь допустим, что процесс В хочет создать подкласс окна, порожденного одним из потоков процесса А Сначала код процесса В должен определить описатель этого окна, что можно сделать самыми рязными способами В примере на рис 22-1 поток процесса В просто вызывает FindWindow, затем — SetWtndowLongPtr, пытаясь изменить адрес процедуры WndProc окна Обратитевниманис пытаясь Этот вызов не дает ничего, кроме NULL Функция SetWindowLongPtr просто проверяет, не хочет




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