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

Вниз

Вызов функции из функции   Найти похожие ветки 

 
Сергей   (2011-01-14 22:08) [0]

Вызов функции из функции

Код такой:

type
 TGetMy = procedure() of object;

function MyFunc1(OnGetMy : TGetMy = nil): Boolean;

 procedure EvOnChange(Self, Sender: TObject);
 begin
   if Assigned(OnGetMy) then OnGetMy(); // Âòîðîé âûçîâ.
 end;

var
 Form : TForm;
 EvChange : TMethod;
begin
 if Assigned(OnGetMy) then OnGetMy(); // Ïåðâûé âûçîâ.
 Form := TForm.Create(Application);
 with Form do begin
   with TEdit.Create(Form) do begin
     Parent := Form;
     EvChange.Code := @EvOnChange;
     OnChange := TNotifyEvent(EvChange);
   end;
   // ...
 end;
end;


Проблема в том, что первый вызов OnGetMy проходит, а второй из функции EvOnChange вызывает ошибку Дельфи. Вопрос, как сделать вызов правильно, чтобы ошибки не возникало?


 
Сергей М. ©   (2011-01-14 22:33) [1]


> procedure EvOnChange(Self, Sender: TObject);


А это к чему такие выкрутасы с попыткой выдать регул.процедуру за метод класса ?


 
Сергей   (2011-01-14 23:39) [2]


> Сергей М. ©   (14.01.11 22:33) [1]
>
> > procedure EvOnChange(Self, Sender: TObject);
>
> А это к чему такие выкрутасы с попыткой выдать регул.процедуру
> за метод класса ?


Знаете другой способ сделать то же самое?


 
sniknik ©   (2011-01-15 00:15) [3]

> сделать то же самое?
сильно сомневаюсь в необходимости этого (задачи как таковой кроме "сделать изврат" нет), но например ...
type
 TMyClass = class
   procedure Change(Sender: TObject);
 end;

procedure TMyClass.Change(Sender: TObject);
begin
 ShowMessage("Event Change");
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Form: TForm;
begin
 Form:= TForm.Create(Application);
 with TEdit.Create(Form) do begin
   Parent  := Form;
   OnChange:= TMyClass(nil).Change;
 end;
 Form.ShowModal;
end;


 
sniknik ©   (2011-01-15 00:19) [4]

или (чтобы не смущать народ странными привидениями типов) так -
type
 TMyEdit = class(TEdit)
   procedure Change(Sender: TObject);
 end;

procedure TMyEdit.Change(Sender: TObject);
begin
 ShowMessage("Event Change");
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Form: TForm;
begin
 Form:= TForm.Create(Application);
 with TMyEdit.Create(Form) do begin
   Parent  := Form;
   OnChange:= Change;
 end;
 Form.ShowModal;
end;


 
Сергей   (2011-01-15 00:33) [5]


> <Цитата>
>
> sniknik ©   (15.01.11 00:15) [3]
>
> > сделать то же самое?
> сильно сомневаюсь в необходимости этого (задачи как таковой
> кроме "сделать изврат" нет), но например ...
> type
>  TMyClass = class
>  
>  procedure TForm1.Button1Click(Sender: TObject);


Если бы у бабушки была TForm1, то она была бы дедушкой.

Впрочем это всё оффтоп.

Может ли кто-нибудь ответить на вопрос из первого постинга?


 
sniknik ©   (2011-01-15 00:42) [6]

> была TForm1
ну так убери, к коду тут оно никакого отношения не имеет. считай, что не кнопка не нажимается, а делается вызов регулярной процедуры.
код читать то умеешь?

> ответить на вопрос из первого постинга?
ну, как бы отвечено уже, ошибок не возникает.


 
sniknik ©   (2011-01-15 00:50) [7]

> код читать то умеешь?
чтобы не напрягать твой ум....  TForm1 нет.
program Izvrat;

{$APPTYPE CONSOLE}

uses
 SysUtils, Dialogs, Forms, StdCtrls;

type
 TMyClass = class
   procedure Change(Sender: TObject);
 end;

