Теперь наша ловушка вполне работоспособна, и можно приступать к насыщению её функциональностью. Поскольку функция может быть вызвана в адресном пространстве другого процесса, она не может вызывать функции главной программы. Простейший способ известить программу о срабатывании ловушки – послать сообщение какому-то из её окон. Но какому окну, и какое сообщение? Рассмотрим эти вопросы по отдельности.
Какому окну?
Для того чтобы послать окну сообщение, необходимо знать его идентификатор (handle). Можно, конечно, послать сообщение сразу всем окнам Windows, указав в качестве идентификатора окна HWND_BROADCAST, но делать это по каждому нажатию клавиши – значит неоправданно увеличить нагрузку на всю систему. Поэтому, лучше выделить в области обмена, наряду с HookHandle еще одну переменную – FormHandle – в которую вызывающая программа перед установкой ловушки должна записать идентификатор окна, обрабатывающего сообщения от ловушки.
Какое сообщение?
В Windows одновременно выполняются десятки программ. Поэтому, особенно при получении сообщений от других процессов всегда есть некоторая вероятность, что жестко закодированные номера сообщений (типа WM_APP + 1234) в разных программах совпадут, что приведет к их некорректной работе. Поэтому, для целей обмена между процессами лучше получить общий уникальный номер сообщения. Для этого служит функция:
function RegisterWindowMessage(
lpString: PChar // уникальная текстовая строка
): UINT; stdcall;
Функция проверяет, было ли уже зарегистрировано сообщение с параметром lpString. Если еще нет – «выдается» уникальный в пределах сессии Windows номер, если да – возвращается ранее полученный номер.
Получение номера удобно разместить в тот же модуль, что и область обмена, а в качестве lpString использовать тот же идентификатор UniqueHookId.
Таким образом, модуль, предназначенный для обмена, принимает окончательный вид:
Code: |
unit Exchange;
interface
uses Windows;
type PKeyboardHookInfo = ^TKeyboardHookInfo; TKeyboardHookInfo = packed record FormHandle: THandle; HookHandle: THandle; end;
var WMKeyHook: Integer = 0; CommonArea: PKeyboardHookInfo = NIL;
implementation
var Mapping: THandle = 0;
const UniqueHookId = '{F61D1A60-4DB8-11D3-89E9-9579FCF8927A}'; // Для генерации уникального идентификатора удобно использовать GUID // Просто нажмите Ctrl+Shift+G в среде разработки Delphi – // и Вы получите статистически уникальную строку
initialization Mapping := CreateFileMapping(-1, NIL, PAGE_READWRITE, 0, SizeOf(CommonArea), UniqueHookId); CommonArea := MapViewOfFile(Mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); WMKeyHook := RegisterWindowMessage(UniqueHookId);
finalization if Assigned(CommonArea) then UnmapViewOfFile(CommonArea); if Mapping <> 0 then CloseHandle(Mapping); end. |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!