Прерывание сообщений 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, это более жесткий способ.
Комментарии