procedure TMyClass.Change(Sender: TObject);
begin
 ShowMessage("Event Change");
end;

var
 Form: TForm;
begin
 Form:= TForm.Create(Application);
 with TEdit.Create(Form) do begin
   Parent  := Form;
   OnChange:= TMyClass(nil).Change;
 end;
 Form.ShowModal;
end.


 
Сергей   (2011-01-15 01:05) [8]


> sniknik ©   (15.01.11 00:50) [7]
>
> > код читать то умеешь?
> чтобы не напрягать твой ум....  TForm1 нет.


Похоже между нами стоит непреодолимый смысловой преобразователь. На мой вопрос из первого постинга как вызвать функцию, я получаю любые ответы, кроме ответа на вопрос как вызвать функцию.


> sniknik ©   (15.01.11 00:50) [7]
>  TMyClass = class
>    procedure Change(Sender: TObject);
>  end;


Меня НЕ интересует TMyClass.

Меня НЕ интересует вопрос как наплодить не нужные мне классы. Также как и вопрос о том, сколько будет один плюс один, два плюс два и тому подобные.


> procedure TForm1.Button1Click(Sender: TObject);


Меня НЕ интересует никакая TForm1. А равно и все другие формы.

Меня НЕ интересует миллион других вопросов.

На данный момент интересует только один вопрос, как правильно осуществить вызов из примера в первом постинге.


 
Германн ©   (2011-01-15 01:30) [9]


> чтобы не смущать народ странными привидениями

Да. Не надо смущать народ привидениями. К тому же они и не так страшны, как их малюют. :)


> Сергей   (14.01.11 22:08)  

Тёзка, читай эту основополагающую статью до полного просветления!
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=342
И тогда никаких извратов не потребуется.


 
sniknik ©   (2011-01-15 02:04) [10]

> как наплодить не нужные мне классы.
описание типа это не класс... в смысле, не физический объект занимающий место. наплодить описаниями нельзя, зато, описанием можно представить одни и те же данные в разной интерпретации, что позволяет избежать бессмысленного перекладывания этих самых данных с места на место, только ради того, чтобы чему то что то присвоить (к тому же проигнорировав "лишнее").

> Меня НЕ интересует никакая TForm1. А равно и все другие формы.
как же так, а твой пример в [0]? без "других форм" не потребовалось бы "присобачивать" регулярную процедуру методу класса.
т.е. это твое утверждение лишает последнего смысла сам вопрос.

> как правильно осуществить вызов из примера в первом постинге.
легко, честное слово легко, но хотелось бы знать цель, а не исправлять бредовый способ под "неведому зверушку"...


 
Amoeba_   (2011-01-15 02:09) [11]

Автору вопроса:
http://www.gunsmoker.ru/2008/10/x-y-z.html

P.S. Тонкий намек на толстые обстоятельства.


 
sniknik ©   (2011-01-15 02:13) [12]

> Тёзка, читай эту основополагающую статью до полного просветления!
просветление вряд ли наступит, ведь там нет ответа "как сделать вызов правильно" в его коде... а все остальное, в том числе и относительно правильный код, его не интересует.


 
Германн ©   (2011-01-15 02:22) [13]


> sniknik ©   (15.01.11 02:13) [12]
>
> > Тёзка, читай эту основополагающую статью до полного просветления!
>
> просветление вряд ли наступит, ведь там нет ответа "как
> сделать вызов правильно" в его коде... а все остальное,
> в том числе и относительно правильный код, его не интересует.
>

Ну "Надежда" всегда остаётся последней. Так может быть автор всё-таки просветлеет?


 
Сергей   (2011-01-15 16:52) [14]

Похоже непреодолимый смысловой преобразователь продолжает работать, работать, работать ...


> Amoeba_   (15.01.11 02:09) [11]
>
> Автору вопроса:
> http://www.gunsmoker.ru/2008/10/x-y-z.html


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


> Германн ©   (15.01.11 01:30) [9]
>
> > Сергей   (14.01.11 22:08)  
>
> Тёзка, читай эту основополагающую статью до полного просветления!
>
> http://www.delphikingdom.com/asp/viewitem.asp?catalogid=342


