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

Вниз

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

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

Наверх




Память: 0.64 MB
Время: 0.004 c
15-1294182094
NailMan
2011-01-05 02:01
2011.04.24
Летающие тряпочки начинают уверенно летать у меня


3-1256924418
Незнайка
2009-10-30 20:40
2011.04.24
Работа с MSSQL


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


6-1215495439
AHTOLLlKA
2008-07-08 09:37
2011.04.24
Socks5 клиент, как состряпать запрос ?


15-1293701642
12
2010-12-30 12:34
2011.04.24
Произношение комплексного числа. По каким буквам "ударять"?





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