Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.23;
Скачать: CL | DM;

Вниз

Передача TNotifyEvent в качестве константы   Найти похожие ветки 

 
Dogless   (2004-05-05 10:02) [0]

Приветствую!
Имеется структура
Type ButtonRec = record
ButtonCaption: ShortString;
ButtonWidth: Integer;
ButtonProcedure: TNotifyEvent;
End;

Мне надо через неё передать константы. Делаю вот так:
Const ButtonArray: ButtonRec =
 (ButtonCaption: "ButtonCaption"; ButtonWidth: 80); ButtonProcedure: SendOrder);

Не хочет. "[Error] MainUnit.pas(2298): Constant or type identifier expected".
Чего-то ламерное упустил. А чего не понимаю. Поможите! :)


 
Dogless   (2004-05-05 10:03) [1]

Забыл добавить, что SendOrder - это процедура класса.


 
Islander   (2004-05-05 10:07) [2]

SendOrder должен иметь тип TNotifyEvent


 
Jack128 ©   (2004-05-05 10:15) [3]


> процедура класса
это называется метод. Он по определению не может быть константой, так состоит из двух частей 1) Указатель на код (это действительно - константа) 2) Указатель на экземпляр класса(объект) (псевдопеременная Self в теле метода), а вот это не может быть константой.

В принципе если тебе не нужен Self, то можно объявить ButtonProcedure как TMethod, тогда можно написать const
 ButtonProcedure: TMethod = (Code : nil; Data : @TForm1.FormCreate);

Вопрос по теме к более знающим людям: почему вот такой код выдаем ошибку

const
 m: TMethod = (Code : nil; Data : @TForm1.FormCreate);
 n: TNotifyEvent = TNotifyEvent(t); // Константное выражение ожидается

а вот такой нет:
const
 i: Integer = 2;
 d: Double = Int64(i);


 
Jack128 ©   (2004-05-05 10:19) [4]

Черт, опечаток и ошибок сделал

> const
>  m: TMethod = (Code : nil; Data : @TForm1.FormCreate);
>  n: TNotifyEvent = TNotifyEvent(m); // Константное выражение
> ожидается
>
> а вот такой нет:
> const
>  i: Integer = 2;
>  d: Int64 = Int64(i); // Тут тоже ошибка, но почему!!!!


 
Dogless   (2004-05-05 10:24) [5]

2Islander   (05.05.04 10:07) [2]
Он и есть такой.

2Jack128 ©   (05.05.04 10:15) [3]
Сделал, как ты говоришь. Т.е.
Type ButtonRec = record
ButtonCaption: ShortString;
ButtonWidth: Integer;
ButtonProcedure: TMethod;
End;


Возникло 2 проблемы:
1) надо потом ButtonProcedure назначить на onClick
Сейчас сделал onClick:=TNotifyEvent(ButtonProcedure);. Не знаю насколько это правильно.

2) Пишу Const ButtonArray: ButtonRec =
(ButtonCaption: "ButtCaption"; ButtonWidth: 80); ButtonProcedure: @TMain.SendOrder);

Получаю [Error] MainUnit.pas(2297): Type expected but "@" found
Без "@" получаю всё тот же [Error] MainUnit.pas(2297): Constant or type identifier expected


 
Dogless   (2004-05-05 10:29) [6]

Вообще пишу вот так
Const ButtonArray: ButtonRec =
(ButtonCaption: "Button"; ButtonWidth: 80; ButtonProcedure: @TMain.SendOrder);
. Ошибка [Error] MainUnit.pas(2297): "(" expected but "@" found


 
Jack128 ©   (2004-05-05 10:35) [7]

Так - пошел ка  я спать.. Не мой сегодня день..

Const ButtonArray: ButtonRec =
(ButtonCaption: "Button"; ButtonWidth: 80;
 ButtonProcedure: (Code: @TForm1.FormCreate; Data: nil));


 
Dogless   (2004-05-05 10:46) [8]

ок, спасибо. Константу передал. А как теперь назначить на onClick ?
Приведение к TNotifyEvent вызывает исключение при нажатии на кнопку.


 
Jack128 ©   (2004-05-05 10:56) [9]


> Приведение к TNotifyEvent вызывает исключение при нажатии
> на кнопку.
Какое?  Все работает..

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

var
 Form1: TForm1;

implementation

{$R *.DFM}

Type ButtonRec = record
ButtonCaption: ShortString;
ButtonWidth: Integer;
ButtonProcedure: TMethod;
End;

