Главная страница
    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.48 MB
Время: 0.033 c
7-1081312481
random
2004-04-07 08:34
2004.05.23
Как програмно узнать открыт CD-ROM или закрыт


6-1080366633
Energizer
2004-03-27 08:50
2004.05.23
Винсоки. Формирование пакетов


14-1083674325
****
2004-05-04 16:38
2004.05.23
Вот думаю ,думаю и никак не придумаю : что означает слово "ИМХО"?


14-1083328106
uny
2004-04-30 16:28
2004.05.23
тема такая странная


1-1084351959
Litr
2004-05-12 12:52
2004.05.23
Форма





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский