Roland Bengtsson
Roland Bengtsson

Reputation: 5148

How can I share an OnEnter event for a TcxGrid?

I want to standardize the behaviour on an Devexpress TcxGrid. So I have a unit ClientData with a event:

procedure TClientData.grdOnEnter(Sender: TObject);
begin
  mnuCxGridStandardMenu.Grid := TcxGrid(Sender);
end;

If I try to use that event from a TcxGrid.OnEnter event in another unit it refuse to work. If I paste in ClientData.grdOnEnter then a dialog says it is not an valid identifier.

Is it possible to share an event for several units in Delphi 2007 ?

EDIT: The ClientData is a datamodule that is created at startup and freed at applications exit. The reference is in a global var ClientData. So I think it should work to reference it from another unit.

Upvotes: 0

Views: 877

Answers (2)

Francesca
Francesca

Reputation: 21640

Yes it should work if you assign the event handler through code.
If your event handler does not use anything from the ClientData instance (recommended), you don't even need to create an instance.
A nil variable of type TClientData is enough.

In the sample app below, the ClientData module is not auto-created by the dpr and remains nil. That does not prevent the event handler to work correctly.

the dpr

program Project2;

uses
  Forms,
  Unit10 in 'Unit10.pas' {Form10},
  Unit11 in 'Unit11.pas' {ClientData: TDataModule};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm10, Form10);
  Application.Run;
end.

the Form dfm

object Form10: TForm10
  Left = 0
  Top = 0
  Caption = 'Form10'
  ClientHeight = 282
  ClientWidth = 418
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 168
    Top = 168
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
end

the Form pas

unit Unit10;

interface

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

type
  TForm10 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form10: TForm10;

implementation

{$R *.dfm}

procedure TForm10.Button1Click(Sender: TObject);
begin
  if ClientData = nil then
    ShowMessage('ClientData is nil')
  else
    ShowMessage('ClientData is NOT nil');
end;

procedure TForm10.FormCreate(Sender: TObject);
begin
  OnClick := ClientData.WhateverEvent;
end;

end.

the DataModule dfm

object ClientData: TClientData
  OldCreateOrder = False
  Height = 150
  Width = 215
end

the DataModule pas

unit Unit11;

interface

uses
  SysUtils, Classes, Windows;

type
  TClientData = class(TDataModule)
    procedure WhateverEvent(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ClientData: TClientData;

implementation

{$R *.dfm}

procedure TClientData.WhateverEvent(Sender: TObject);
begin
  MessageBox(0, PChar('Sender is ' + Sender.ClassName), 'Test', MB_ICONINFORMATION or MB_OK);
end;

end.

Upvotes: 1

shunty
shunty

Reputation: 3758

You can do it, so long as your form unit has the ClientData unit in its uses clause and a properly instantiated TClientData object exists and is accessible. (Don't get confused between the class definition and the object of that class type). Then, for example, you could add something like this to the OnCreate handler:

// Optional - ClientData may be a 'global' object so won't need creating.
// FClientData could be a form member ora more globally accessible variable.
//FClientData := TClientData.Create(Self); 
// or
//FClientData := TClientData.Create(Application);
cxGrid1.OnEnter := FClientData.grdOnEnter;

If the [F]ClientData object is destroyed before your form then you'll get an access violation when something tries to enter the OnEnter method.

Upvotes: 1

Related Questions