(
(value: WM_DESTROY; name: \'WM_DESTROY\ used: False),
(value: WM_MOVE; name: \'WM_MOVE\ used: False),
(value: WM_SIZE; name: \'WM_SIZE\ used: False),
(value: WM_ACTIVATE; name: \'WM_ACTIVATE\ used: False),
(value: WM_SETFOCUS; name: \'WM_SETFOCUS\ used: False),
(value: WM_KILLFOCUS; name: \'WM_KILLFOCUS\ used: False),
(value: WM_ENABLE; name: \'WM_ENABLE\ used: False),
(value: WM_SETTEXT; name: \'WM_SETTEXT\ used: False),
(value: WM_GETTEXT; name: \'WM_GETTEXT\ used: False),
(value: WM_PAINT; name: \'WM_PAINT\ used: False),
(value: WM_CLOSE; name: \'WM_CLOSE\ used: False),
(value: WM_QUIT; name: \'WM_QUIT\ used: False),
(value: WM_SIZING; name: \'WM_SIZING\ used: False),
(value: WM_MOVING; name: \'WM_MOVING\ used: False),
(value: WM_NOTIFY; name: \'WM_NOTIFY\ used: False),
(value: WM_NCHITTEST; name: \'WM_NCHITTEST\ used: False)
);
Загрузка фильтра (выбранных и невыбранных сообщений в соответствующие списки) производится очень просто (листинг 10.14).
...
Листинг 10.14.
Загрузка фильтра сообщений
procedure TfrmMessages.LoadFilter();
var
i: Integer;
begin
//Загрузка фильтра сообщений
lstAvailMessages.Clear();
lstSelMessages.Clear();
for i := mess_first to mess_last do
if messages_list[i].used then
//Сообщение перехватывается
lstSelMessages.Items.Add(messages_list[i].name)
else
lstAvailMessages.Items.Add(messages_list[i].name);
end;
При обращении к форме f rmMessages, кроме загрузки фильтра, нужно произвести некоторые дополнительные действия. Поэтому работа с этой формой начинается так же, как и в случае формы свойств окна, с вызова ее специального метода (листинг 10.15).
...
Листинг 10.15.
Инициализация формы
procedure TfrmMessages.ShowMessages(wnd: HWND);
begin
self.wnd := wnd;
LoadFilter();
ShowModal();
end;
При нажатии кнопок > (выбрать) и < (отменить выбор) происходит перемещение сообщений между списками фильтра (листинг 10.16).
...
Листинг 10.16.
Перемещение сообщений между списками выбранных и доступных сообщений
procedure TfrmMessages.cmbAddMessageClick(Sender: TObject);
var
i: Integer;
begin
if lstAvailMessages.SelCount = 0 then Exit;
//Включение выбранных сообщений в список перехватываемых
for i := lstAvailMessages.Count – 1 downto 0 do
if lstAvailMessages.Selected[i] then
messages_list[GetMessageIndex(i, False)].used := True;
//Отобразим изменения в списках
LoadFilter();
end;
procedure TfrmMessages.cmDelMessageClick(Sender: TObject);
var
i: Integer;
begin
if lstSelMessages.SelCount = 0 then Exit;
//Исключение выбранных сообщений из списка перехватываемых
for i := lstSelMessages.Count – 1 downto 0 do
if lstSelMessages.Selected[i] then
messages_list[GetMessageIndex(i, True)].used := False;
//Отобразим изменения в списках
LoadFilter();
end;
Функция GetMessagelndex, используемая в листинге 10.16, реализована следующим образом (листинг 10.17).
...
Листинг 10.17.
Преобразование номера сообщения в списке в номер сообщения в массиве messages_list
function TfrmMessages.GetMessageIndex(listIndex: Integer;
used: Boolean):Integer;
var
i, count: Integer;
begin
count := 0;
for i := mess_first to mess_last do
if messages_list[i].used = used then
begin
if count = listIndex then
begin
//Нашли
GetMessageIndex := i;
Exit;
end;
Inc(count);
end;
GetMessageIndex := 0;
end;
Теперь обратимся к реализации главной функции, выполняемой формой: использованию ловушки. Итак, слежение за выбранным в дереве окном (дескриптор его сохранен в поле wnd при инициализации формы) начинается и заканчивается при нажатии кнопки cmbStart. Обработчик нажатия этой кнопки приведен в листинге 10.18.
...
Листинг 10.18.
Запуск/остановка перехвата сообщений
procedure TfrmMessages.cmbStartClick(Sender: TObject);
begin
if cmbStart.Caption <> \'Остановить\' then
begin
//Начинаем слежение
lvwMessages.Clear;
//Создаем проекцию файла
hFile := CreateFileMapping(INVALID_HANDLE_VALUE, nil,
PAGE_READWRITE,
0, SizeOf(THookInfo),
strFileMapName);
hook_info := MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0,
SizeOf(THookInfo));
//Создание ловушки
if InstallHook(wnd, frmMessages.Handle) then
cmbStart.Caption := \'Остановить\'
else
begin
//При ошибке удалим проекцию файла
UnmapViewOfFile(hook_info);
hook_info := nil;
CloseHandle(hFile);
hFile := 0;
MessageBox(Handle, \'Ошибка при создании ловушки\',
PAnsiChar(Application.Title), MB_ICONEXCLAMATION);
end;
end
else
begin
//Заканчиваем слежение (удаляем ловушку и проекцию файла)
RemoveHook();
UnmapViewOfFile(hook_info);
hook_info := nil;
CloseHandle(hFile);
hFile := 0;
Читать дальше
Конец ознакомительного отрывка
Купить книгу