Внешний вид сайта:

Прерывание сообщений Windows в невизуальных компонентах

Как неоконный компонент может получать сообщения от Windows? Иногда мы нуждаемся в неоконных компонентах (т.е. тех, которые получены не от TWinControl), чтобы получать сообщения 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, это более жесткий способ.

Комментарии

Нет комментариев. Ваш будет первым!