Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/202: Рейтинг темы: голосов - 202, средняя оценка - 4.85
1 / 1 / 1
Регистрация: 10.12.2009
Сообщений: 22

Как создать свое событие для своего класса?

15.12.2009, 15:40. Показов 43381. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день всем!
Подскажите как создать событие для своего класса? Экземпляр класса должен реагировать на
определенные события, обработчик которых вызывается при определенных условиях. Познания не очень обширны, по сему не знаю как это реализуется.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.12.2009, 15:40
Ответы с готовыми решениями:

Как отловить событие для своего класса?
класс: TSomeClass = class(TObject) procedure OnKeyDown(var Message); message WM_KEYDOWN; end; var C: TSomeClass; begin

Событие для своего класса
Я зоздал класс TPeople и класс TTrafficlight. Сответственно создал код: type TPeople=class go:Boolean; speed, x, y,...

Событие onCick для своего класса
Можно ли для своего класса (без родительского) создать событие onClick или любое другое событие с мышкой?

12
 Аватар для Mawrat
13113 / 5894 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
15.12.2009, 17:52
Лучший ответ Сообщение было отмечено как решение

Решение

Стандартный подход такой:
Определяем новый класс: TMyClass. И добавляем в него механизм работы с событием MyEvent.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
unit uMyClass;
 
interface
 
uses
  Classes, Dialogs;
 
type
 
  TMyClass = class
  private
    FName : String;
    //...
    //Поле ссылающееся на обработчик события MyEvent.
    //Тип TNotifyEvent описан в модуле Clases так: TNotifyEvent = procedure(Sender: TObject) of object;
    //Фраза  "of object" означает, что в качестве обработчика можно назначить только метод какого-либо
    //класса, а не произвольную процедуру.
    FOnMyEvent : TNotifyEvent;
    //...
  protected
    //...
    //Эта процедура проверяет задан ли обработчик события. И, если задан, запускает его.
    procedure DoMyEvent; dynamic;
  public
    //...
    //Это свойство позволяет назначить обработчик для обработки события MyEvent.
    property OnMyEvent : TNotifyEvent read FOnMyEvent write FOnMyEvent;
    //...
    //Процедура, которая принимает решение - произошло событие MyEvent или нет.
    //Таких процедур может быть несколько - везде где может возникнуть событие MyEvent.
    //Если событие MyEvent произошло, то вызвается процедура DoMyEvent().
    procedure GenericMyEvent;
    //...
    //Имя экземпляра класса.
    property Name : String read FName write FName;
    //...
  published
    //...
  end;
 
implementation
 
{ TMyClass }
 
procedure TMyClass.DoMyEvent;
begin
  //Если обработчик назначен, то запускаем его.
  if Assigned(FOnMyEvent) then FOnMyEvent(Self);
end;
 
procedure TMyClass.GenericMyEvent;
var
  MyEventIsOccurred : Boolean;
  //...
begin
  //...
  MyEventIsOccurred := True;
  //Если верно некоторое условие, которое подтверждает, что событие MyEvent
  //произошло, то делаем попытку запустить связанный обработчик.
  if MyEventIsOccurred then begin
    DoMyEvent;
  end;
  //...
end;
 
end.
Модуль с формой (TForm), в котором тестируется механизм событий класса TMyClass.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls
 
  ,uMyClass;
 
type
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    
    //Обработчик события MyEvent для объектов, принадлежащих типу TMyClass.
    procedure MyObjectMyEvent(Sender : TObject);
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
{ TForm1 }
 
//Обработчик события MyEvent для объектов, принадлежащих типу TMyClass.
procedure TForm1.MyObjectMyEvent(Sender: TObject);
var
  MyObj : TMyClass;
begin
  if not (Sender is TMyClass) then Exit;
 
  MyObj := Sender as TMyClass;
  ShowMessage('Событие MyEvent произошло! Имя объекта, который породил событие: ' + MyObj.Name);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  MyObj1, MyObj2, MyObj3 : TMyClass;