Const ButtonArray: ButtonRec =
(ButtonCaption: "Button"; ButtonWidth: 80;
 ButtonProcedure: (Code: @TForm1.FormClick; Data: nil));

procedure TForm1.FormCreate(Sender: TObject);
begin
 Button1.OnClick := TNotifyEvent(ButtonArray.ButtonProcedure);
end;

procedure TForm1.FormClick(Sender: TObject);
begin
 ShowMessage("yra");
end;


 
Dogless   (2004-05-05 11:07) [10]

Ага, ошибка была в другом.
А на что могло повлиять, что у нас Data = nil?
Дело в том, что у меня ButtonArry передаётся в процедуру, где создаются: форма, мемо и кнопки (как из раз из записи). Объект Memo - глобальный. Потом в SendOrder осуществляется доступ к Memo. Почему-то в процедуре SendOrder он nil. Это могло произойти из-за такой передачи указателя на обработчик onClick ?


 
Dogless   (2004-05-05 11:10) [11]

Так может быть попонятней:
Const ButtonArray: array [1..1] of ButtonRec =
((ButtonCaption: "??????? ?? ?????";
ButtonWidth: 80;
ButtonProcedure: (Code: @TMain.SendOrder; Data: nil)
));

...

Preview("Типовая форма " + S,700,550,ButtonArray,Str);


Procedure TMain.Preview(S: String; Wdth,Hght: Integer;
 ButtonArray: array of ButtonRec;
...

  For t:=Low(ButtonArray) to High(ButtonArray) Do
   With TButton.Create(Panel) Do
    Begin
     Parent:=Panel;
     Anchors:=[akRight,akBottom];
     Top:=5;
     Left:=OffSet;
     Height:=Height + 2;
     Width:=ButtonArray[t].ButtonWidth;
     Caption:=ButtonArray[t].ButtonCaption;
     Dec(OffSet,Width + 5);
     onClick:=TNotifyEvent(ButtonArray[t].ButtonProcedure);
    End; {With}


Обработчик SendOrder:

Procedure TMain.SendOrder(Sender: TObject);
Begin
 ...
Memo.Lines.SaveToFile(TempPath + "doc.txt");  <-- Вот здесь почему-то Memo = nil, хотя Memo объявлен глобальным.


 
Jack128 ©   (2004-05-05 11:15) [12]


> А на что могло повлиять, что у нас Data = nil?
Data - это неявная переменная Self в методе - я уже писал..Если ты хочешь, чтобы self имел актуальное значение - тогда тебе придется отказаться от использования констант..


 
Dogless   (2004-05-05 11:17) [13]

Всё ясно. Теперь т.к. составляющая Self убрана, то
Procedure TForm1.Button1Click(Sender: TObject);
Begin
Memo.Lines.SaveToFile(...)
End;

Хотя класс и TForm1 в описании процедуры, то так теперь к Memo не обратишься. Тепепь надо писать фиксированно:
Procedure TForm1.Button1Click(Sender: TObject);
Begin
Form1.Memo.Lines.SaveToFile(...)
End;


 
Dogless   (2004-05-05 11:17) [14]

Всё ясно. Теперь т.к. составляющая Self убрана, то
Procedure TForm1.Button1Click(Sender: TObject);
Begin
Memo.Lines.SaveToFile(...)
End;

Хотя класс и TForm1 в описании процедуры, то так теперь к Memo не обратишься. Тепепь надо писать фиксированно:
Procedure TForm1.Button1Click(Sender: TObject);
Begin
Form1.Memo.Lines.SaveToFile(...)
End;


 
Dogless   (2004-05-05 11:19) [15]

Jack128, спасибо тебе большое. Без тебя бы не справился :)
В следующий раз помогу чем смогу я.



Страницы: 1 вся ветка

Текущий архив: 2004.05.23;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.025 c
14-1083339126
alexeyy
2004-04-30 19:32
2004.05.23
Delphi 4. Руководство разработчика баз данных


1-1083813352
Vilux
2004-05-06 07:15
2004.05.23
Кол-во дней между двумя датами


1-1084300704
magician
2004-05-11 22:38
2004.05.23
Проблемы с ini


4-1080815064
WELLiON
2004-04-01 14:24
2004.05.23
Исчезающий значок из трея


1-1083839939
ary
2004-05-06 14:38
2004.05.23
Векторный шрифт