Свобода кода

блог программиста

Поиск по блогу

Средства контроля действий пользователя.

19 Сентябрь 2010 . admin пишет -

Любая операционная система, включающая в себя интерфейс, представляет разработчику средства для отслеживания действий пользователя.
Суть пользовательского интерфейса Windows составляют элементы управления. Любые действия пользователя вынуждают Windows отправить приложению сообщение о том, что произошло в системе. Таким образом, если мы хотим узнать, с каким именно элементом управления взаимодействует пользователь, мы должны перехватить это сообщение. Перехват сообщений осуществляется с помощью хуков.
В операционной системе Microsoft® Windows™ хуком называется механизм перехвата особой функцией событий (таких как сообщения, ввод с мыши или клавиатуры) до того, как они дойдут до приложения. (далее…)

Рубрики: Механизм ловушек (hooks)

Работа со строками в Win API

16 Март 2010 . Alex пишет -

Функции Win API не поддерживают тип string, принятый в Delphi. Они работают со строками, оканчивающимися на #0 (нуль-терминированные строки, null-terminated strings). Это означает, что строкой называется указатель на цепочку символов. Признаком конца такой цепочки является символ #0. Раньше для таких строк использовали термин ASCIIZ. ASCII - обозначение кодировки, Z - zero. Сейчас кодировка ASCII заменена на ANSI, поэтому этот термин больше не применяется, хотя это те же самые по своей сути строки. Обычно программисту приходится работать с кодировкой ANSI, но это не единственная кодировка, поддерживаемая Windows.
(далее…)

Рубрики: Win32 API и Delphi

Графические функции Win API. Часть 2.

16 Март 2010 . Alex пишет -

Использование кистей, карандашей и шрифтов в GDI принципиально отличается от того, что привычно в Delphi. Класс TCanvas имеет свойства Brush, Pen и Font, изменение атрибутов которых приводит к выбору того или иного карандаша, шрифта, кисти. В GDI эти объекты самостоятельны, должны создаваться, получать свой дескриптор, <выбираться> в нужный контекст устройства с помощью функции SelectObject и уничтожаться после использования. Причём удалять можно только те объекты, которые не выбраны ни в одном контексте. (далее…)

Рубрики: Win32 API и Delphi

Графические функции Win API. Часть 1.

16 Март 2010 . Alex пишет -

Та часть Win API, которая служит для работы с графикой, обычно называется GDI (Graphic Device Interface). Ключевым в GDI является понятие контекста устройства (Device Context, DC). Контекст устройства - это специфический объект, хранящий информацию о возможностях устройства, о способе работы с ним и о разрешённой для изменения области. В Delphi контекст устройства представлен классом TCanvas, свойство Handle которого содержит дескриптор контекста устройства. TCanvas универсален в том смысле, что с его помощью рисование в окне, на принтере или в метафайле выглядит одинаково. То же самое справедливо и для контекста устройства. Разница заключается только в том, как получить в разных случаях дескриптор контекста.
(далее…)

Рубрики: Win32 API и Delphi

Компоненты, влияющие на обработку событий. Часть 2.

16 Март 2010 . Alex пишет -

Функции Win API GetWindowLong и SetWindowLong предназначены для получения и изменения 32-разрядного значения, связанного с данным окном. В данном случае мы с их помощью рабо-таем с 32-разрядным параметром - адресом оконной процедуры. Изменение адреса оконной процедуры с помощью SetWindowLong и есть то самое порождение оконного подкласса, о котором писалось ранее. Функция MakeObjectInstance - это та самая функция, которая превращает метод в оконную процедуру. FreeObjectInstance освобождает память, выделенную для создания кода входа и выхода функцией MakeObjectInstance.
(далее…)

Рубрики: Win32 API и Delphi

Компоненты, влияющие на обработку событий. Часть 1.

16 Март 2010 . Alex пишет -

