Как уведомить контрол о событии?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Как уведомить контрол о событии?

Сообщение EatMyShorts » 15.10.2009 14:03:04

Доброго времени суток.
Есть 2 формы, на 1ой Grid, а на 2ой edit. Как сообщить edit'у что произошло событие OnCellClick на первой форме?
Приходит на ум сделать так:
Код: Выделить всё
unit unit1;//содержит Form1

uses unit2;//содержит Form2

....................

procedure Form1.GridCellClick(cell: TCell);// знаю что не так, прсто для примера  :)
begin
  Form2.edit.Text := Grid.Cell.Text;
end;



Или можно как-то по красивее?
EatMyShorts
новенький
 
Сообщения: 30
Зарегистрирован: 06.10.2009 19:48:19

Re: Как уведомить контрол о событии?

Сообщение VirtUX » 15.10.2009 14:16:15

А что конкретно нужно передать в Edit.Text из Grid?
Аватара пользователя
VirtUX
энтузиаст
 
Сообщения: 880
Зарегистрирован: 05.02.2008 10:52:19
Откуда: Крым, Алушта

Re: Как уведомить контрол о событии?

Сообщение EatMyShorts » 15.10.2009 14:19:32

А что конкретно нужно передать в Edit.Text из Grid?

Да
EatMyShorts
новенький
 
Сообщения: 30
Зарегистрирован: 06.10.2009 19:48:19

Re: Как уведомить контрол о событии?

Сообщение Vadim » 15.10.2009 15:01:27

EatMyShorts писал(а):Или можно как-то по красивее?

"Покрасивей" - это как? :)
Что-нибудь типа:
Я целлку щёлкнул у Grid'ы,
Мой Drag'n'Drop туды-сюды,
Со вздохом ей присовкупил,
Edit'ы текст. Потом свалил...

;)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как уведомить контрол о событии?

Сообщение EatMyShorts » 15.10.2009 15:16:43

"Покрасивей" - это как? :)
Что-нибудь типа:

Я целлку щёлкнул у Grid'ы,
Мой Drag'n'Drop туды-сюды,
Со вздохом ей присовкупил,
Edit'ы текст. Потом свалил...

Ну покрасивей это в unit2 где находится edit отреагировать на событие которое произошло на первой форме.
EatMyShorts
новенький
 
Сообщения: 30
Зарегистрирован: 06.10.2009 19:48:19

Re: Как уведомить контрол о событии?

Сообщение v-t-l » 15.10.2009 16:12:40

Это как? Создать процедуру обработки в модуле unit2, потом присвоить ее событию компонента в модуле unit1? :shock:
Врядли это будет покрасивее :D
v-t-l
энтузиаст
 
Сообщения: 735
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Re: Как уведомить контрол о событии?

Сообщение yuray » 16.10.2009 12:40:50

Вопрос очень интересный и актуальный. Однозначно писать вот такой код нельзя - нарушается инкапсуляция.
Код: Выделить всё
procedure Form1.GridCellClick(cell: TCell);// знаю что не так, прсто для примера  :)
begin
  Form2.edit.Text := Grid.Cell.Text;
end;

Способов, как минимум, есть 2.
Первый, который напрашивается, это послать контролу соответствующее сообщение. Пример можно посмотреть в папке %LAZARUS%\examples\messages\.
Наведу пример касательно вопроса.
На форму Form1кладем StringGrid1 и кнопку BitBtn1. По кнопке будем вызывать Form2, на которой расположен Edit1.
При клике по гриде в Form2.Edit1.text будем отображать количество кликов.

Собственно код

Form1

Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  Grids, Buttons, StdCtrls, LCLIntf;

type

  { TForm1 }

  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    StringGrid1: TStringGrid;
    procedure BitBtn1Click(Sender: TObject);
    procedure StringGrid1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Unit2;

{ TForm1 }

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

procedure TForm1.StringGrid1Click(Sender: TObject);
begin
  PostMessage(Form2.Handle, WM_GRIDCLICK, 1, 0);
end;

initialization
  {$I unit1.lrs}

end.


Form2

unit Unit2;

