My-library.info
Все категории

Валерий Борисок - Delphi. Трюки и эффекты

На электронном книжном портале my-library.info можно читать бесплатно книги онлайн без регистрации, в том числе Валерий Борисок - Delphi. Трюки и эффекты. Жанр: Программы издательство неизвестно, год 2004. В онлайн доступе вы получите полную версию книги с кратким содержанием для ознакомления, сможете читать аннотацию к книге (предисловие), увидеть рецензии тех, кто произведение уже прочитал и их экспертное мнение о прочитанном.
Кроме того, в библиотеке онлайн my-library.info вы найдете много новинок, которые заслуживают вашего внимания.

Название:
Delphi. Трюки и эффекты
Издательство:
неизвестно
ISBN:
нет данных
Год:
неизвестен
Дата добавления:
17 сентябрь 2019
Количество просмотров:
283
Читать онлайн
Валерий Борисок - Delphi. Трюки и эффекты

Валерий Борисок - Delphi. Трюки и эффекты краткое содержание

Валерий Борисок - Delphi. Трюки и эффекты - описание и краткое содержание, автор Валерий Борисок, читайте бесплатно онлайн на сайте электронной библиотеки My-Library.Info
«Delphi. Трюки и эффекты», как и все издания данной серии, адресована тем, кто хочет научиться делать с помощью уже знакомых программных пакетов новые, интересные вещи. В первой части книги многое говорится о среде разработки Delphi (самых последних версий) и программировании на языке Object Pascal. Благодаря этому издание подходит и новичкам, и начинающим программистам. Вторая (основная) часть книги описывает удивительные возможности, скрытые в языке, и на примерах учит читателя программистским фокусам – от «мышек-невидимок» и «непослушных окон» до воспроизведения МРЗ и управления офисными программами Word и Excel из приложений Delphi. Купив эту книгу, вы пройдете непростой путь к вершинам программистского мастерства весело и интересно.

Delphi. Трюки и эффекты читать онлайн бесплатно

Delphi. Трюки и эффекты - читать книгу онлайн бесплатно, автор Валерий Борисок

);

