powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Родитель, наследники, события. Вопрос новичка.
22 сообщений из 22, страница 1 из 1
Родитель, наследники, события. Вопрос новичка.
    #39937032
Kira1998
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет! Есть один вопрос от новичка:
Есть родительская форма, от которой унаследовано много дочерних форм. На дочерних формах много cxDateEdit. Надо сделать проверку содержимого всех cxDateEdit на всех формах по событию OnExit. Я сделала так:
В родительской форме:

Код: pascal
1.
2.
3.
4.
procedure TfrmMain.cxDataEditExit(Sender: TObject);
begin
  // здесь проверка содержимого cxDateEdit
end;



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure TfrmMain.FormShow(Sender: TObject);
var
  i: Integer;
  DE : TcxDateEdit;
begin
    for i := ComponentCount - 1 downto 0 do
    begin
        if Components[i] is TcxDateEdit then
        begin
            DE := Pointer(Components[i]);
            DE.OnExit := cxDataEditExit;
        end;
    end;
end;



И все как бы заработало, кроме одного "но"... На дочерних формах у некоторых cxDateEdit уже был свой обработчик события OnExit, который перестал работать.
Как сделать так, что бы в дочерних формах в cxDateEdit отрабатывало и событие OnExit и проверка содержимого?
Извините, если подобный вопрос уже обсуждался, я ответа не нашла.
Заранее благодарна за помощь.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937052
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Назначать cxDataEditExit не всем компонентам, а только тем, у которых обработчик OnExit не назначен
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937055
Kira1998
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DimaBr,
увы, проверку надо включить для всех TcxDateEdit :(
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937061
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kira1998
DimaBr,
увы, проверку надо включить для всех TcxDateEdit :(

У Delphi нет подписки на событие.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937062
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проверка, проверкой, а затирать событие новым не нужно
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937063
Cobalt747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kira1998
DimaBr,
увы, проверку надо включить для всех TcxDateEdit :(

Тогда надо где-то сохранять прежние обработчики, ассоциируя их с контролом
и в новом обработчике проверять - сохранён ли для этого контрола прежний обработчик.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937066
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kira1998,

Код: pascal
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.
type
  TForm1 = class(TForm)
...
    DE: TcxDateEdit;
    procedure DEExit(Sender: TObject); // Прежний обработчик
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure cxDataEditExit(Sender: TObject); // Новый обработчик
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject); 
var
  fP: ^TNotifyEvent;
begin
  fP := AllocMem(SizeOf(TNotifyEvent));
  fP^ := DE.OnExit; // Запоминаем старый обработчик
  DE.Tag := Integer(fP);
  DE.OnExit := cxDataEditExit;
end;


procedure TForm1.FormDestroy(Sender: TObject);
var
  fP: ^TNotifyEvent;
begin
  fP := Pointer(DE.Tag);
  if Assigned(fP) then
    Dispose(fP)
end;

procedure TForm1.cxDataEditExit(Sender: TObject); // Новый обработчик
var
  fP: ^TNotifyEvent;

begin
  fP := Pointer(TComponent(Sender).Tag);
  if Assigned(fP) then
    fP^(Sender);

  ShowMessage('Новый код');

end;

procedure TForm1.DEExit(Sender: TObject);
begin
  ShowMessage('Старый код');
end;
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937068
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Простой вариант: Сохранять уже назначенный обработчик в поле Tag, а в общем OnExit проверять, есть ли там значение и если есть, то выполнять.

Чуть более сложный вариант: трюк с подменой класса.
type
TcxDateEdit = class(cxUnit.TcxDateEdit)
// здесь можно перекрыть какой-либо метод, и существующие контролы типа TcxDateEdit станут объектами этого расширенного класса.
// можно override-ить DoExit, если он есть, или еще как-то прицепиться к событию помимо OnExit
end;
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937071
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Василий 2,

поле Tag - оно маленькое. Не поместится обработчик. :)
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937072
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем так сложно? Да и за
ъъъъъ

DE.Tag := Integer(fP);

надо бить батогами.
Достаточно же
Tag := NativeUInt(@OnExit);
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937073
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Василий 2,

ню-ню.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937075
Kira1998
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Большое спасибо за помощь! :)
Буду разбираться, после отпишусь о результатах!
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937078
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Волшебный INHERITED спасёт
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937082
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А блин. Все время забываю про эту хрень, что метод объекта это не только лишь указатель.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937084
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DimaBr,

дык, там заменяется свойство уже после создания наследника.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937086
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Василий 2
это не только лишь

Угу.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937103
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
поле Tag - оно маленькое. Не поместится обработчик. :)

Поместится, tag - NativeInt.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937112
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wadman
ъъъъъ
поле Tag - оно маленькое. Не поместится обработчик. :)

Поместится, tag - NativeInt.

Поместится, но не полностью. :)
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937157
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
DimaBr,
дык, там заменяется свойство уже после создания наследника.

Та и я о том же. Не нужно его заменять !!!
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937161
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DimaBr,

так скушно.
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937177
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если Делфи 2009 и выше
Код: pascal
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.
type
  TfrmMain = class(TForm)
  strict private
    FEvents: TDictionary<TObject, TNotifyEvent>
    ...........
  end;

procedure TfrmMain.FormShow(Sender: TObject);
var
  i: Integer;
  DE : TcxDateEdit;
begin
    for i := ComponentCount - 1 downto 0 do
    begin
        if Components[i] is TcxDateEdit then
        begin
            DE := TcxDateEdit(Components[i]);
            if Assigned(DE.OnExit) then
              FEvents.Add(DE, DE.OnExit);
            DE.OnExit := cxDataEditExit;
        end;
    end;
end;

procedure TfrmMain.cxDataEditExit(Sender: TObject);
var
  LEvent: TNotifyEvent;
begin
  // здесь проверка содержимого cxDateEdit
  if FEvents.TryGetValue(Sender, LEvent) then
    LEvent(Sender);
end;


Не забыть создать/уничтожить FEvents в конструкторе/деструкторе.

И переинициализацию события лучше делать не в FormShow, а в FormCreate
...
Рейтинг: 0 / 0
Родитель, наследники, события. Вопрос новичка.
    #39937199
Kira1998
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,
Большое спасибо за помощь! Ваш код тоже замечательно работает! :)

Еще раз огромное спасибо всем, кто помог мне :)
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Родитель, наследники, события. Вопрос новичка.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]