Код: Выделить всё
{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, windows;

const
  WM_GRIDCLICK = WM_USER + 244;

type

  { TForm2 }

  TForm2 = class(TForm)
    Edit1: TEdit;
  private
    { private declarations }
    procedure WMGridClick(var Message:TMessage); message WM_GRIDCLICK;

  public
    { public declarations }
  end;

var
  Form2: TForm2;

implementation

{ TForm2 }

procedure TForm2.WMGridClick(var Message: TMessage);
begin
  Edit1.Text := inttostr(StrToIntDef(Edit1.Text, 0)+Message.WParam);
end;

initialization
  {$I unit2.lrs}

end.


Эстетам объектно-ориентированного программирования этот способ кажется некрасивым. Поэтому, можно обойтись и без сообщений. Тогда нужно использовать свойство процедурного типа. Если кому интересно, могу навести пример и этого способа.
yuray
новенький
 
Сообщения: 95
Зарегистрирован: 22.05.2008 14:19:19
Откуда: Ровно, Украина

Re: Как уведомить контрол о событии?

Сообщение Vadim » 16.10.2009 12:52:57

yuray
yuray писал(а):...нарушается инкапсуляция.

А Ваш код нарушает кроссплатформенность. ;)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Как уведомить контрол о событии?

Сообщение yuray » 16.10.2009 14:48:18

Vadim писал(а):А Ваш код нарушает кроссплатформенность. ;)

Опс... Извините, исправляюсь

Form1

Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  Grids, Buttons, StdCtrls, LCLIntf;

type

  { TForm1 }

  TForm1 = class(TForm)
    BitBtn1: TBitBtn;
    StringGrid1: TStringGrid;
    procedure BitBtn1Click(Sender: TObject);
    procedure StringGrid1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Unit2;

{ TForm1 }

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

procedure TForm1.StringGrid1Click(Sender: TObject);
begin
  PostMessage(Form2.Handle, WM_GRIDCLICK, 1, 0);
end;

initialization
  {$I unit1.lrs}

end.


Form2

Код: Выделить всё
unit Unit2;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, LMessages;

const
  WM_GRIDCLICK = LM_USER + 244;

type

  { TForm2 }

  TForm2 = class(TForm)
    Edit1: TEdit;
  private
    { private declarations }
    procedure WMGridClick(var Message:TLMessage); message WM_GRIDCLICK;
  public
    { public declarations }
  end;

var
  Form2: TForm2;

implementation

{ TForm2 }

procedure TForm2.WMGridClick(var Message: TLMessage);
begin
  Edit1.Text := IntToStr(StrToIntDef(Edit1.Text, 0)+Message.WParam);
end;

initialization
  {$I unit2.lrs}

end.
yuray
новенький
 
Сообщения: 95
Зарегистрирован: 22.05.2008 14:19:19
Откуда: Ровно, Украина

Re: Как уведомить контрол о событии?

Сообщение скалогрыз » 16.10.2009 15:31:57

EatMyShorts писал(а):Доброго времени суток.
Есть 2 формы, на 1ой Grid, а на 2ой edit. Как сообщить edit'у что произошло событие OnCellClick на первой форме?
Приходит на ум сделать так:
Или можно как-то по красивее?


достаточно красиво? =)

Код: Выделить всё
unit unit1;

uses
  ... unit2;

procedure TForm1.OnCellClick(Sender: TObject;ACol, ARow: integer);
begin
  form2.CellClicked( Sender as TStringGrid, ACol, Arow );
end;

----
unit unit1;

type
  TForm2 = class(TForm)
    edit1 : TEdit;
  pulbic
    procedure CellClicked(AGrid: TStringGrid; ACol, ARow: Integer);
  end;

procedure TForm2.CellClicked(AGrid: TStringGrid; ACol, ARow: Integer);
begin
  edit1.Text :=  AGrid.Cells[ACol, ARow];
end;


можно сделать наоборот, что у form1 дополнительное событие, который вызывается при нажатии на ячейку.
Но так или иначе, хотя бы один из модулей должен знать о другом. Взаимознание совсем не обязательно.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 36

Рейтинг@Mail.ru