Опять TForm1, TForm1, TForm1.
В постинге [8], тёзка, я сообщил, что меня не интересует TForm1, а также никакие лишние классы. Сколько можно вываливать эти детсадовские примеры как создать TButton или TMyClass?

В первом постинге описана конкретная ситуация, и задан вопрос, знает ли кто-нибудь способ вызова функции в данной конкретной ситуации ( а не в миллионе других ситуаций ). Похоже, что пока никто не знает.

Это вам не TButton на TForm1 создавать.


 
sniknik ©   (2011-01-15 17:07) [15]

> как осуществить нужный вызов у вас нету. :)
зато есть сомнения в нужности самого "нужного вызова".

> эти детсадовские примеры как создать TButton или TMyClass?
эти детсадовские примеры - основа ООП. либо следуй либо не используй.

> в данной конкретной ситуации
в данной конкретной ситуации способ простой, не использовать локальную (стековую) переменную при вызове ее в кода в другом месте. а сохранить ее где нибудь в доступном из обоих мест месте, например.
(говорил же просто)

> а не в миллионе других ситуаций
т.е. зацикливаться на кривом методе решения, вместо того чтобы достичь цели миллионом других методов? цель подменена средством.

> Это вам не TButton на TForm1 создавать.
а ты так нифига и не понял.


 
имя   (2011-01-15 20:00) [16]

Удалено модератором


 
sniknik ©   (2011-01-15 20:50) [17]

> (если же параметров будет больше, или спецификация вызова будет другой, параметры могут передаваться через стек
все правильно, но не смертельно... в дельфи в процедурах делается восстановление состояния указателей, и потому параметром больше параметром меньше, "ерунда, дело житейское" (© Карлсон который живет на крыше)... а иначе бы были невозможны процедуры с открытым списком.
т.е. если к нему не обращаться то неважно, что он "мусорный" (кусок Data метода у него не инициализирован, но и обращения к self нет).

но вот то, что адрес/параметр остались в стеке, т.е. суть локальные, а вызов внешний по отношению к ним,  вот это уже гарантированное AV.

насчет спецификаций ... + похоже параллельный ответ "делающему монстра", ну пофиг.
возьми его код, и замени  
 EvChange.Code := @EvOnChange;
 OnChange := TNotifyEvent(EvChange);
на
 OnChange := TNotifyEvent(OnGetMy); (сохраним переменную собственно в объекте)
и все будет работать (если конечно OnGetMy передана извне, и это адрес "внешней" процедуры, а не такой же локальной).
работает, хотя, при вызове метода 2 параметра Self, Sender, а процедуры объекта только 1 Self. (т.е. лишний не мешает)

> Тогда у тебя может что-то получиться.
не получится, если "именно так как хочется". почему вроде объяснил.

> Нанять программиста.
вот это да. гарантирование решение проблем... т.к. программисты решают задачу, а не правят до посинения неверный путь ее решения, только потому что "так хочется".


 
DiamondShark ©   (2011-01-15 23:50) [18]

Поциэнт хочет вызвать вложенную процедуру как процедуру верхнего уровня?
При этом стучит ложкой и огрызается на медперс-анал?
Вколите ему кто-нибудь два кубика эвтаназепама.


 
Германн ©   (2011-01-16 04:07) [19]


> В постинге [8], тёзка, я сообщил, что меня не интересует
> TForm1, а также никакие лишние классы. Сколько можно вываливать
> эти детсадовские примеры как создать TButton или TMyClass?
>
>

В постинге [8] кроме очевидного бреда "недоучки" ничего нет!

Но в посте [0] присутствует Form : TForm;
И на этой форме создаются компоненты типа TEdit. Создаются в рантайме, очевидно. Но без всякого понимания что и как нужно делать! А статьи читать - не барское дело!
P.S. Троешники идут лесом!


 
Юрий Зотов ©   (2011-01-16 08:46) [20]

А ответ на вопрос "как правильно осуществить вызов из примера в первом постинге" все же имеется.

Отвечаю: правильно - никак. Правильно - переработать структуру кода так, чтобы не приходилось делать неправильное.


 
Юрий Зотов ©   (2011-01-16 09:06) [21]

Но если уж очень сильно хочется, то:
1. Вложенную процедуру сделать внешней.
2. Назначить EvChange.Data (ссылка на объект, чье событие надо назначить).

Только это все равно неправильно. Правильно - так не делать.


 
Юрий Зотов ©   (2011-01-16 09:55) [22]


procedure Proc(Sender: TObject);
begin
 ShowMessage(Sender.ClassName)
end;

var
 M: TMethod;

procedure TForm1.FormCreate(Sender: TObject);
var
 Edit: TEdit;
begin
 Edit := TEdit.Create(Self);
 Edit.Parent := Self;
 M.Code := @Proc;
 M.Data := Edit;
 Edit.OnChange := TNotifyEvent(M)
end;


 
DiamondShark ©   (2011-01-16 19:04) [23]


> Юрий Зотов ©   (16.01.11 09:55) [22]

Вы сами свой пример не запускали.


 
sniknik ©   (2011-01-16 19:30) [24]

> Вы сами свой пример не запускали.
почитай выше, о разнице между 1 и 2мя  переменными ([17]). + подумай, какая разница как переменную обозвать. не, конечно неплохо называть однотипно, но для компа это просто адрес в памяти, а название self или sender он не разбирает (если его не "обучить" конечно, типа RTTI).

кстати сам попробуй, а после того как сработает убери значение из M.Data := Edit;. поставь там nil, и вот тогда... бяда бяда. ;)


 
DiamondShark ©   (2011-01-16 20:04) [25]


