Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Родитель, наследники, события. Вопрос новичка. / 22 сообщений из 22, страница 1 из 1
13.03.2020, 12:28
    #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
13.03.2020, 13:00
    #39937052
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Родитель, наследники, события. Вопрос новичка.
Назначать cxDataEditExit не всем компонентам, а только тем, у которых обработчик OnExit не назначен
...
Рейтинг: 0 / 0
13.03.2020, 13:06
    #39937055
Kira1998
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Родитель, наследники, события. Вопрос новичка.
DimaBr,
увы, проверку надо включить для всех TcxDateEdit :(
...
Рейтинг: 0 / 0
13.03.2020, 13:30
    #39937061
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Родитель, наследники, события. Вопрос новичка.
Kira1998
DimaBr,
увы, проверку надо включить для всех TcxDateEdit :(

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

Тогда надо где-то сохранять прежние обработчики, ассоциируя их с контролом
и в новом обработчике проверять - сохранён ли для этого контрола прежний обработчик.
...
Рейтинг: 0 / 0
13.03.2020, 13:34
    #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
13.03.2020, 13:36
    #39937068
Василий 2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Родитель, наследники, события. Вопрос новичка.
Простой вариант: Сохранять уже назначенный обработчик в поле Tag, а в общем OnExit проверять, есть ли там значение и если есть, то выполнять.

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

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

DE.Tag := Integer(fP);

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

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

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

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

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

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

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

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

так скушно.
...
Рейтинг: 0 / 0
13.03.2020, 15:55
    #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
13.03.2020, 16:37
    #39937199
Kira1998
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Родитель, наследники, события. Вопрос новичка.
_Vasilisk_,
Большое спасибо за помощь! Ваш код тоже замечательно работает! :)

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


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