Загрузка фильтра (выбранных и невыбранных сообщений в соответствующие списки) производится очень просто (листинг 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;

cmbStart.Caption := 'Начать слежение

end;

end;

Как можно увидеть, вся сложность на стороне приложения-шпиона состоит в создании/удалении проекции файла и в вызове двух экспортируемых из библиотеки hook, dll функций. Они подключаются следующим объявлением:

...

function InstallHook(wnd: HWND; spy: HWND): Boolean stdcall;

external 'hookhook.dll' name 'InstallHook

function RemoveHook(): Boolean stdcall;

external 'hookhook.dll' name 'RemoveHook

Для обработки сообщения WM_SPY_NOTIFY, посылаемого ловушкой, переопределена оконная процедура формы f rmMessages (листинг 10.19).

...

Листинг 10.19.

Обработка сообщения WM_SPY_NOTIFY

procedure TfrmMessages.WndProc(var Message: TMessage);

var

item: TListItem;

i: Integer;

begin

if (Message.Msg = WM_SPY_NOTIFY) and (hook_info <> nil) then

begin

//Обрабатываем уведомление о приходе сообщения в наблюдае-

мое окно

for i := mess_first to mess_last do

if (messages_list[i].value = hook_info^.mess) and

messages_list[i].used then

begin

//Сообщение выбрано в фильтре – добавим запись в список

item := lvwMessages.Items.Add();

item.Caption := messages_list[i].name;

item.SubItems.Add(IntToStr(hook_info^.wParam));

item.SubItems.Add(IntToStr(hook_info^.lParam));

end;

end

else

inherited WndProc(Message);

end;

Ловушка

Теперь обратимся к реализации самой ловушки. По рассмотренным ранее причинам ловушка размещена в отдельной DLL (hookhook.dll на прилагаемом к книге диске в папке с номером главы). На случай, если вы не знакомы с созданием DLL средствами Delphi, приведем краткие сведения.

Среда программирования Delphi замечательна тем, что позволяет просто делать довольно сложные вещи. Хотя и при использовании сред разработки, скрывающих меньшее количество сложных деталей, например Visual C++, создание DLL не является очень сложной задачей. Итак, для создания DLL в простейшем, то есть нашем, случае достаточно выполнить следующие действия.

1. Создать соответствующий проект (с помощью команды меню FiLe → New → Other, тип проекта – DLL Wizard) (рис. 10.6).

2. В DPR-файле получившегося проекта реализуем функции, которые предполагается экспортировать.

3. Объявляем, какие функции нужно экспортировать с помощью ключевого слова exports (листинг 10.20).

Рис. 10.6. Создание проекта DLL

Структура DLL ловушки, реализованной в нашем примере, приведена в листинге 10.20.

...

Листинг 10.20.

DLL ловушки без реализации функций

library hook;

uses

Windows,

HookData;

//****************************************************

//Экспортируемые функции

function InstallHook(wnd: HWND; spy: HWND): Boolean stdcall;

forward;

function RemoveHook(): Boolean stdcall; forward;

exports

InstallHook,

RemoveHook;

//****************************************************

begin

hook_info := nil;

hFile := 0;

end.

Код после begin является кодом инициализации библиотеки (выполняется при загрузке DLL в память процесса). Правда, как показали многочисленные эксперименты, проведенные во время написания и отладки ловушки, код этот не выполняется при загрузке DLL ловушки в адресное пространство другого процесса.

Теперь обратимся к реализации экспортируемых функций InstallHook, а также RemoveHook. Как вы помните, только эти две функции вызываются из программы-шпиона. Начнем с функции установки ловушки (листинг 10.21).

...

Листинг 10.21.

Установка (создание) ловушки

function InstallHook(wnd: HWND; spy: HWND): Boolean stdcall;

begin

//Открываем проекцию файла (области файла подкачки)

if not GetFileMapping() then

begin

//Не удалось спроецировать файл в память

InstallHook := False;

Exit;

end;

//Сохраняем данные, необходимые для работы ловушки

hook_info^.wnd := wnd;

hook_info^.spy_wnd := spy;

//Создаем ловушку

if (GetWindowThreadProcessId(wnd) <> 0)

then

hook_info^.hook_handle :=

SetWindowsHookEx(WH_CALLWNDPROC, WndProcHook,

hInstance, GetWindowThreadProcessId(wnd))

else

//Создание ловушки для потоков нашего приложения

//было бы фатальным

hook_info^.hook_handle := 0;

InstallHook := hook_info^.hook_handle <> 0;

//Освободим проекцию файла

ReleaseFileMapping();

end;

Функция InstallHook использует глобальную переменную-указатель hook_inf о, которая объявлена в модуле HookData. Функция GetFileMapping, также используемая в листинге 10.21, связывает указатель hookinf о с областью памяти, на которую проецируется файл. Соответственно, процедура ReleaseFileMapping отменяет проецирование файла в память (после этого использовать указатель hookinf о нельзя).

API-функция GetWindowThreadProcessId используется для определения идентификатора потока, создавшего наблюдаемое окно. Проверка неравенства значения, возвращенного этой функцией, нулю используется для того, чтобы в случае закрытия интересующего нас окна до запуска ловушки мы не начали следить за окнами приложения-шпиона.

Работу с проецируемым файлом в ловушке рассмотрим чуть позже. Сейчас же обратимся к функции удаления ловушки, реализация которой приводится в листинге 10.22.

...

Листинг 10.22.

Удаление ловушки

function RemoveHook(): Boolean stdcall;

begin

if GetFileMapping() then

begin

if hook_info^.hook_handle <> 0 then

//Удаляем ловушку

UnhookWindowsHookEx(hook_info^.hook_handle);

//Закрываем проекцию файла

ReleaseFileMapping();

RemoveHook := True;

end

else

RemoveHook := False;

end;

Тут все просто и не требует подробного пояснения. Теперь же рассмотрим так часто используемые функцию и процедуру, работающие с проекцией файла в память. Функция GetFileMapping, приведенная в листинге 10.23, открывает проекцию файла в память и связывает указатель hookinf о с областью памяти, отведенной для проекции файла.

...

Листинг 10.23.

Открытие проекции файла

function GetFileMapping(): Boolean;

begin

//Пытаемся открыть проекцию файла

hFile := OpenFileMapping(FILE_MAP_WRITE, False, PAnsiChar(strFileMapName));

//Получаем адрес разделяемой памяти

hook_info := MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0, SizeOf(THookInfo));

GetFileMapping := hook_info <> nil;


Валерий Борисок читать все книги автора по порядку

Валерий Борисок - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки My-Library.Info.


Delphi. Трюки и эффекты отзывы

Отзывы читателей о книге Delphi. Трюки и эффекты, автор: Валерий Борисок. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.