> подумай, какая разница как переменную обозвать.

Подумай, какая разница, дать корректный код, или глюкопотенциальную фигню.

Если прототип "procedure Proc" написать корректно, то код будет просто работать корректно всегда.
А так надо помнить, что, благодаря модели "register", вызов с неправильной сигнатурой не портит стек.
Ну, по крайней мере, при двух аргументах не портит.
Ну, в текущей версии компилятора, точняк не портит.
Ну, в том объекте, кому мы делегат навешиваем, точно нет фигни, вроде

property OnChange : TNotifyEvent; read GetOnChange; write SetOnChange;

function TMyCrazyObject.GetOnChange
begin
 Result := FInnerObject.OnChange;
end;

procedure TMyCrazyObject.SetOnChange
begin
 FInnerObject.OnChange := value;
end;


 
Юрий Зотов ©   (2011-01-16 20:08) [26]


> DiamondShark ©   (16.01.11 19:04) [23]

О, великий Гуру, вот здесь:
http://webfile.ru/5056135
Вы найдете исходник, экзешник и скриншот.

Конечно, можно было обойтись только одним исходником, но он у Вас уже и так есть (см. выше) - и раз Вы не смогли его откомпилировать и запустить, значит, у Вас с этим какие-то проблемы. Поэтому пришлось сделать это за Вас, мне не трудно.

LOL


 
DiamondShark ©   (2011-01-16 20:15) [27]


> Юрий Зотов ©   (16.01.11 20:08) [26]

Да в пень мне тот исходник, экзешник и скриншот.

Вы лучше объясните, из каких побуждений вы использовали некорректную сигнатуру процедуры?
Хотели отучить ТС от копипасты (еретической мысли, что забыли про селф, я разумеется, не допускаю)?


 
Ega23 ©   (2011-01-16 20:31) [28]


> из каких побуждений вы использовали некорректную сигнатуру
> процедуры?

Сфигали она некорректная?
З.Ы. У тебя точно перманентный ПМС.


 
DiamondShark ©   (2011-01-16 20:51) [29]


> Ega23 ©   (16.01.11 20:31) [28]
> Сфигали она некорректная?

С того, что type TNotifyEvent = procedure (Sender: TObject) of object
У этой сигнатуры два параметра: неявный Self и явный Sender.

З.Ы. У тебя перманентный ФГМ.


 
Ega23 ©   (2011-01-17 00:18) [30]


