Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];

Вниз

Передача 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.049 c
1-1083488720
Barn
2004-05-02 13:05
2004.05.23
Вопрос по работе с книгами Excel с помощью Дельфи


3-1083046147
Имя2
2004-04-27 10:09
2004.05.23
Как узнать тип файла, хранящегося в таблице.


14-1083656290
GanibalLector
2004-05-04 11:38
2004.05.23
ДОС версии ниже 6.22.


3-1083148163
gu_est
2004-04-28 14:29
2004.05.23
номер колонки в DBGridEh


1-1084217733
killer
2004-05-10 23:35
2004.05.23
Вставка втроки в TStringList





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский