Листинг 10.9.
Добавление оконного стиля
procedure TfrmWindowProp.cmbAddStyleClick(Sender: TObject);
var
style: DWORD;
addstyle: DWORD;
begin
if lstAvailStyle.ItemIndex = –1 then Exit;
//Удаление выбранного стиля окна
//..определяем, какой стиль удалить
addstyle := styles[GetStyleIndex(lstAvailStyle.ItemIndex,
False)].value;
//..вычисляем и устанавливаем новое значение стиля окна
style := GetWindowLong(wnd, GWL_STYLE);
style := style or addstyle;
SetWindowLong(wnd, GWL_STYLE, style);
//..перерисуем все окна
InvalidateRect(0, nil, True);
//Обновим список стилей окна
LoadWindowStyle();
end;
Удаление флага стиля производится аналогично добавлению, просто над битами стиля окна выполняется другая операция (листинг 10.10).
Листинг 10.10.
Удаление оконного стиля
procedure TfrmWindowProp.cmbDelStyleClick(Sender: TObject);
var
style: DWORD;
delstyle: DWORD;
begin
if lstStyle.ItemIndex = –1 then Exit;
//Удаление выбранного стиля окна
//..определяем, какой стиль удалить
delstyle := styles[GetStyleIndex(lstStyle.ItemIndex, True)].value;
//..вычисляем и устанавливаем новое значение стиля окна
style := GetWindowLong(wnd, GWL_STYLE);
style := style and not delstyle;
SetWindowLong(wnd, GWL_STYLE, style);
//..перерисуем все окна
InvalidateRect(0, nil, True);
//Обновим список стилей окна
LoadWindowStyle();
end;
После удаления или добавления оконного стиля вызывается перерисовка всех окон, чтобы проявился результат проведенной операции. Удаление и добавление дополнительных (расширенных) оконных стилей осуществляется аналогично. Только при этом используются массив exstyles, функция GetExStylelndex и константа GWL_EXSTYLE, передаваемая в функции GetWindowLongи SetWindowLong.
Что же за функция GetStylelndex используется в листинге 10.10? Она позволяет определить положение в массиве styles стиля, выбранного в списке доступных или используемых стилей (верхний список) (листинг 10.11).
Листинг 10.11.
Определение положения записи о нужном стиле
function TfrmWindowProp.GetStyleIndex(listIndex: Integer;
used: Boolean): Integer;
var
i, count: Integer;
begin
count := 0;
for i := 0 to 17 do
if styles[i].used = used then
begin
if count = listIndex then
begin
//Нашли
GetStyleIndex := i;
Exit;
end;
Inc(count);
end;
GetStyleIndex := 0;
end;
Функция GetStylelndex принимает в качестве параметров номер строки в соответствующем списке и логическое значение, от истинности или ложности которого зависит, используемые или неиспользуемые стили будут подсчитываться внутри функции.
Применение функции GetStylelndex и введение в структуру Styleinf о поля used несколько усложняет алгоритм работы с массивом стилей, но зато позволяет избавиться от постоянного перемещения данных, например, из массива доступных стилей в массив используемых стилей. К тому же пришлось бы использовать по два массива для обычных и дополнительных оконных стилей.
Перехват сообщений
Теперь рассмотрим самую сложную часть программы, отвечающую за перехват сообщений выбранного окна. Форма, ведущая статистику перехваченных сообщений, приведена на рис. 10.5.
Показанная на рис. 10.5 форма имеет имя frmMessages.
Перехватчик сообщений состоит из двух частей: части программы (ЕХЕ), отвечающей за построение фильтра сообщений, а также обрабатывающей перехваченные сообщения, и ловушки, заключенной в DLL(hook\hook.dll).
Взаимодействие ловушки и ЕХЕ-файла построено по следующей схеме.
1. Из приложения вызываются функции создания и удаления ловушки (расположенные в DLL).