> У этой сигнатуры два параметра: неявный Self и явный Sender.

M.Code := @Proc;
M.Data := Edit;


З.Ы. ЛМД.


 
DiamondShark ©   (2011-01-17 00:30) [31]


> Ega23 ©   (17.01.11 00:18) [30]

Ты пьян, что-ли?
Попробуй сформулировать по-русски, что за мысль ты собирался донести своей многозначительной копипастой?


 
Servy ©   (2011-01-17 00:40) [32]

По-моему, DiamondShark вполне резонно отмечает, что если код из [22] дополнить например таким образом:


procedure Proc(Sender: TObject);
begin
ShowMessage(Sender.ClassName)
end;

var
M: TMethod;

procedure TForm1.FormCreate(Sender: TObject);
var
 Edit: TEdit;
 Memo: TMemo;
 Button: TButton;
begin
 Edit := TEdit.Create(Self);
 Edit.Parent := Self;
 M.Code := @Proc;
 M.Data := Edit;
 Edit.OnChange := TNotifyEvent(M);

 Memo := TMemo.Create(Self);
 Memo.Parent := Self;
 Memo.Top := 30;
 Memo.OnChange := TNotifyEvent(M);
end;


То он будет показывать "TEdit" для обоих компонентов, тогда как, по всей видимости Sender"ом у второго компонента должно быть TMemo. Засим, код из [22] видимо очень неправильный :).

Единственный вопрос в том, специально ли Юрий Зотов поставил вместо Self - Sender и опустил второй параметр, или это была трагическая случайность, сделавшая код из [22] еще неправильнее, чем планировалось им изначально.


 
Ega23 ©   (2011-01-17 01:10) [33]


> То он будет показывать "TEdit" для обоих компонентов, тогда
> как, по всей видимости Sender"ом у второго компонента должно
> быть TMemo.

Он будет показывать ровно то, что должен показывать. Задачи, чтобы это был полноценный TNotifyEvent не было.
Не далее как в четверг как раз такую штуку реализовывал. Но с процедурой мне не понравилось, сделал тупо

TDummyClass = class (TObject)  
public
 class procedure Proc(Sender: TObject);
end;


 
DiamondShark ©   (2011-01-17 01:26) [34]


> Он будет показывать ровно то, что должен показывать.

Может ты расскажешь, что он должен показывать? Ну, т.е. как ты задачу понял?


 
sniknik ©   (2011-01-17 01:37) [35]

> То он будет показывать "TEdit" для обоих компонентов, тогда как, по всей видимости Sender"ом
> у второго компонента должно быть TMemo. Засим, код из [22] видимо очень неправильный :).
вообще то он не правильный вовсе не поэтому. а потому, что у метода обычно 2 параметра, и описывать регулярку под метод стоило бы не так
procedure Proc(Sender: TObject);
а так
procedure Proc(Self, Sender: TObject);
и все. ничего более.
что "сдвигает" параметр, а не меняет их местами из-за имени. т.е. ну, чтобы вам было привычнее напишите так
procedure Proc(Self: TObject);
а, второй там просто не используется, и возможности его вызвать с ним тоже нет (без извращений с приведением типа). т.е. ошибок из-за этого тоже не будет.

т.что то, что ты инкриминируешь "у второго компонента должно быть TMemo" неверно, не должен, а есть и будет именно TMemo, но только "за кадром" во втором не присутствующем, а в Self передается из Data куда мы/ты его сам поместил. т.е. ССЗБ в этом случае.

ты что думаешь, ты тут воздухом дышишь? © Морфей из матрицы.
вы как начинающий Нео, привязываетесь к именам... а они не существенны. компьютеру на них начхать, они только для нас.


 
DiamondShark ©   (2011-01-17 01:51) [36]


> sniknik ©   (17.01.11 01:37) [35]

Вообще-то, если решать задачу замены метода на регулярную процедуру, то логично было бы терять/игнорировать именно Self, а не явные параметры.