begin
  //Создаём экземпляры класса TMyClass.
  MyObj1 := TMyClass.Create;
  MyObj1.Name := 'MyObj1';
  MyObj2 := TMyClass.Create;
  MyObj2.Name := 'MyObj2';
  MyObj3 := TMyClass.Create;
  MyObj3.Name := 'MyObj3';
 
  //Для MyObj1 и MyObj2 назначаем обработчики события MyEvent.
  MyObj1.OnMyEvent := MyObjectMyEvent;
  MyObj2.OnMyEvent := MyObjectMyEvent;
 
  //Работаем с экземплярами класса. При этом в каждом из экзепляров
  //возникает событие MyEvent.
 
  MyObj1.GenericMyEvent;
  MyObj2.GenericMyEvent;
 
  //При выполнении метода MyObj3.GenericMyEvent, событие MyEvent наступит, но оно
  //не будет обработано процедурой MyObjectMyEvent, т. к., ранее, мы не назначили её в качестве
  //обработичика события MyEvent для экземпляра MyObj3.
  MyObj3.GenericMyEvent;
 
  MyObj1.Free;
  MyObj2.Free;
  MyObj3.Free;
end;
 
end.
Возможно я замудрёно объяснил тут. Можно сделать проще. И тип обработчика события не обязательно должен быть TNotifyEvent. Можно свой тип создать. TNotifyEvent - обработчик этого типа обязательно должен являться методом какого-либо класса. Можно объявить свой тип обработчика, без этого ограничения.
В приложенном архиве рабочий код.
Вложения
Тип файла: rar MyEvent.rar (171.3 Кб, 771 просмотров)
5
1 / 1 / 1
Регистрация: 10.12.2009
Сообщений: 22
16.12.2009, 10:07  [ТС]
Спасибо большое. Буду разбираться.
0
1 / 1 / 2
Регистрация: 03.06.2015
Сообщений: 103
03.06.2015, 23:55
а можно еще параметры ему передать? дело в том, что создаю динамически панели, ну и по нажатию, нужно в определенную переменную писать конкретную строку.. как это можно реализовать?
0
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,608
04.06.2015, 00:51
Цитата Сообщение от ptytb1 Посмотреть сообщение
а можно еще параметры ему передать?
Кому ему? Классу?
Цитата Сообщение от ptytb1 Посмотреть сообщение
дело в том, что создаю динамически панели, ну и по нажатию, нужно в определенную переменную писать конкретную строку.
Ну и пиши. Но в своей пользовательской программе. Классы/компоненты то тут при чем? Они ничего не знают и главное ничего не должны знать о программе, в которой их используют.
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
04.06.2015, 01:23
Цитата Сообщение от ptytb1 Посмотреть сообщение
а можно еще параметры ему передать? дело в том, что создаю динамически панели, ну и по нажатию, нужно в определенную переменную писать конкретную строку.. как это можно реализовать?
заменить TNotifyEvent на другой тип (можно на свой) - с аргументами. могу навалить кучу примеров из своих прожэктов. но утром, щас - спать.
0
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,608
04.06.2015, 01:28
Цитата Сообщение от Verevkin Посмотреть сообщение
заменить TNotifyEvent на другой тип (можно на свой) - с аргументами. могу навалить кучу примеров из своих прожэктов
А может не надо портить новичков? И не надо плодить монстров?

Добавлено через 2 минуты
Свой класс/компонент, если он ДСП, не очень то и нужен. Всю функциональность можно реализовать в самой программе.
0
1 / 1 / 2
Регистрация: 03.06.2015
Сообщений: 103
04.06.2015, 09:43
делал вот так, создавал процедуру с константой procedure opendialog(const Name: t componentName); и при создании очередной панели на событие онклик вешал эту прцседуру NewPanel.OnClick:=opendialog(NewPanel.na me); но делфи сильно ругался и выдавал ошибки
Вот одна из них
[dcc32 Error] Unit1.pas(180): E2010 Incompatible types: 'TNotifyEvent' and 'procedure, untyped pointer or untyped parameter'

Добавлено через 1 час 13 минут
проще говоря у каждой панели есть имя содержащее в себе айди, мне нужно по нажатию на конкретную панель получать именно ее айди (айди можно записать в тег, но я пока с именем делаю)
0
 Аватар для Mawrat
