Прерывание сообщений Windows в невизуальных компонентах
Например, предположим, что мы разрабатываем невизуальный компонент, который регистрирует наше приложение как окно просмотра буфера обмена, чтобы приложение могло отвечать на изменения в буфере обмена.
Чтобы получить информацию относительно изменения буфера обмена, наш компонент долен получить сообщение от Windows.
Функция Delphi AllocateHWnd используется, чтобы создать скрытое окно, а DeallocateHWnd распорядится с окном, когда мы закончим с ним работу.
Скрытое окно нуждается в оконной процедуре. Мы можем использовать метод нашего класса компонента. AllocateHWnd получает ссылку на этот метод как параметр. В методе мы обрабатываем сообщения, которые нам нужны, остальное поручаем Windows, используя вызов API DefWindowProc.
Следующий код - это скелетная часть как использовать AllocateHWnd.
type
// Класс, полученный от TComponent
// (или любой другой класс)
TMyClass = class(TComponent)
private
FHWnd: HWND;
// поле для хранения дескриптора окна
...
protected
procedure WndMethod(var Msg: TMessage); virtual;
// оконная процедура, вызываемая Windows
// для обработки данного сообщения
{ ... }
public
constructor Create(AOwner: TComponent); override;
// здесь создаем window proc
destructor Destroy; override;
// здесь освободить window proc
{ ... }
end;
Выполнение:
TMyClass.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{ ... }
// Создаем окно
FHWnd := AllocateHWnd(WndMethod);
{ ... }
end;
TMyClass.Destroy;
begin
{ ... }
// Уничтожаем окно
DeallocateHWnd(FHWnd);
{ ... }
inherited Destroy;
end;
TMyClass.WndMethod(var Msg : TMessage);
var
Handled: Boolean;
begin
// Предположим, что мы обрабатываем сообщение
Handled := True;
case Msg.Msg of
WM_SOMETHING: DoSomething;
// Код обработки сообщения
WM_SOMETHINGELSE: DoSomethingElse;
// Код обработки другого сообщения
...
else
// не обрабатывали сообщение
Handled := False;
end;
if Handled then
// Мы обработали сообщение -
// записываем результат сообщения
Msg.Result := 0
else
// Мы не обрабатывали сообщение
// передаем в DefWindowProc и записываем результат
Msg.Result := DefWindowProc(FHWnd, Msg.Msg,
Msg.WParam, Msg.LParam);
end;
Конечно, можно использовать только Windows API, это более жесткий способ.
Комментарии