Но, поскольку Self первый, то "красиво" потерять его не получится. Остаётся только описать и проигнорировать.
Ну и для чистоты концепции неплохо бы передавать в Self именно nil, а не бессмысленную ссылку на объект, Self-ом не являющийся.


 
Германн ©   (2011-01-17 01:58) [37]


> Вообще-то, если решать задачу

А нужно ли решать эту задачу в "Начинающим"?
Да ещё и разводить теоретический спор на тему этой задачи?
Сам сабж - бредовый. X-Y-Z


 
Servy ©   (2011-01-17 02:02) [38]


> что "сдвигает" параметр, а не меняет их местами из-за имени.
>  т.е. ну, чтобы вам было привычнее напишите так
> procedure Proc(Self: TObject);


Я бы и написал Self, и второй параметр там оставил. Но Юрий Зотов написал там именно Sender. Таким образом, новичок бы логично предположил, что туда передается именно Sender. В коде [22] разницы нет, так как Sender = Self, поэтому я привел другой пример в [32], где Sender и Self различаются. Соответственно, возникает вопрос, намеренно ли в [22] написан Sender (и если так, то зачем, ветка то для начинающих), или это ошибка, которую следует поправить.

Злобный буратино то не я, а автор кода. Я лишь продемонстрировал, что в Sender"е оказывается совсем не Sender, что должно было навести на некоторые мысли доблестного защитника кода из [22], который уверен, что в никаких проблем с сим кодом не наблюдается.

Ваши объяснения того, что происходит мне не были нужны, однако надеюсь пригодятся кому-нибудь из начинающих.


 
sniknik ©   (2011-01-17 02:06) [39]

> если решать задачу замены метода на регулярную процедуру
я вообще то изначально был против ее решать... проще/лучше описать типом/классом (что ни добавляет ни байта к коду), чем составлять "вручную" в коде, и утяжелять его.
посмотри примеры [3], [4].
> Ну и для чистоты концепции неплохо бы передавать в Self именно nil, а не бессмысленную ссылку на объект, Self-ом не являющийся.
почему это она бессмысленная? раз объект существует (обьект Edit создали? создали) то есть (должна быть раз предусмотрена) и ссылка на него, но если хочешь добавь в любой пример ([3], [4])  слово class перед procedure и "цель" достигнута.


 
sniknik ©   (2011-01-17 02:09) [40]

> Self-ом не являющийся.
или имеется в виду второй случай с Memo? ну так бысмысленным сделал его тот кто вручную составлял и составил неправильно, дал Mem-У Edit. ССЗБ.


 
Servy ©   (2011-01-17 02:33) [41]


> Ega23 ©   (17.01.11 01:10) [33]
> Он будет показывать ровно то, что должен показывать. Задачи,
>  чтобы это был полноценный TNotifyEvent не было.


Конечно, задача ведь была "сделайте мне как можно более неполноценный TNotifyEvent".


> sniknik ©   (17.01.11 02:09) [40]
> или имеется в виду второй случай с Memo? ну так бысмысленным
> сделал его тот кто вручную составлял и составил неправильно,
>  дал Mem-У Edit. ССЗБ.


Я правильно вас обоих понял: то, что явный параметр TNotifyEvent  - Sender - потерян и не доступен из процедуры, а неявный параметр - Self -  переименован в Sender не является ошибкой в коде [22], а, напротив, является отличным примером написания кода для начинающих? Тогда будет замечательно, если вы потрудитесь обосновать это нелепое с моей точки зрения утверждение.


 
Германн ©   (2011-01-17 02:36) [42]


> Германн ©   (17.01.11 01:58) [37]
>
>
> > Вообще-то, если решать задачу
>
> А нужно ли решать эту задачу в "Начинающим"?
> Да ещё и разводить теоретический спор на тему этой задачи?
>
> Сам сабж - бредовый. X-Y-Z
>


 
Servy ©   (2011-01-17 02:44) [43]


> Сам сабж - бредовый.


Да. Однако на обсуждаемую спорную ошибку в [22] это никак не влияет, негоже сделать вид, что там все окей, позволив возможным неопытным читателям этой ветки обмануться, не так ли?


 
Германн ©   (2011-01-17 03:16) [44]


> Да. Однако на обсуждаемую спорную ошибку в [22] это никак
> не влияет, негоже сделать вид, что там все окей, позволив
> возможным неопытным читателям этой ветки обмануться, не
> так ли?

Вы скачали пример по ссылке в Юрий Зотов ©   (16.01.11 20:08) [26]?
Вы его проверили? Он работает?

Однако, не стоит обсуждать тут пост [22], если у вас нет намерения "поспорить с ЮЗ".


 
Servy ©   (2011-01-17 03:38) [45]


> Вы скачали пример по ссылке в Юрий Зотов ©   (16.01.11 20:
> 08) [26]?
> Вы его проверили? Он работает?


Да, он работает. Как это подтверждает отсутствие в нем обсуждаемой ошибки, явно сформулированной мной в [41]?


> Однако, не стоит обсуждать тут пост [22], если у вас нет
> намерения "поспорить с ЮЗ".


Я не пониманию, исходя из чего единственным допустимым поводом обсуждения поста является намерение "поспорить с ЮЗ". Я против него в целом ничего не имею, все люди ошибаются. Другое дело, что тут почему-то появились люди, упорно утверждающие, что так и надо.


 
Leonid Troyanovsky ©   (2011-01-17 04:06) [46]


> Servy ©   (17.01.11 02:44) [43]

> Да. Однако на обсуждаемую спорную ошибку в [22] это никак
> не влияет, негоже сделать вид, что там все окей, позволив
> возможным неопытным читателям этой ветки обмануться, не
> так ли?

По ходу обсуждения я заметил не одну неточность в формулировках,
но не спешил их уточнять, бо поведение ТС к тому не располагало.
ЮЗ, IMHO, имел в этом случае право и  на умышленную неточность.

Ну, а так, конечно, да - все люди ошибаются, и указывать на ошибки
святое форумное дело.

--
Regards, LVT.


 
Сергей   (2011-01-17 04:29) [47]


> sniknik ©   (15.01.11 20:50) [17]
> замени  
>  EvChange.Code := @EvOnChange;
>  OnChange := TNotifyEvent(EvChange);
> на
>  OnChange := TNotifyEvent(OnGetMy); (сохраним переменную
> собственно в объекте)
> и все будет работать


Опять не то. Задача вызвать функции OnGetMy из функции MyFunc1, а не просто прописать её в OnChange.


> Юрий Зотов ©   (16.01.11 08:46) [20]
>
> А ответ на вопрос "как правильно осуществить вызов из примера
> в первом постинге" все же имеется.
>
> Отвечаю: правильно - никак.


Ничего. Все эти личностные оценки правильно или не правильно давайте оставим в стороне.


 
Германн ©   (2011-01-17 05:15) [48]


> Задача вызвать функции OnGetMy из функции MyFunc1, а не
> просто прописать её в OnChange.

А ТС продолжает настаивать на своём бреде. :(


 
Servy ©   (2011-01-17 05:45) [49]


> Опять не то. Задача вызвать функции OnGetMy из функции MyFunc1,
>  а не просто прописать её в OnChange.


Это невозможно. Указатели на локальные процедуры и функции не положено сохранять. Если вы попробуете скомпилировать следующий код:

procedure Test;

 procedure Local;
 begin
   ShowMessage("I am local");
 end;

var
 P: TProcedure;
begin
 P := Local;
end;


То увидите вполне закономерное сообщение об ошибке:

E2094 Local procedure/function "Local" assigned to procedure variable

Однако, операцию взятия адреса у локальных процедур разработчики компилятора почему-то не запретили (вероятно напрасно). Однако, при таком вызове (через сохраненный указатель) по вполне объективным причинам обращаться к локальным переменным (включая параметры, такие как OnGetMy) родительской функции вы не сможете.

Решение вам предлагалось еще в [15]:


> в данной конкретной ситуации способ простой, не использовать
> локальную (стековую) переменную при вызове ее в кода в другом
> месте. а сохранить ее где нибудь в доступном из обоих мест
> месте, например.
> (говорил же просто)


Если оно вас по каким-то причинам не устраивает, то, судя по всему, у задачи в вашей постановке решения нет (так как по постановке задачи нельзя отменить локальность функции, а жестокая реальность не дает обращаться к стековым переменным родительской функции, если дочерняя вызывается черт знает откуда).


 
sniknik ©   (2011-01-17 08:14) [50]

> Опять не то. Задача вызвать функции OnGetMy из функции MyFunc1, а не просто прописать её в OnChange.
тебе же объяснили причину, она локальная(/адрес), сделай ее глобальной и сможешь указать, и ее (а переменную сохранять рядом как в [4] например).

или опять не то? т.е. уперся в один, невозможный вариант, и "решаешь" его. а нужно решать задачу. а варианты менять, а лучше изначально использовать правильные.

... есть еще возможность ..., переходи на яву, хотя, нет, точно за нее не скажу, на яваскрипт, вот там точно, такое в порядке вещей. неважно где описана процедура ее можно назначить любому событию (там это даже используется сделать "типа объекта со своим списком переменных").


 
KSergey ©   (2011-01-17 08:53) [51]

> Сергей   (17.01.11 04:29) [47]
> Все эти личностные оценки правильно или не правильно давайте оставим в стороне.

Где здесь личностные оценки?!


 
Сергей   (2011-01-18 18:40) [52]


> Servy ©   (17.01.11 05:45) [49]
>
> > Опять не то. Задача вызвать функции OnGetMy из функции
> MyFunc1,
> >  а не просто прописать её в OnChange.
>
> Это невозможно. Указатели на локальные процедуры и функции
> не положено сохранять.


"Не положено" и "невозможно" - это разные вещи.


 
Плохиш ©   (2011-01-18 18:43) [53]


> ... есть еще возможность ..., переходи на яву, хотя, нет,
>  точно за нее не скажу, на яваскрипт, вот там точно, такое
> в порядке вещей.

Разве в ява или яваскрипте есть вложенные функции?


 
sniknik ©   (2011-01-18 19:14) [54]

> Разве в ява или яваскрипте есть вложенные функции?
в яве не уверен, не писал на ней, а вот в яваскрипте... вот про что говорил
http://javascript.ru/basic/closure
думаю примеров там для ответа на этот вопрос достаточно.


 
DiamondShark ©   (2011-01-18 20:19) [55]


> Сергей   (18.01.11 18:40) [52]
> "Не положено" и "невозможно" - это разные вещи.

Не положено сохранять (вне контекста определения) указатель на локальную функцию, потому что невозможно (вне контекста определения) её вызвать.

Так понятнее?

Отсюда следует, что для того, чтобы её-таки вызвать, тебе понадобится сделать захват и восстановление контекста.
Для захвата тебе понадобится какая-нибудь структура, которая будет жить не меньше указателя на функцию (а контроль над ним ты теряешь прямо вот не одходя от кассы, хе-хе).
А для восстановления тебе придётся проэмулировать стековый фрейм.

Вот простого надёжного решения ты не хочешь, а хитроподвыперднутое глюкалово ты хочешь.

Тебе больше делать нехер? Времени свободного много? Ну сходи с тёлками потуси.


 
Leonid Troyanovsky ©   (2011-01-18 22:22) [56]


> DiamondShark ©   (18.01.11 20:19) [55]

> Вот простого надёжного решения ты не хочешь, а хитроподвыперднутое
> глюкалово ты хочешь.

Так понятней.
Хорошо описано.

--
Regards, LVT.



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

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

Наверх




Память: 0.66 MB
Время: 0.015 c
15-1294991323
Антон Т.
2011-01-14 10:48
2011.04.24
Как сделать рассылку?


15-1294985178
Медвежонок ХМЛ
2011-01-14 09:06
2011.04.24
УЭК


2-1295333857
voha
2011-01-18 09:57
2011.04.24
Handle ActiveX объекта


2-1240595519
Артем
2009-04-24 21:51
2011.04.24
открыт ли порт?


2-1295522746
cyber-pilot
2011-01-20 14:25
2011.04.24
Вопрос про работу эксепшенов