Так как стандартные средства Delphi не позволяют использовать все инструменты Win API для работы с окнами, иногда приходится писать компоненты, модифицирующие форму. Мне, например, приходилось писать компоненты, при помещении которых на форму она становится непрямоугольной или полупрозрачной. Очень часто таким компонентам приходится обрабатывать те сообщения, которые предназначены форме-хозяину. Delphi даёт возможность компоненту перехватить сообщения, хотя, на мой взгляд, механизм перехвата оставляет желать лучшего, потому что он не допускает возможности взаимодействия нескольких перехватчиков.
Вместо общего описания алгоритма перехвата я далее просто приведу один из способов сделать это. Способ этот не единственный верный, многие детали можно модифицировать для нужд конкретной задачи, однако основная идея (и основные недостатки) никуда не денутся. Далее я буду предполагать, что компонент перехватывает сообщения владельца (Owner). Что нужно изменить, чтобы он начал перехватывать сообщения родителя (Parent), я скажу чуть позже.
Прежде всего, владелец должен быть окном, поэтому в конструкторе компонента надо проверить класс владельца. Это очень полезно ещё и потому, что тогда в остальных методах объекта можно обойтись без такой проверки, что делает код более эффективным. Чтобы предотвратить создание компонента, достаточно в его конструкторе возбудить какое-либо исключение
Метод компонента не может быть оконной процедурой, потому что методу всегда неявно передаётся <лишний> параметр Self. Поэтому нужна генерация специального кода входа и выхода для того, чтобы вызывать метод вместо оконной процедуры. Этот код генерируется с помощью специальной функции Delphi, которая создаёт в памяти нужный код и возвращает на него указатель. Поэтому компонент должен иметь указатель на этот код (я условно назову этот указатель NewWndProc). Сам метод, обрабатывающий события (условно - HookWndProc) должен иметь один параметр-переменную типа TMessage, и может быть как статическим, тик и виртуальным или динамическим. Кроме того, нужен указатель на старую процедуру, которая была до установки компонента (OldWndProc). Далее, компонент должен содержать два метода для перехвата и освобождения, которые выглядят так:
procedure TMyComponent.HookOwner;
begin
if Assigned(Owner) then
begin
OldWndProc := Pointer(GetWindowLong(TForm(Owner).Handle, GWL_WndProc));
NewWndProc := MakeObjectInstance(HookWndProc);
SetWindowLong(TForm(Owner).Handle, GWL_WndProc, LongInt(NewWndProc))
end
end;

procedure TMyComponent.UnhookOwner;
begin
if Assigned(Owner) and Assigned(OldWndProc) then
SetWindowLong(TForm(Owner).Handle, GWL_WndProc, LongInt(OldWndProc));
if Assigned(NewWndProc) then
FreeObjectInstance(NewWndProc);
NewWndProc := nil;
OldWndProc := nil
end

Рубрики: Win32 API и Delphi

Особые сообщения

16 Март 2010 . Alex пишет -

Отправка и обработка некоторых сообщений производится не по общим правилам, а с некоторыми исключениями. Приведённый ниже список таких сообщений не претендует на полноту, но всё-таки может оказаться полезным для начинающего.
(далее…)

Рубрики: Win32 API и Delphi

Сообщения, определяемые пользователем

15 Март 2010 . Alex пишет -

Использование сообщений очень удобно в тех случаях, когда нужно заставить окно выполнить какое-то действие. Поэтому Windows предоставляет возможность программисту создавать свои сообщения, которые могут быть локальными или глобальными. Использование локальных сообщений связано с некоторым риском. Дело в том, что эти сообщения должны посылаться только <своим> окнам, то есть тем, оконные процедуры которых написаны так, чтобы пра-вильно интерпретировать это сообщение. Если послать такое сообщение <чужому> окну, его реакция может быть непредсказуемой, потому что человек, писавший его оконную процедуру, мог использовать сообщение с этим же номером для своих целей. Всё это вовсе не значит, что обмен локальными сообщениями возможен только внутри одной программы: если разные программы написаны так, что они правильно понимают одно и то же локальное сообщение, они могут без каких-либо ограничений обмениваться им. Немного повторюсь: важно только чтобы отправитель и получатель сообщения одинаково понимали его. В справочной системе специально указывается, что недопустимо отправлять такие сообщения окнам классов ‘BUTTON’, ‘EDIT’, ‘LISTBOX’ и ‘COMBOBOX’.
(далее…)

Рубрики: Win32 API и Delphi

Сообщения Windows. Часть 3.

15 Март 2010 . Alex пишет -

Стандартная оконная процедура в Delphi устроена так, что она ищет среди методов класса специальные методы для обработки каждого сообщения. Эти методы во многом подобны обыкновенным виртуальным методам. Другими словами, если переопределить такой метод, будет вызван именно новый, а не старый вариант. Вообще говоря, в классе-родителе метода для обработки какого-то конкретного сообщения может и не существовать. Это, однако, никак не сказывается на синтаксисе (в отличие от обычных виртуальных методов, где приходится писать директиву virtual для вновь созданных и override для перекрытых). (далее…)

Рубрики: Win32 API и Delphi

Сообщения Windows. Часть 2.

15 Март 2010 . Alex пишет -

Кроме номера, каждое сообщение содержит два параметра - WParam и LParam. Буквы и означают и , то есть первый параметр 16-разрядный, а второй - 32-разряд-ный. Однако так было только в старых, 16-разрядных версиях Windows. В 32-разрядных версиях оба параметра 32-разрядные, несмотря на их названия. Конкретный смысл каждого параметра зависит от сообщения. В некоторых сообщениях один или оба параметра могут вообще не использоваться, в других - наоборот, двух параметров даже не хватает. В этом случае один из параметров (обычно LParam) содержит указатель на дополнительные данные. (далее…)

Рубрики: Win32 API и Delphi
стр 1 из 6123456»