Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Переопределение оконной процедуры и метода для другой формы

Delphi , Программа и Интерфейс , Формы

Переопределение оконной процедуры и метода для другой формы



unit SubSecon;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TForm2 = class(TForm)
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

procedure TForm2.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Caption := Format ('Cursor in %d, %d', [X, Y]);
end;

end.


unit SubMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    BtnShow: TButton;
    BtnProc: TButton;
    BtnMeth: TButton;
    procedure BtnShowClick(Sender: TObject);
    procedure BtnMethClick(Sender: TObject);
    procedure BtnProcClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    OldWndMeth, NewWndMeth: Pointer;
    SubControl: TWinControl;
  public
    procedure NewWinMethod (var Msg: TMessage);
  end;

var
  Form1: TForm1;

implementation

uses SubSecon;

{$R *.DFM}

var
  OldWndProc: Pointer = nil;

function NewWinProc (Handle: THandle;
  Msg, wParam, lParam: LongInt): LongInt; stdcall;
begin
  if Msg = wm_RButtonDown then
  begin
    Beep;
    SetWindowText (Handle,
      PChar (Format ('Right click in %d, %d', [
        LoWord (lParam), HiWord (lParam)])));
  end;
  // pass call to old window proc
  Result := CallWindowProc (OldWndProc, Handle,
    Msg, wParam, lParam);
end;

procedure TForm1.NewWinMethod (var Msg: TMessage);
begin
  if Msg.Msg = wm_LButtonDown then
  begin
    Beep;
    SubControl.SetTextBuf (
      PChar (Format ('Left click in %d, %d', [
        LoWord (Msg.lParam), HiWord (Msg.lParam)])));
  end
  else
    Msg.Result := CallWindowProc (OldWndMeth,
      SubControl.Handle, Msg.Msg, Msg.WParam, Msg.LParam);
end;

procedure TForm1.BtnShowClick(Sender: TObject);
begin
  Form2.Show;
end;

procedure TForm1.BtnProcClick(Sender: TObject);
begin
  OldWndProc := Pointer (SetWindowLong
    (Form2.Handle, gwl_WndProc, LongInt (@NewWinProc)));
  BtnProc.Enabled := False;
  end;

procedure TForm1.BtnMethClick(Sender: TObject);
begin
  SubControl := Form2;
  NewWndMeth := MakeObjectInstance (NewWinMethod);
  OldWndMeth := Pointer (SetWindowLong (
    SubControl.Handle, gwl_WndProc, Longint (NewWndMeth)));
  BtnMeth.Enabled := False;
    end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Assigned (NewWndMeth) then
    FreeObjectInstance (NewWndMeth);
end;

end.

Загрузить исходный код проекта

Это проект Delphi, демонстрирующий переопределение процедур и методов окон для другого формы.

Единица SubSecon определяет форму (TForm2) с частным методом FormMouseMove, который обновляет заголовок формы для отображения текущей позиции курсора (X, Y) при перемещении мыши.

Единица SubMain определяет основную форму (TForm1) с тремя кнопками: BtnShow, BtnProc и BtnMeth. Каждая кнопка имеет соответствующий обработчик события:

  • BtnShowClick: Показывает вторую форму (TForm2).
  • BtnProcClick: Переопределяет процедуру окна второй формы с помощью пользовательской процедуры NewWinProc.
  • BtnMethClick: Переопределяет метод окна подклассированного контроля (SubControl) в второй форме с помощью пользовательского метода NewWinMethod.

Когда вы кликните BtnProc, процедура окна второй формы будет заменена на NewWinProc. Эта процедура издаёт звук и устанавливает заголовок формы для отображения позиции курсора при нажатии правой кнопки мыши.

Когда вы кликните BtnMeth, метод окна подклассированного контроля в второй форме будет заменен на NewWinMethod. Эта метод издаёт звук и обновляет текст контроля для отображения позиции курсора при нажатии левой кнопки мыши.

Обратите внимание, что пользовательские процедуры и методы вызываются через оригинальную процедуру окна и метод соответственно. Проект использует функции Delphi SetWindowLong и CallWindowProc, чтобы достичь этого.

Вот предложение по улучшению:

Вместо использования SetWindowLong и CallWindowProc, вы можете использовать встроенную поддержку Delphi для процедур и методов окон через интерфейс TWndMethod. Это может сделать ваш код более читаемым и maintainable.

Например, вы можете определить класс пользовательской процедуры окна, реализующий интерфейс TWndMethod:

type
  TCustomWindowProc = class(TWndMethod)
    procedure WndProc(var Msg: TMessage);
  end;

Затем создайте экземпляр этого класса и присвойте его событию OnMessage формы:

procedure TForm1.BtnProcClick(Sender: TObject);
begin
  Form2.OnMessage := MyCustomWindowProc;
  BtnProc.Enabled := False;
end;

procedure TCustomWindowProc.WndProc(var Msg: TMessage);
begin
  // Пользовательская реализация процедуры окна
  if Msg.Msg = WM_RBUTTONDOWN then
    Beep;
  SetWindowText(Form2.Handle, PChar(Format('Right click in %d, %d', [LoWord(Msg.lParam), HiWord(Msg.lParam)])));
end;

Эта APPROACH более проста и легче поддерживать, чем использование SetWindowLong и CallWindowProc.

Переопределение оконной процедуры и метода для другой формы позволяет изменять поведение окна, в том числе обработку событий и передачу управляющих сообщений.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Формы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 12:20:45/0.0039498805999756/0