Форум: "Основная";
Текущий архив: 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 =
. Ошибка [Error] MainUnit.pas(2297): "(" expected but "@" found
(ButtonCaption: "Button"; ButtonWidth: 80; ButtonProcedure: @TMain.SendOrder);
← →
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