13113 / 5894 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
04.06.2015, 10:10
Цитата Сообщение от ptytb1 Посмотреть сообщение
делал вот так, создавал процедуру с константой procedure opendialog(const Name: t componentName); и при создании очередной панели на событие онклик вешал эту прцседуру NewPanel.OnClick:=opendialog(NewPanel.na me); но делфи сильно ругался и выдавал ошибки
TPanel.OnClick принадлежит типу TNotifyEvent. Этот тип определён так:
Delphi
1
type TNotifyEvent = procedure (Sender: TObject) of object;
Т. е., это процедура-метод, а не самостоятельная процедура. И этот метод должен иметь один параметр указанного типа. Компилятор в сообщении об ошибке пишет об этом несовпадении типов:
Цитата Сообщение от ptytb1 Посмотреть сообщение
[dcc32 Error] Unit1.pas(180): E2010 Incompatible types: 'TNotifyEvent' and 'procedure, untyped pointer or untyped parameter'
"Несовместимые типы: 'TNotifyEvent' и 'процедура, нетипизированный указатель или нетипизированный параметр'".
Цитата Сообщение от ptytb1 Посмотреть сообщение
делал вот так, создавал процедуру с константой procedure opendialog(const Name: t componentName);
В данном случае новый обработчик не нужен. Потому, что сведения об объекте, который вызвал этот обработчик (в том числе его имя), можно получить через параметр Sender, который передаётся в обработчик типа TNotifyEvent.
Пример:
Delphi
1
2
3
4
5
6
7
procedure TForm1.Panel1Click(Sender: TObject);
var
  Panel : TPanel;
begin
  Panel := Sender as TPanel;
  ShowMessage('Обработчик TForm1.Panel1Click() вызвал компонент с именем: ' + Panel.Name);
end;
Если обработчик может быть назначен компонентам разных типов, тогда так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
procedure TForm1.Panel1Click(Sender: TObject);
var
  Cmp : TComponent;
  Panel : TPanel;
begin
  //Если в проекте обработчик мог быть назначенным разным типам компонентов (а не только экземплярам TPanel).
  Cmp := Sender as TComponent;
  ShowMessage('Обработчик TForm1.Panel1Click() вызвал компонент типа ' + Cmp.ClassName
    + ' с именем: ' + Cmp.Name);
 
  //Если экземпляр принадлежит классу TPanel или его потомку, то выполняем какие-то специальные действия:
  if Sender is TPanel then
  begin
    Panel := Sender as TPanel;
    if Panel.Color <> clRed then
      Panel.Color := clRed
    else
      Panel.Color := clGreen;
    ShowMessage('Изменён цвет панели.');
  end;
end;
1
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
04.06.2015, 10:23
Цитата Сообщение от northener Посмотреть сообщение
Свой класс/компонент, если он ДСП, не очень то и нужен.
а я про класс не говорил.
я говорил про тип события.
Если я правильно понял автора, ему в обработчик события надо что-то передавать изнутри класса наружу.
Delphi
1
2
3
4
type TNotifyEvent = procedure (Sender: TObject) of object; // простой обработчик
type TMyShitEvent1 = procedure (Sender: TObject; const Param: <тип_параметра>)  of object; // не совсем простой обработчик
type TMyShitEvent2 = procedure (Sender: TObject; var Param: <тип_параметра>)  of object; // не совсем простой обработчик
type TMyFuncEvent = function (Sender: TObject<; другие параметры>): <тип> of object; // и даже так можно!
0
1 / 1 / 2
Регистрация: 03.06.2015
Сообщений: 103
04.06.2015, 11:11
Цитата Сообщение от Mawrat Посмотреть сообщение
Пример:
огромное спасибо!! работает хорошо)
0
0 / 0 / 0
Регистрация: 13.05.2014
Сообщений: 37
16.10.2018, 08:16
Судя по количеству сообщений galdora на форуме, он таки не разобрался.Жестокий пример) А можно примерчик по-проще?
0
5943 / 4519 / 1094
Регистрация: 29.08.2013
Сообщений: 28,099
Записей в блоге: 3
16.10.2018, 20:30
Цитата Сообщение от Vinder Посмотреть сообщение
А можно примерчик по-проще?
пример чего?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.10.2018, 20:30
Помогаю со студенческими работами здесь

Как создать свое событие?
В общем суть такая: есть абстрактный класс фигуры, и три производных от него. На экране ( используем конечно же вин формс) в picturebox...

Как создать своё событие, к которому можно обращаться с другого события.
Подскажите как создать событие с определёнными операциями внутри, к которому можно обратиться через другое событие, например: при нажатии...

Как создать событие event которое можно изменить для конкретного экземпляра класса?
создал свой класс MyDGV и создал в нем событие BeforeLoad и AfterLoad например Friend Event BeforeLoad(ByVal sender As Object, ByVal e...

Создать свое событие
Ребята помогите пожалуйста, мне нужно создать собственное событие. Вот к примеру можно сделать так, выбрать цвет у кнопки - допустим синий,...

Как создать объект своего класса в билдере?
Написал в билдере класс class Point { public: Point() ; void DrawPoint(float, float); protected: float x,y; }; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru