IT-Блог о программировании и операционных системах

Расширяем возможности Delphi / Builder IDE

6 комментариев:
В данной заметке, хочу поделиться с вами хорошим примером написания модуля, с помощью которого можно добавить новые возможности в вашу Delphi IDE.
Пример из этой статьи довольно простой, но между тем и очень эффективный. Он позволяет очень легко добавить обработчик события (назовём его обработчиком нажатия средней кнопки мыши), в среду Delphi, путём обработки сообщений Windows.
Пусть, для примера, в обработчике будет выполняться код, отвечающий за программное нажатие клавиши F12, тем самым позволяя нам переключаться между окнами исходного кода и дизайнера форм по средней кнопке мыши. Очень удобно, правда?
unit WinSwap;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms;

type
  TWinSwap = class(TObject)
    private
      fIDE:TApplication;
      procedure PressKey(Key:Word);
    protected
      procedure IDEMessage(var Msg: TMsg; var Handled: Boolean);
    public
      property IDE:TApplication read fIDE write fIDE;
  end;

var
  oSwaper: TWinSwap;

implementation

procedure SwapInit;
begin
  { связываем поле fIDE со средой Delphi }
  oSwaper.IDE := Application;
  { устанавливаем новый обработчик OnMessage }
  oSwaper.IDE.OnMessage := oSwaper.IDEMessage;
end;

{ TWinSwap }
procedure TWinSwap.IDEMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if IDE.Active then
    begin
      if Msg.Message = WM_MBUTTONUP then
      PressKey(VK_F12);
    end
  else
    Exit;
end;

procedure TWinSwap.PressKey(Key: Word);
begin
  keybd_event(Key,0,KEYEVENTF_EXTENDEDKEY,0);
  keybd_event(Key,0,KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,0);
end;

initialization
  oSwaper := TWinSwap.Create;
  { инициализируем расширение }
  SwapInit;

finalization
  { скидываем обработчик }
  oSwaper.IDE.OnMessage := nil;
  oSwaper.Free;
end.
Как видите, код не самый сложный и разобраться в нём не составит никакого труда. Ключевые строки располагаются в процедуре SwapInit. Происходит присвоение значения объекта Application (которое рассматривается как объект самой среды) полю fIDE типа TApplication и затем устанавливаем новый обработчик OnMessage уже самой IDE.
Таким образом можно обрабатывать многие полезные сообщения, приходящие из вне. Можно работать с отдельными частями IDE как с простыми компонентами, средствами объекта Application.  Вообщем можно много всего, главное приложить немного фантазии, которой у меня к сожалению не много.

Установка

Установка такого модуля сводится к обычной инсталляции нового компонента в новый, или существующий пакет. Другими словами, установка такого модуля и нового компонента ничем не отличается.
Надеюсь, этот пример был полезен для вас. С наилучшими пожеланиями. Читайте новые интересные заметки на страницах блога Delphi Day.

Правильная версия


Если вы прочитаете комментарии ниже, поймете, что данная версия кода мягко говоря не очень правильная. Как я там написал, что:


Если написать ещё один подобный (компонент?, даже не знаю как правильно назвать) модуль. То при его инициализации, обработчик OnMessage как бы перекроет обработчики всех остальных, инсталлированых до него, что собственно одно и тоже (с небольшими поправками), о чём говорил USoft.

Я немного дополнил код, следуя совету USoft. Проверял на 10ти таких установленных в систему расширений. Теперь всё работает прекрасно. Испытания проводил в двух средах: D7, D2k6.
Хотел бы отдельно поблагодарить Алексея Тимохина за расшифровку совета USoft и USoft'a, за дельный совет. Спасибо, коллеги.
 Итак, правильная версия скорее всего должна быть такая:



unit WinSwap;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms;

type
  TIDEHandler = procedure (var Msg:TMsg; var Handled: Boolean) of object;
  TWinSwap = class(TObject)
    private
      fIDE:TApplication;
      fIDEHandler:TIDEHandler;
      procedure PressKey(Key:Word);
    protected
      procedure IDEMessage(var Msg: TMsg; var Handled: Boolean);
      procedure BuffHandler;
    public
      property IDE:TApplication read fIDE write fIDE;
      property Handler:TIDEHandler read fIDEHandler write fIDEHandler;
  end;

var
  oSwaper: TWinSwap;

implementation

procedure SwapInit;
begin
  { связываем поле fIDE со средой Delphi }
  oSwaper.IDE := Application;
  oSwaper.BuffHandler;
  { устанавливаем новый обработчик OnMessage }
  oSwaper.IDE.OnMessage := oSwaper.IDEMessage;
end;

{ TWinSwap }
procedure TWinSwap.BuffHandler;
begin
  Handler := oSwaper.IDE.OnMessage;
end;

procedure TWinSwap.IDEMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if IDE.Active then
    begin
      if Msg.Message = WM_MBUTTONUP then
        PressKey(VK_F12);
      Handler(Msg,Handled);
    end
  else
    begin
      Handler(Msg,Handled);
      Exit;
    end;
end;

procedure TWinSwap.PressKey(Key: Word);
begin
  keybd_event(Key,0,KEYEVENTF_EXTENDEDKEY,0);
  keybd_event(Key,0,KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,0);
end;

initialization
  oSwaper := TWinSwap.Create;
  { инициализируем расширение }
  SwapInit;

finalization
  { скидываем обработчик }
  oSwaper.IDE.OnMessage := nil;
  oSwaper.Free;
end.