Конференция "Начинающим" » заNILить форму после Close;
 
  • ничтожная козявка (21.08.08 12:37) [0]
    В некой dll есть функция, показывающая форму. Перед созданием формы, она проверяет ее на NIL:

     if not Assigned(Form1) then Form1 := TForm1.Create(AOwner);



    также требуется, что бы после закрытия (Close) форма была уничтожена:

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
     ...
     Action := caFree;
     ...
    end;



    ВОПРОС: как сделать так, чтоб она была не только уничтожена, но и переменная Form1 приняла значение NIL. Т.к. поскольку эта переменная не NIL, при повторной попытке создать форму, ее конструктор
      if not Assigned(Form1) then Form1 := TForm1.Create(AOwner);
    не вызывается, и в последствии сыпятся AV.
  • @!!ex © (21.08.08 12:41) [1]
    TForm1 = class
    public
     FormLinkPointer:^TForm1;
    end;

    ....
    Form1:TForm;
    Form1:=TForm.Create();
    Form1.FormLinkPointer:=@Form1;

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
     FormLinkPointer^:=nil;
    end;

  • Ega23 © (21.08.08 12:41) [2]
    Ну самого себя занилить у тебя не получится.
    Форма модальная?
  • ничтожная козявка (21.08.08 12:52) [3]
    @!!ex
     Ок, спасибо! Это работает. А нельзя ли Self для этих целецей использовать?

    Ega23
     Модальной ее делать нельзя, к сожалению.
  • Leonid Troyanovsky © (21.08.08 13:01) [4]

    > ничтожная козявка   (21.08.08 12:37)  

    > В некой dll есть функция, показывающая форму.

    Это ошибка.

    --
    Regards, LVT.
  • @!!ex © (21.08.08 13:08) [5]
    > А нельзя ли Self для этих целецей использовать?

    Нет.
  • ничтожная козявка (21.08.08 13:58) [6]
    Leonid Troyanovsky

    > Это ошибка

     как полагается реализовывать это?
  • Сергей М. © (21.08.08 14:00) [7]

    > ничтожная козявка   (21.08.08 13:58) [6]


    А как она, форма, там завелась ?
    Что ей не жилось спокойно в ехе ?
  • Юрий Зотов © (21.08.08 14:04) [8]
    > @!!ex ©   (21.08.08 12:41) [1]

    Зачем такие извраты?

    procedure TForm1.FormClose(...);
    begin
      Action := caFree;
    end;

    procedure TForm1.OnDestroy(...);
    begin
     Form1 := nil;
    end;



    И вся морковь.
  • {RASkov} © (21.08.08 14:08) [9]
    А зачем эта ссылка на форму вообще? убрать ее нафик...
    И будет достаточно Action := caFree; а "единичность формы"(если именно ее преследует автор) можно будет сделать "такой же" глобальной переменной, только например Булевого типа.... и делов.
  • ничтожная козявка (21.08.08 14:10) [10]

    > Сергей М. ©   (21.08.08 14:00) [7]

     это что-то навроде плагина.. ТЗ так велит.

     
    > @!!ex ©   (21.08.08 13:08) [5]
    >
    > > А нельзя ли Self для этих целецей использовать?
    >
    > Нет.

     ога, я понял, потому что Self и Form1 это две большие разницы и заниливание одного из этих указателей ничего не даст.
  • ничтожная козявка (21.08.08 14:11) [11]

    > Юрий Зотов ©   (21.08.08 14:04) [8]

     я кстати постеснялся сначала так делать:)
  • Сергей М. © (21.08.08 14:17) [12]
    И в ТЗ прямо так и написано - пихать всю эту форменную беду не иначе как в DLL ?
  • ничтожная козявка (21.08.08 14:18) [13]

    > Сергей М. ©   (21.08.08 14:17) [12]

     дословно
  • Сергей М. © (21.08.08 14:23) [14]
    Ну что ж ... Дословно так дословно)
    Но геморрой при этом грозит не тем кто лепил ТЗ, а тебе)
  • ничтожная козявка (21.08.08 14:26) [15]

    > Сергей М. ©   (21.08.08 14:23) [14]

     довольно уж тянуть кота за резину :)) советуйте как дОлжно быть, чем грозит, кто виноват и как наказать :))
  • Ega23 © (21.08.08 14:32) [16]
    procedure TForm1.OnDestroy(...);
    begin
    Form1 := nil;
    end;



    Ага, а она у меня и вовсе не Form1, а
    var
     tmpfrm : TForm1

  • Dennis I. Komarov © (21.08.08 14:55) [17]
    > [16] Ega23 ©   (21.08.08 14:32)

    procedure TForm1.OnDestroy(...);
    begin
     TForm1(Sender) := nil;
    end;

    не спасет?
  • Leonid Troyanovsky © (21.08.08 15:02) [18]

    > ничтожная козявка   (21.08.08 13:58) [6]

    >  как полагается реализовывать это?

    http://www.podgoretsky.com/OtherParts/DM/BadTips.aspx

    --
    Regards, LVT.
  • Leonid Troyanovsky © (21.08.08 15:15) [19]

    > Dennis I. Komarov ©   (21.08.08 14:55) [17]

    >  TForm1(Sender) := nil;

    > не спасет?

    Особенно трогательно выглядит TForm1().

    И, во-ще, хватит извращений:
    1. глобальные переменные - MD,
    2. формы в длл - MD.

    --
    Regards, LVT.
  • Anatoly Podgoretsky © (21.08.08 15:26) [20]

    > Leonid Troyanovsky ©   (21.08.08 15:02) [18]

    Это не отвечает на вопрос "Как наказать", а наказать надо примерно, с отрыванием.
  • Anatoly Podgoretsky © (21.08.08 15:28) [21]

    > ничтожная козявка   (21.08.08 12:37)  

    Что бы определить существует форма или нет, глобальных переменных для этого не надо, а надо использовать Screen.Forms
  • @!!ex © (21.08.08 15:48) [22]
    > [8] Юрий Зотов ©   (21.08.08 14:04)

    Хотя бы затем, что "Класс "Пассажирский самолёт ТУ-154М" не должен ничего знать о пассажирском самолёте ТУ-154М с бортовым номером 34567 и базирующимся в Благовещенске."
    (С)Ega23
    http://pda.delphimaster.net/?n=3&id=1213366269&p=2
    пост номер 158.
  • @!!ex © (21.08.08 15:50) [23]
    > [11] ничтожная козявка   (21.08.08 14:11)

    Вот и не делай так никогда. ЮЗ скорее всего издевнулся... Вот уж он то из тех, кто знат что ТАК делать не стоит.
  • Сергей М. © (21.08.08 16:01) [24]

    > ничтожная козявка   (21.08.08 14:26) [15]


    Кури BPL.
    Выбора у тебя нет.
  • Сергей М. © (21.08.08 16:06) [25]

    > кто виноват


    Известно кто - говнюк-начальник)


    > как наказать


    О, это отдельная история)

    Уж мы оттянемся по полной программе - дай-ка только сюда "виновного")
  • Юрий Зотов © (21.08.08 16:09) [26]
    > @!!ex ©   (21.08.08 15:48) [22]

    1. Чему будет равно поле формы после ее уничтожения?
    2. И вот летят они навстречу друг другу... и ничего друг о друге не знают...

    Выводы:

    1. Не нужно усложнять то, что можно сделать просто.

    2. Даже правильные, в принципе, вещи (отсутствие глобальных перменных, неразмещение форм в DLL и пр.) не нужно превращать в абсолютные догмы. При грамотном использовании нет ничего страшного ни в глобальных переменных, ни в DLL с формами. А при неграмотном можно напортачить и без них.
  • ничтожная козявка (21.08.08 16:29) [27]

    > Сергей М. ©   (21.08.08 16:01) [24]
    > Кури BPL.

     некий экзешник может выполнять одну и туже функцию по-разному, подключая каждый раз нужные длл. BPL позволит это делать? можно использовать BPL настолько же динамически как длл?
  • Amoeba © (21.08.08 16:33) [28]
    Да.
    Можно.

    BPL всего лишь разновидность DLL.
  • ничтожная козявка (21.08.08 16:37) [29]
    тогда в чем соль?
  • Amoeba © (21.08.08 16:39) [30]

    > ничтожная козявка   (21.08.08 16:37) [29]
    >
    > тогда в чем соль?

    В отсутствии множества граблей.
  • Vlad Oshin © (21.08.08 16:45) [31]

    > тогда в чем соль?


    http://softwarer.ru/packages.html
  • ничтожная козявка (21.08.08 16:50) [32]

    > Vlad Oshin ©   (21.08.08 16:45) [31]

    спасибо, нашел уже
    тут тоже пишут: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=274
  • Vlad Oshin © (21.08.08 16:56) [33]

    > ничтожная козявка   (21.08.08 16:50) [32]

    Тоже читал. Собственно:
    Вот это впечатляет:
    С пакетами первый раз компилим и без пакетов второй раз

    В DLL экспортируется следующая функция:
    function GetObjectClass : TClass ;
    begin
     Result := TObject ;
    end ;
    В главном файле приложения результат функции сравнивается с ожидаемым:
    var Result : AnsiString ;
    begin
     if GetObjectClass = TObject
       then Result := 'MainProject.TObject = DllProject.TObject'
       else Result := 'MainProject.TObject <> DllProject.TObject' ;
     MessageBox ( 0, PChar ( Result ), PChar ( 'Линковка' ), MB_OK ) ;
    end.
  • ЛшдлуттнСфе (21.08.08 17:20) [34]
    не по существу, но я люблю глобальные переменные.
  • Leonid Troyanovsky © (21.08.08 17:55) [35]

    > ЛшдлуттнСфе   (21.08.08 17:20) [34]

    > не по существу, но я люблю глобальные переменные.

    А я - лесбиян, люблю девушек.

    --
    Regards, LVT.
  • ЛшдлуттнСфе (21.08.08 18:17) [36]

    > Leonid Troyanovsky ©   (21.08.08 17:55) [35

    а я не лесбиян, я просто люблю девушек...
  • Сергей М. © (21.08.08 18:38) [37]

    > я не лесбиян, я просто люблю девушек


    Девушкам-то "вкайф", а каковО тому, о ком идет "любовь" ?
    Им-то, знаешь ли, кАково)
  • Leonid Troyanovsky © (21.08.08 20:03) [38]

    > ЛшдлуттнСфе   (21.08.08 18:17) [36]

    Любвиобилен.

    --
    Regards, LVT.
  • Германн © (21.08.08 20:07) [39]

    > Leonid Troyanovsky ©   (21.08.08 20:03) [38]
    >
    >
    > > ЛшдлуттнСфе   (21.08.08 18:17) [36]
    >
    > Любвиобилен.
    >

    Чего ещё можно ждать от кота?
    :)
  • @!!ex © (21.08.08 20:52) [40]
    > 1. Чему будет равно поле формы после ее уничтожения?

    Согласен, лучше обнулять на уничтодение, а не на закрытие.


    > 1. Не нужно усложнять то, что можно сделать просто.

    а нет там усложнения. А вот когда выяснится, что нужно две TForm1 будет СТОЛЬКО граблей...
    Мы все таки с использованием ООП пишем, или только вид делаем?
  • Loginov Dmitry © (21.08.08 21:05) [41]

    > "единичность формы"(если именно ее преследует автор) можно
    > будет сделать "такой же" глобальной переменной, только например
    > Булевого типа.... и делов.


    Круто! Избавляемся от одной глобальной переменной, добавляем другую :)


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


    По значению то же самое, но не по адресу.


    > TForm1(Sender) := nil;
    > end;
    > не спасет?


    обнулится локальная переменная, или регистр, а дальше что?


    > 1. глобальные переменные - MD


    Application, Screen - тоже глобальные переменные. Долой их?
    Не вижу ничего плохого в глобальных переменных, если с помощью них удается решить поставленную задачу, не ухудшая надежность и читабельность кода, и не нанося ущерба его дальнейшему сопровождению.


    > 2. формы в длл - MD.


    если DLL и ЕХЕ скопилены с пакетами, то очень даже не MD.


    > Что бы определить существует форма или нет, глобальных переменных
    > для этого не надо, а надо использовать Screen.Forms


    зачем усложнять и вносить заведомые тормоза? Если форма не модальная и может существовать не более чем в одном экземпляре, то глобальная переменная, автоматически предлагаемая Delphi, имхо, самое оно! Для модальных же форм смысла в каких-либо глобальных переменных гораздо меньше, почти всегда достаточно
    with TForm.Create() do
    try
     ShowModal;
    finally
     Free;
    end;


    Для дочених форм MDI глобальные переменные и вовсе недопустимы.
  • Юрий Зотов © (21.08.08 21:09) [42]
    > @!!ex ©   (21.08.08 20:52) [40]

    > а нет там усложнения.

    Точно нет? А я-то на Ваш код глядел-глядел - и никак не мог сообразить:

    1. На фига там нужно поле типа "указатель на указатель", а не просто "указатель"? (мелочь, но все же).

    2. Каким образом это поле позволяет проверить существование формы? Никаким.

    > А вот когда выяснится, что нужно две TForm1 будет СТОЛЬКО граблей

    3. Еще раз: каким образом Ваш код от этих граблей спасает? Никаким.

    4. Не выяснится. Сабж читайте. Весь смысл в том и есть, что вторая форма не допускается.

    > Мы все таки с использованием ООП пишем, или только вид делаем?

    5. Мы вообще пишем, или только вид делаем? Вы понимаете, что Ваш код ничего не дает и неверен в самом своем принципе?
  • Anatoly Podgoretsky © (21.08.08 22:10) [43]
    > @!!ex  (21.08.2008 20:52:40)  [40]

    А лучше не обнулять, а если обнулять, то не нулем.
  • McSimm © (22.08.08 00:42) [44]

    > А лучше не обнулять, а если обнулять, то не нулем.

    так память же перевыделится кому-нибудь ?
    на вероятностях проверка получается.

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

    Уже забыл, кажется именно так реализован какой-то рабочий класс в VCL (TPrinter?, TClipboard?)
  • {RASkov} © (22.08.08 01:30) [45]
    > [41] Loginov Dmitry ©   (21.08.08 21:05)
    > Круто! Избавляемся от одной глобальной переменной, добавляем другую :)

    Вся разница в том, что ее "нилить" не нужно.... т.е. безболезненно ее можно "занилить"(сбросить в False) например на OnClose....
    Так что, ничего это и не круто, а тоже самое почти, может только чуть проще... :)
  • {RASkov} © (22.08.08 02:03) [46]
    > Уже забыл, кажется именно так реализован какой-то рабочий класс в VCL (TPrinter?, TClipboard?)

    Оба. Printer и Clipboard - это по сути не переменные, а функции... А реализация их проста:

    var FClipboard: TClipboard;
    function Clipboard: TClipboard;
    begin
     if FClipboard = nil then FClipboard := TClipboard.Create;
     Result := FClipboard;
    end;



    Принтер точно так же....
  • Юрий Зотов © (22.08.08 06:13) [47]
    Если поставить супернадежность и принципы ООП самоцелью, то класс формы надо просто сделать синглтоном - и всех дел.

    implementation

    var
     _Instance: TObject;

    class function TForm1.NewInstance: TObject;
    begin
     if _Instance = nil then
       _Instance := inherited NewInstance;
     Result := _Instance;
    end;

    procedure TForm1.FreeInstance;
    begin
     inherited;
     _Instance := nil;
    end;


    Только всегда ли нужна стрельба из пушек? Иногда бывает вполне достаточно и рогатки.
  • @!!ex © (22.08.08 07:33) [48]
    > 1. На фига там нужно поле типа "указатель на указатель",
    > а не просто "указатель"? (мелочь, но все же).

    А нафига там нужен указатель??
    Нам надо ссылку обнулить или где?


    > 2. Каким образом это поле позволяет проверить существование
    > формы? Никаким.
    >
    > > А вот когда выяснится, что нужно две TForm1 будет СТОЛЬКО
    > граблей

    Если форма существует, то Form1 не nil? Если не существует, то nil. Какие еще варианты развития событий?


    > 4. Не выяснится. Сабж читайте. Весь смысл в том и есть,
    > что вторая форма не допускается.

    Вы не могли бы процитировать сообщение, где автор на это указывает? Помойму вы малость сами тему не читали... Нет ни слова о том, что форма должна быть одна. Собственно если бы речь шла об одной форме, то к вашему коду никаких претензий не было бы.


    > 5. Мы вообще пишем, или только вид делаем? Вы понимаете,
    > что Ваш код ничего не дает и неверен в самом своем принципе?

    Позволяет обнулить ссылки указывающие на объект?
    В примере только одну, если ввести массив, то все.
    Что не нравится, можно поконкретнее?
  • Anatoly Podgoretsky © (22.08.08 07:50) [49]

    > Если форма существует, то Form1 не nil? Если не существует,
    >  то nil. Какие еще варианты развития событий?

    Form1 := nil
  • ничтожная козявка (22.08.08 10:48) [50]

    > @!!ex ©   (22.08.08 07:33) [48]
    > Вы не могли бы процитировать сообщение, где автор на это
    > указывает?

     форма действительно должна быть одна, на самом деле, хотя я об этом прямо не говорил..
    глоб. переменная Form1 у меня одна и перед созданием формы я и произвожу ее проверку на nil чтобы избежать дублей.
     синглтону тут действительно самое место, но что-то лень:)) получилось почти тоже самое, только я единственность объекта контролирую не в его конструкторе а за пределами класса вобще, во внешнем коде.. короче я тут рогаткой обошелся :)) за универсальностью буду в других, более важных вещах гоняться:))
  • Anatoly Podgoretsky © (22.08.08 10:52) [51]
    Не надо контролировать по содержимому глобальной переменной, пример я привел выше, переменная равна nil а форма есть и точно также наоборот.
    Есть же гарантирование средство Screen.Forms
  • Юрий Зотов © (22.08.08 12:40) [52]
    > @!!ex ©   (22.08.08 07:33) [48]

    > Что не нравится, можно поконкретнее?

    Можно. Давайте действительно конкретно. Поскольку иначе, как вдруг выяснилось, не получается.

    Конкретность № 1.

    Я утверждаю, что Ваш код в [1] для сабжа совершенно бесполезен, так как проконтролировать существование формы не позволяет.

    Если Вы с этим не согласны, то докажите, что я не прав. Только не надо слов, надо конкретно - Вы же этого хотели? Вот и напишите конкретный работающий пример проверки существования формы с помощью кода [1].

    После этого сможем перейти к другим конкретностям. Если, конечно, до них вообще дойдет дело.
  • Leonid Troyanovsky © (22.08.08 13:22) [53]

    > Loginov Dmitry ©   (21.08.08 21:05) [41]

    > Application, Screen - тоже глобальные переменные. Долой
    > их?

    Я уже не один раз высказывался по этому поводу, не вижу
    смысла повторяться.

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

    Мои соболезнования.

    > если DLL и ЕХЕ скопилены с пакетами, то очень даже не MD.

    Приведи три причины необходимости использования
    DLL with BPL with EXE vs EXE, тогда и обсудим кто MD.

    --
    Regards, LVT.
  • Юрий Зотов © (22.08.08 13:34) [54]
    > Приведи три причины необходимости использования
    > DLL with BPL with EXE vs EXE

    1. Плагинная архитектура.
    2. Обновление по сети.
    3. Повторное использование кода в других приложениях.
  • DVM © (22.08.08 13:37) [55]

    > Leonid Troyanovsky ©   (21.08.08 15:15) [19]


    > 1. глобальные переменные - MD,

    Это, мягко говоря, чушь. Глобальная переменная, будучи применена в нужное время и в нужном месте нисколько не ухудшает, а наоборот упрощает программу и делает ее более читабельной и лаконичной. Взгляните на модуль SysUtils, к примеру.
  • Leonid Troyanovsky © (22.08.08 13:49) [56]

    > Юрий Зотов ©   (22.08.08 13:34) [54]

    > 1. Плагинная архитектура.
    > 2. Обновление по сети.
    > 3. Повторное использование кода в других приложениях.

    Необходимость первого нуждается в отдельном обосновании.

    А, в остальном, изволь: пусть это будет, например,
    web service & client.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (22.08.08 13:55) [57]

    > DVM ©   (22.08.08 13:37) [55]

    > и лаконичной. Взгляните на модуль SysUtils, к примеру.

    Ну, и что там упрощенного, читабельного и лаконичного?

    Сделай все эти переменные, скажем, полями TApplication,
    и будет всем хорошо.

    Авторы же явно не стремились к повторному использованию кода,
    ведь глобальные переменные и ООП несовместимы.

    --
    Regards, LVT.
  • DVM © (22.08.08 14:03) [58]

    > Ну, и что там упрощенного, читабельного и лаконичного?

    Там есть множество переменных которые один единственный раз должны быть проинициализированы при старте программы и в дальнейшем менять ся во время выполнения программы не могут. Версия Windows например.


    > Сделай все эти переменные, скажем, полями TApplication,
    > и будет всем хорошо.

    Да, но тогда тот же sysutils будет намертво приклеен к TApplication, а этот самый TApplication нужен бывает не везде и не всегда.


    > Авторы же явно не стремились к повторному использованию
    > кода,
    > ведь глобальные переменные и ООП несовместимы.
    >

    А ООП и глобальные константы совместимы? Да и не ООП единым...
  • Anatoly Podgoretsky © (22.08.08 14:06) [59]
    > DVM  (22.08.2008 13:37:55)  [55]

    Русский программист и даже русский человек в состоянии оправдать что угодно.
  • Anatoly Podgoretsky © (22.08.08 14:11) [60]
    > DVM  (22.08.2008 14:03:58)  [58]

    Не совместимы, да и сам Дельфи далек от классического ООП
  • DVM © (22.08.08 14:11) [61]

    > Anatoly Podgoretsky ©   (22.08.08 14:06) [59]

    Вы тоже категорически против глобальных переменных?

    Я лично, не вижу ничего зазорного, если, скажем в каком то модуле программы будет глобальная переменная MyVar, которая в блоке initialization модуля получает значение из некоторой функции MyVar := MyVARFunc(); Почему я не использую функцию MyVARFunc напрямую вместо переменной? Вызов MyVARFunc  может занимать много времени и ресурсов, например.

    Другое дело, когда заводятся глобальные переменные для форм. Это мне не нравится.
  • DVM © (22.08.08 14:12) [62]

    > Anatoly Podgoretsky ©   (22.08.08 14:11) [60]


    > да и сам Дельфи далек от классического ООП

    Ну раз далек, то и незачем его притягивать за уши к ООП, пытаясь отказаться от глобальных переменных целиком и полностью.
  • @!!ex © (22.08.08 14:15) [63]
    > Если Вы с этим не согласны, то докажите, что я не прав.
    > Только не надо слов, надо конкретно - Вы же этого хотели?
    > Вот и напишите конкретный работающий пример проверки существования
    > формы с помощью кода [1].

    А я написал, конкретный, работающий пример еще в [1] написал. Автор даже проверил и отписался, что да, действительно работает:

    > @!!ex
    > Ок, спасибо! Это работает.
  • Leonid Troyanovsky © (22.08.08 14:24) [64]

    > DVM ©   (22.08.08 14:03) [58]

    > Там есть множество переменных которые один единственный
    > раз должны быть проинициализированы при старте программы
    > и в дальнейшем менять ся во время выполнения программы не
    > могут. Версия Windows например.

    Это уже не переменные, а константы.
    Проинициализировать что-либо при старте - это еще тот бином Ньютона.

    > Да, но тогда тот же sysutils будет намертво приклеен к TApplication,
    >  а этот самый TApplication нужен бывает не везде и не всегда.

    Это вопрос проектирования.
    А Application мог бы пригодиться хоть и в консольном приложении.

    > А ООП и глобальные константы совместимы?

    Вполне.

    --
    Regards, LVT.
  • Anatoly Podgoretsky © (22.08.08 14:35) [65]
    > DVM  (22.08.2008 14:11:01)  [61]

    Нет, есть исключения - глобальные переменные Дельфи, Application и Screen
    Из собственных только две - DataModele и MainForm - но это по принципам работы, раньше Дельфи иначе работала, можно было и без CreateForm писать.
  • Anatoly Podgoretsky © (22.08.08 14:36) [66]
    > DVM  (22.08.2008 14:12:02)  [62]

    Надо стремиться, см. выше
  • Anatoly Podgoretsky © (22.08.08 14:38) [67]
    > @!!ex  (22.08.2008 14:15:03)  [63]

    В [1] нет никакой проверки существования формы.
  • DVM © (22.08.08 14:44) [68]

    > Leonid Troyanovsky ©   (22.08.08 14:24) [64]


    > Это уже не переменные, а константы.

    Но формально, они в разделе var, а не const. Да и нельзя присвоить именно константе из раздела const значение уже во время выполнения программы.

    Выходит, с одной стороны:


    > > А ООП и глобальные константы совместимы?
    >
    > Вполне.


    Но с другой:


    > ведь глобальные переменные и ООП несовместимы.
  • Leonid Troyanovsky © (22.08.08 14:50) [69]

    > DVM ©   (22.08.08 14:44) [68]

    > Но формально, они в разделе var, а не const. Да и нельзя
    > присвоить именно константе из раздела const значение уже
    > во время выполнения программы.

    Ну, и не нужны глобальные переменные.
    Есть нужда - пользуй объекты, со свойствами только для чтения.


    > Выходит, с одной стороны:

    > Но с другой:

    Как не крути, переменные отличаются от констант.

    --
    Regards, LVT.
  • DVM © (22.08.08 14:50) [70]
    А в SysInit сколько глобальных переменнных. Их тоже в классы загонять?
  • DVM © (22.08.08 14:52) [71]

    > Ну, и не нужны глобальные переменные.
    > Есть нужда - пользуй объекты, со свойствами только для чтения.
    >


    > Это вопрос проектирования.
    > А Application мог бы пригодиться хоть и в консольном приложении.
    >  


    > Это вопрос проектирования.
    > А Application мог бы пригодиться хоть и в консольном приложении.
    >  

    Может и мог бы, только зачем усложнять настолько простые вещи? Почему то программисты на Делфи стремятся обернуть элементарное в кучу классов с огромной иерархией и сложными взаимосвязями вместо того чтобы просто написать сотню строчек делающих то же самое, но без лишних сложностей.
  • Leonid Troyanovsky © (22.08.08 14:54) [72]

    > DVM ©   (22.08.08 14:50) [70]

    > А в SysInit сколько глобальных переменнных. Их тоже в классы
    > загонять?

    Чего их гнать, раз уж они уже случились.
    Речь-то шла о собс-ручных переменных.

    --
    Regards, LVT.
  • Юрий Зотов © (22.08.08 14:54) [73]
    > Leonid Troyanovsky ©   (22.08.08 13:49) [56]

    > Необходимость первого нуждается в отдельном обосновании.

    Необходимость второго и третьего - тоже. Таким обоснованием (причем, железобетонным) может служить, например, ТЗ.

    > А, в остальном, изволь: пусть это будет, например,
    > web service & client.

    Что тоже нуждается в обосновании. Причем, не менее.

    PS
    Леонид, как известно, многие (если не все) задачи можно решить разными способами. Естественно, выбор того или иного решения ВСЕГДА должен быть обоснован. Проектируя архитектуру (структуру кода и т.п.) будущей программы, конечно, НИКОГДА не следует забывать о необходимости обоснования выбранного решения, но точно так же и НИКОГДА не следует априори отметать то или иное из прочих возможных решений.

    PPS
    Пресловутые "советы" предназначены для совсем уж начинающих и хороши лишь тем, что позволяют НАЧИНАЮЩИМ уберечься от распространенных ошибок. Но не стоит превращать их в догмы - иначе они станут столь же вредны, сколь и полезны. Программист просто должен понимать, что, как и зачем он делает, чем это хорошо и плохо, какие могут быть подводные камни и как их не допустить - и т.д.
  • Юрий Зотов © (22.08.08 15:11) [74]
    > @!!ex ©   (22.08.08 14:15) [63]

    Как уже справедливо заметил Анатолий, в примере [1] нет никакой проверки существования формы - то есть, нет никакого решения сабжа вообще.

    Добавьте к примеру [1] ЛЮБУЮ такую проверку - и я ДОКАЖУ Вам (причем, вполне конкретно, как Вы и хотели), что работать она НЕ будет. Потому что никакая проверка, основанная на коде [1] работать не может уже в самом ПРИНЦИПЕ этого кода.

    Вы хотели конкретики? ОК, я жду ее. И теперь уже от Вас просто так не остану, поверьте. Извините, но сами напросились.

    Итак - либо к примеру [1] Вы добавляете конкретный, неопровержимый и работающий код проверки существования формы, либо признаете (явным или неявным образом - неважно), что код в [1] для такой проверки не дает ровно ничего.

    После чего сможем перейти к другим "конкретностям" в коде [1]. Они там тоже имеются.
  • @!!ex © (22.08.08 16:01) [75]
    То, что уже было написано в [1] и немного измененный.
    TForm1 = class
    public
    FormLinkPointer:^TForm1;
    end;

    ....
    Form1:TForm;
    Form1:=TForm.Create();
    Form1.FormLinkPointer:=@Form1;

    procedure TForm1.FormClose(...);
    begin
     Action := caFree;
    end;

    procedure TForm1.OnDestroy(...);
    begin
     FormLinkPointer^:=nil;
    end;



    Собственно проверка:
    if Form1<>nil then
     //Значит существует
    else
     //Значит не существует

  • @!!ex © (22.08.08 16:14) [76]
    Вот тоже самое в коде:
    http://www.mediafire.com/?btmj4ydyxgn
  • @!!ex © (22.08.08 16:17) [77]
    > Добавьте к примеру [1] ЛЮБУЮ такую проверку - и я ДОКАЖУ
    > Вам (причем, вполне конкретно, как Вы и хотели), что работать
    > она НЕ будет. Потому что никакая проверка, основанная на
    > коде [1] работать не может уже в самом ПРИНЦИПЕ этого кода

    И ведь работает... У меня в компиляторе ошибка, да?

    С нетерпением жду доказательства неработоспособности работающего кода. :))
  • Anatoly Podgoretsky © (22.08.08 16:22) [78]
    > @!!ex  (22.08.2008 16:01:15)  [75]

    Я уже писал

    Form1 := nil;
    Form1 := AnyValue;
  • @!!ex © (22.08.08 16:23) [79]
    > [78] Anatoly Podgoretsky ©   (22.08.08 16:22)

    Так это применимо и к коду ЮЗ.
    Давайте тогда вообще флаги не использовать? Они же сломатся могут...
    реальный пример, когда Form1 ghbcdfbdf.n rfrjt nj ytrjhhtrnyjt pyfxtybt - vj;yj&
  • @!!ex © (22.08.08 16:24) [80]
    >>Когда Form1 присваиваЮт какое то некорректное значение - можно?
  • Anatoly Podgoretsky © (22.08.08 16:35) [81]
    > @!!ex  (22.08.2008 16:23:19)  [79]

    Я же указал единственно правильный и надежный путь.
    Зачем же мучаться с глобальными переменными, которые ничего не гарантирую, кроме получения AV
  • @!!ex © (22.08.08 16:50) [82]
    > [81] Anatoly Podgoretsky ©   (22.08.08 16:35)

    Согласен. Но уже о другом речь.
  • Anatoly Podgoretsky © (22.08.08 16:53) [83]
    > @!!ex  (22.08.2008 16:50:22)  [82]

    А о другом тебе ответит ЮЗ
  • Юрий Зотов © (22.08.08 17:09) [84]
    > @!!ex ©   (22.08.08 16:01) [75]

    Зачем мухлевать? Некрасиво. Все прекрасно видят, что код в [75] по сравнению с кодом в [1] не "немного измененный", а измененный В ПРИНЦИПЕ. И вот почему.

    1. В [75] для проверки существования формы Вы никаким образом не задействовали ни поле FormLinkPointer, ни относящийся к нему код. Если поле FormLinkPointer и относящийся к нему код, просто выбросить  то ничего не изменится. А раз это поле и ВЕСЬ сопряженный с ним код нигде не используются, тогда зачем они вообще нужны? Низачем.

    2. Для проверки существования формы Вы использовали все ту же самую тривиальную глобальную переменную, которую предлагали и другие, но против использования которой Вы столь активно возражали ("Мы все таки с использованием ООП пишем, или только вид делаем?").

    3. Таким образом, от кода [1] Вы попросту отказались (что и понятно, поскольку код в [1] действительно ничего не дает и поэтому совершенно не нужен) и заменили его другим кодом. Что и означает - "изменили в принципе".

    4. Но даже и тут Вы все равно ошиблись. Поскольку даже самую элементарную проверку - и ту умудрились сделать неверно. После закрытия формы она будет уничтожена, а Ваша проверка покажет, что она существует.

    5. Попытки хоть как-нибудь выкрутиться не прокатят. Не стоило и пробовать.

    ============================================

    Для того, чтобы существование формы можно было вообще хоть как-нибудь проверить, нужно при ее создании какой-то флажок взвести, а при уничтожении этот флажок сбросить. Таким флажком может служить, вообще говоря, любая и хранящаяся где угодно переменная, но ОДНО недопустимо - эта переменная НЕ ИМЕЕТ ПРАВА БЫТЬ ПОЛЕМ ТОЙ ЖЕ ФОРМЫ. Иначе при уничтожении формы она исчезнет, а вместе с ней исчезнет и та информация, которая нужна для следующей проверки.

    А в [1] как раз ПОЛЕ ФОРМЫ и введено (причем еще и введено кривовато, ну да ладно, не в том суть). Вот почему код в [1] для проверки существования формы не дает (И НЕ МОЖЕТ ДАТЬ!) абсолютно ничего.
  • {RASkov} © (22.08.08 17:16) [85]
    Всё, @!!ex "влип" :)
  • @!!ex © (22.08.08 17:20) [86]
    > 1. В [75] для проверки существования формы Вы никаким образом
    > не задействовали ни поле FormLinkPointer, ни относящийся
    > к нему код. Если поле FormLinkPointer и относящийся к нему
    > код, просто выбросить  то ничего не изменится. А раз это
    > поле и ВЕСЬ сопряженный с ним код нигде не используются,
    > тогда зачем они вообще нужны? Низачем.

    Юрий, вы меня нафиг поражаете. Вы в курсе, что такое указатель на указатель??
    Вот именно такой и используется.
    Меня FornLinkPOinter^ мы меняем Form2 в примере. Можете в дебагере проверить.
    Честное слово, я не ожидал что вы так плохо понимаете указатели...
  • @!!ex © (22.08.08 17:23) [87]
    > [85] {RASkov} ©   (22.08.08 17:16)

    Да не.
    Если бы я не был уверен в своей правоте, то с ЮЗ спорсить бы никогда не стал.
    Просто в данном случае ЮЗ видимо устал в конце недели и плохо понимает код.
  • @!!ex © (22.08.08 17:26) [88]
    Кстати, Юрий, я дал ссылку на код. Попробуйте там просто выбросить весь код относящийся к FormLinkPointer и удивитесь...
    Блин, я в шоке.
  • Юрий Зотов © (22.08.08 17:30) [89]
    > @!!ex ©   (22.08.08 17:20) [86]

    Я, конечно, плохо понимаю указатели. Еще хуже - указатели на указатели. О чем было сказано еще в самом первом моем посте [8].

    LOL.

    Вы все равно используете все ту же самую глобальную переменную. Так и используйте ее ЯВНО, зачем извращаться?

    И что мы тогда получим? Все тот же код в [8], но без чесания правого уха левой рукой.
  • {RASkov} © (22.08.08 17:32) [90]
    > [87] @!!ex ©   (22.08.08 17:23)

    Спор как таковой вообще тут не к месту...
    Вариантов решения вопроса в сабже можно привести более чем один...
    Я так же свой привел.
    Считаю, что в данном случае можно предложить автору свой и высказать(по желанию) -/+ данного варианта.
    По мне, я бы никогда, без особой на то необходимости, не стал-бы пользоваться "путанными" указателями....
  • @!!ex © (22.08.08 17:33) [91]
    > [89] Юрий Зотов ©   (22.08.08 17:30)

    Так я не понял, мой код работает или нет, он основан на том, что написано в [1] и если это убрать, то он робоать перестанет? Где доказательство нерабоести кода??

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

    Form1_1:=TForm1.Create();
    Form1_1.FormLinkPointer:=@Form1_1;

    Form1_2:=TForm1.Create();
    Form1_2.FormLinkPointer:=@Form1_2;

    if Form1_1<>nil then
     //Существует форма 1_1

    if Form1_2<>nil then
     //Существует форма 1_2

  • {RASkov} © (22.08.08 17:36) [92]
    Согласен с [89].
    Я тоже путаюсь в указателях, но уверен, что Юрий много более меня в них понимает...
    И еще....
    ...ни [1] ни [8] ни [75] не сравнятся с [9] :)
  • @!!ex © (22.08.08 17:39) [93]
    > [92] {RASkov} ©   (22.08.08 17:36)

    см [91], Я тчам объяснил, чем мой код отличается от простого использования глобальнйо переменной...
    Я вообще всегда думал, что контроль ссылок на объект делается так, как я написал...
    вона оказываца как.. эта оказывацца "путанные" указатели... а парни и не знают... побегу сообщать... пускай посмеются.
  • {RASkov} © (22.08.08 17:43) [94]
    > [93] @!!ex ©   (22.08.08 17:39)

    Для меня твой код не понятен, поэтому см [90]
    И про поля класса читаем в [84]
  • {RASkov} © (22.08.08 17:45) [95]
    Уже не интересно... последние посты только и состоят из [n]
    :)
  • Юрий Зотов © (22.08.08 17:45) [96]
    > @!!ex ©   (22.08.08 17:33) [91]

    Что ж, будем честными. Код действительно работает. Он действительно основан на том, что написано в 1]. Я был неправ, потому что с самого начала просмотрел код слишком поверхностно. Должен извиниться.

    Тем не менее, способ этот, по сути, ничем не отличается от обычного явного использования глобальной переменной - значит, ему присущи все те же самые недостатки. В частности, те, о которых говорил Анатолий.

    И даже то, что код будет работать с несколькими формами, практически ничего не меняет. Во-первых, для работы с несколькими формами стоит использовать более подходящие вещи (TComponentList, например). Во-вторых, и в этом случае сохраняются все те же самые недостатки.
  • {RASkov} © (22.08.08 18:30) [97]
    Скачал то что было по ссылке в [76], думал что-то интересное будет...
    @!!ex, скажи чесно, как родился такой код? :) Зачем вообще сюда нужно было приделывать эти указатели? (Начиная с [1]...)
    Даже с учетом [91] все равно не понятно для чего это все... :(
    Не, не подумай ничего плохого, но может я для себя узнаю что нового... может об указателях...
    Но по мне, код "ничем" не отличается от [8].... Т.е. отличается - лишней запутанностью. Но это имхо конечно.
    Те же глобальные переменные, и в случае с [91] - их более одной...
  • @!!ex © (22.08.08 19:03) [98]
    > [97] {RASkov} ©   (22.08.08 18:30)

    Это контроль ссылок. в коде [91] нет ни одной глобальной переменной, вобщем то.
    Form1_1 Form1_2 - вполне могут быть частью какого-то класса, например.
    Основной(и единственный) плюс в том, что класс TForm1 ничего не знает о переменных Form1_1, Form1_2. В то время как код в [8] обязует класс знать о глобальной переменной, хранящей указатель на экземпляр класса... Возникает тогда вопрос, а зачем нам вообще класс TForm1? Разве только что ради наследования...

    Вобще этот код - это пример обычной работы с классом, который подчищает за собой ссылки на него указывающие.
    На С++ с помощью шаблонов и этого метода можно делать самоуничтожающиеся объектые, которые подыхают, когда на них никто больше не указывает + все указатели на объект становятся 0, когда объект умирает.
  • {RASkov} © (22.08.08 19:15) [99]
    > [98] @!!ex ©   (22.08.08 19:03)
    > Основной(и единственный) плюс в том, что класс TForm1 ничего
    > не знает о переменных Form1_1, Form1_2.

    Ага... усек это :) Спасибо.
    Но что мешает сделать так:
    TForm1 = class
    public
     FormLink: TForm1;
    end;

    ....
    Form1: TForm;
    Form1:=TForm.Create();
    Form1.FormLink:=Form1;

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
     FormLink:=nil;
    end;


    Вроде то же самое.. только "без" указателей... т.е. без указателей на указатели..)
    Или я что-то уже не соображаю... нужно будет проверить? или это действительно тоже самое?
  • McSimm © (22.08.08 19:16) [100]

    > вполне могут быть частью какого-то класса

    указатель на свойство ?


    > класс TForm1 ничего не знает о переменных Form1_1

    Знает, вы просто сообщаете ему это в ран-тайм (или не сообщаете, если забыли)
  • {RASkov} © (22.08.08 19:17) [101]
    > FormLink:=nil;

    Ну т.е. ее нилим в Дестрой, а в OnClose - caFree...
  • McSimm © (22.08.08 19:18) [102]

    > {RASkov} ©   (22.08.08 19:15) [99]

    нет, это категорически не то же самое, т.к. вы внесли флаг внутрь самого объекта, от чего предостерегал в этой ветке Юрий.

    Ваш класс хранит флаг, в отличие от класса в [1] или [8], которые знают где флаг
  • {RASkov} © (22.08.08 19:19) [103]
    > Знает, вы просто сообщаете ему это в ран-тайм (или не сообщаете, если забыли)

    Кстати, да.... Что-то совсем уже не варит башка.... это все указатели виноваты :)
  • {RASkov} © (22.08.08 19:32) [104]
    > [102] McSimm ©   (22.08.08 19:18)

    Ну да... Вроде похоже но не то... проверил - не работает)
    Ладно... я все равно с указателями путаюсь, поэтому стараюсь без них...
  • Palladin © (22.08.08 20:35) [105]
    Опять из безсмысленной темы "определение существования объекта по значению идентификатора" раздули глупокие размышления. А все решение состоит из двух фраз.
    1. Синглтон - в делфи не осуществим
    2. Дисциплина программиста (самое наиважнейшее) - не забывать сделать так - как написано в [8] и проблемы кончатся.

    Однако как всегда имеет факт куча бессмысленных рассуждений начиная со "указатель на указатель - бред" заканчивая "глобальные переменные - вселенское зло".

    Игорь любит меня (ну и не только) поучать, все хорошо там где это хорошо выглядит. И он прав между прочим.

    "Указатель на указатель бред" - да не всегда. @!!ex пользуется этой этажеркой не для того что бы оперировать через указатель данными указываемого указателя ( :) ), а с целью оперирования переменной, идентификатором. И пофих, что это за переменная, другой ли указатель или целое число.

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

    Война бессмысленна ) и она точно - зло.
  • Loginov Dmitry © (22.08.08 23:58) [106]
    > Я уже не один раз высказывался по этому поводу, не вижу
    > смысла повторяться.


    Извиняюсь, ни разу не слышал.


    > Мои соболезнования.


    В чем именно? Вроде я в них не нуждался пока.


    > Приведи три причины необходимости использования
    > DLL with BPL with EXE vs EXE, тогда и обсудим кто MD.


    Приводилось не раз. Стоит ли повторяться?


    > Сделай все эти переменные, скажем, полями TApplication,
    > и будет всем хорошо.


    Ага. Типа Application.DecimalSeparator будем чем-то лучше простого DecimalSeparator. Ерундистика какая-то. Просто вбили себе в голову, что глобальные переменные - MD, а обосновывать как собираетесь. Я в курсе, что в некоторых популярных языках понятие "глобальная переменная" отсутствует, есть только "глобальный объект", но по моему мнению, спасибо разработчикам дельфи за то что в их продукте все еще можно обратиться к переменным типа DecimalSeparator минуя дополнительные "ненужные" сущности.


    > Проинициализировать что-либо при старте - это еще тот бином
    > Ньютона.


    В этом-то что Вы плохого видете?


    > Ну, и не нужны глобальные переменные.
    > Есть нужда - пользуй объекты, со свойствами только для чтения.


    А как обратиться к объекту, если ссылка на него тоже по сути переменная, а ее быть категорически не должно?


    > Пресловутые "советы" предназначены для совсем уж начинающих
    > и хороши лишь тем, что позволяют НАЧИНАЮЩИМ уберечься от
    > распространенных ошибок. Но не стоит превращать их в догмы
    > - иначе они станут столь же вредны, сколь и полезны. Программист
    > просто должен понимать, что, как и зачем он делает, чем
    > это хорошо и плохо, какие могут быть подводные камни и как
    > их не допустить - и т.д.


    +100


    > Form1 := nil;
    > Form1 := AnyValue;


    Зачем здесь AnyValue? Сломать всегда можно было все что угодно.


    > Я же указал единственно правильный и надежный путь.
    > Зачем же мучаться с глобальными переменными, которые ничего
    > не гарантирую, кроме получения AV


    Единственный правильный и надежный путь это Screen? А для поиска в Screen необходим перебор по Forms с постоянной проверкой типа
    if SameText(Screen.Forms[I].Name, 'ИмяФормы') then

    , и не дай бог я случайно изменю имя формы и забуду его указать в SameText().


    > Война бессмысленна ) и она точно - зло.


    Это точно!
  • DVM © (23.08.08 00:09) [107]

    > А как обратиться к объекту, если ссылка на него тоже по
    > сути переменная, а ее быть категорически не должно?

    наверное, как то так:

    program test;

    begin
     with Object.Create do
       Run;
    end;

    все остальное внутри объекта.
  • Германн © (23.08.08 00:53) [108]

    > DVM ©   (23.08.08 00:09) [107]
    >
    >
    > > А как обратиться к объекту, если ссылка на него тоже по
    > > сути переменная, а ее быть категорически не должно?
    >
    > наверное, как то так:

    Всё бы хорошо. Но!
    Если нужно хранить список таких объектов, то - облом! Приходится таки вводить совершенно ненужную переменную.
  • Тын-Дын © (23.08.08 02:02) [109]

    > Palladin ©   (22.08.08 20:35) [105]


    Хорошо сказано.

    Добавлю, что нужно быть очень осторожным и не скатываться к догматизму во всём.
  • Германн © (23.08.08 02:36) [110]

    > Тын-Дын ©   (23.08.08 02:02) [109]
    >
    >
    > > Palladin ©   (22.08.08 20:35) [105]
    >
    >
    > Хорошо сказано.
    >
    > Добавлю, что нужно быть очень осторожным и не скатываться
    > к догматизму во всём.
    >

    Не забудь  и сказать, что кажный оператор begin должен сопрвождаться оператором end.
  • Германн © (23.08.08 02:55) [111]

    > сопровождаться
  • DVM © (23.08.08 10:02) [112]

    > Германн ©   (23.08.08 00:53) [108]


    > Всё бы хорошо. Но!
    > Если нужно хранить список таких объектов, то - облом! Приходится
    > таки вводить совершенно ненужную переменную.

    Можно ввести объект, который содержит список других объектов и создать его, после чего вся работа будет вестись в нем. Конечно это уже изврат - избавление от глобальных переменных ради избавления.
  • Leonid Troyanovsky © (23.08.08 10:28) [113]

    > Loginov Dmitry ©   (22.08.08 23:58) [106]

    > Единственный правильный и надежный путь это Screen? А для
    > поиска в Screen необходим перебор по Forms с постоянной
    > проверкой типа if SameText(Screen.Forms[I].Name, 'ИмяФормы')
    > then, и не дай бог я случайно изменю имя формы и забуду
    > его указать в SameText().


    constructor TFormX.Create(AOwner: TComponent); // override;
    var
     i: Longint;
    begin
     for i := 0 to Screen.FormCount - 1 do
       if ClassType = Screen.Forms[i].ClassType then
         Abort;
     inherited;
    end;


    --
    Regards, LVT.
  • Leonid Troyanovsky © (23.08.08 10:32) [114]

    > Германн ©   (23.08.08 00:53) [108]

    > Если нужно хранить список таких объектов, то - облом!

    Сделай его полем того объекта, который заведомо
    переживет списочные объекты, например, MainForm or Application.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (23.08.08 10:44) [115]

    > Юрий Зотов ©   (22.08.08 14:54) [73]

    > Пресловутые "советы" предназначены для совсем уж начинающих

    Самое удивительное то, что далеко не начинающие с азартом
    их атакуют, забывая и про место и про время.

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

    --
    Regards, LVT.
  • Leonid Troyanovsky © (23.08.08 10:51) [116]

    > DVM ©   (23.08.08 10:02) [112]

    >  Конечно это уже изврат - избавление от глобальных переменных
    > ради избавления.

    Смею заметить, что размышления на эту тему бывают весьма полезны.
    Глобальные переменные, кроме всего прочего, создают большие
    препятствия повторному использованию кода, это место где
    между модульной и объектной моделью образуется разрыв.

    --
    Regards, LVT.
  • DVM © (23.08.08 10:56) [117]

    > Глобальные переменные, кроме всего прочего, создают большие
    > препятствия повторному использованию кода

    Иногда, но не всегда.
  • Loginov Dmitry © (23.08.08 10:57) [118]
    > constructor TFormX.Create(AOwner: TComponent); // override;
    >
    > var
    > i: Longint;
    > begin
    > for i := 0 to Screen.FormCount - 1 do
    >   if ClassType = Screen.Forms[i].ClassType then
    >     Abort;
    > inherited;
    > end;


    А поизвращеннее ничего нельзя было придумать? Нормально, я тихо мирно хочу показать форму на экране и продолжить дальше свою обработку. Вызываю TMyForm.Create().Show. Так мало того что Show второй раз не сработает, так и дальнейная обработка не выполнится, и я даже не увижу причину. Ужас!
  • Leonid Troyanovsky © (23.08.08 10:59) [119]

    > DVM ©   (23.08.08 10:56) [117]

    > Иногда, но не всегда.

    А ты еще поразмышляй.

    --
    Regards, LVT.
  • DVM © (23.08.08 11:00) [120]

    > А ты еще поразмышляй.


    допустим, опять же, есть такой модуль:

    unit WinVersion;

    interface
    var
     WinVersion: string;

    function GetWinVersion: string;  

    implementation

    ....

    initialization

    WinVersion := GetWinVersion;

    end;



    Как препятствует повторному использованию этого кода переменная WinVersion ?
  • Leonid Troyanovsky © (23.08.08 11:03) [121]

    > Loginov Dmitry ©   (23.08.08 10:57) [118]

    > А поизвращеннее ничего нельзя было придумать? Нормально,
    >  я тихо мирно хочу показать форму на экране и продолжить
    > дальше свою обработку. Вызываю TMyForm.Create().Show. Так
    > мало того что Show второй раз не сработает, так и дальнейная
    > обработка не выполнится, и я даже не увижу причину. Ужас!

    Все в твоих руках, и показ исключений в том числе.
    А что ты собирался Show, если форма не создана?

    --
    Regards, LVT.
  • Leonid Troyanovsky © (23.08.08 11:09) [122]

    > DVM ©   (23.08.08 11:00) [120]

    > Как препятствует повторному использованию этого кода переменная
    > WinVersion ?

    А что ты собирался использовать?
    И еще, секция инициализации - это тоже не самая хорошая
    задумка борландов.

    --
    Regards, LVT.
  • Loginov Dmitry © (23.08.08 11:16) [123]
    глобальные переменные - MD
    DLL - лажа
    секция инициализации - г..но

    как нам вообще удается на дельфи что-то программировать?
  • DVM © (23.08.08 11:16) [124]

    > А что ты собирался использовать?

    А неужели не видно? Я собрался использовать во различных программах этот модуль, а точнее его глобальную переменную WinVersion для получения текущей версии Windows в текстовом представлении, например. На месте версии Windows могло быть что угодно, это не важно.
  • DVM © (23.08.08 11:17) [125]

    > И еще, секция инициализации - это тоже не самая хорошая
    > задумка борландов.

    давайте не отвлекаться от сути, так в какие проблемы с повторным использованием кода [120]?
  • DVM © (23.08.08 11:19) [126]

    > И еще, секция инициализации - это тоже не самая хорошая
    > задумка борландов.

    Для эстетов:

    unit WinVer;

    interface
    var
    WinVersion: string;

    procedure InitializeModule;  
    function GetWinVersion: string;  

    implementation

    ....

    procedure InitializeModule;
    begin  
     WinVersion := GetWinVersion;
    end;

    end;

  • @!!ex © (23.08.08 11:23) [127]
    > как нам вообще удается на дельфи что-то программировать?

    Так и не удается... ПОэтому здесь половина народу пишет на С++, Шарпе и Яве.
  • Loginov Dmitry © (23.08.08 11:27) [128]
    > Все в твоих руках, и показ исключений в том числе.
    > А что ты собирался Show, если форма не создана?


    Я так и понял, что предлагаемый Вами код для практических задач не годится.

    собственно можно сделать классовый метод и описать создание формы в нем:

    class function TBaseForm.GetForm(AOwner: TComponent): TMyForm;
    var
     i: Integer;
    begin  
     for i := 0 to Screen.FormCount - 1 do
       if Screen.Forms[i].ClassType = Self then
       begin
         Result := Screen.Forms[i] as Self;
         Exit;
       end;

     Result := Self.Create(AOwner);
    end;

  • Leonid Troyanovsky © (23.08.08 11:34) [129]

    > Loginov Dmitry ©   (23.08.08 11:27) [128]

    > Я так и понял, что предлагаемый Вами код для практических
    > задач не годится.

    Зависит от задач.
  • Leonid Troyanovsky © (23.08.08 11:37) [130]

    > Leonid Troyanovsky ©   (23.08.08 11:34) [129]

    > Зависит от задач.

    Sorry, промахнулся по кнопе.

    > собственно можно сделать классовый метод

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

    Но, как я понял, идея усвоена.

    --
    Regards, LVT.
  • Leonid Troyanovsky © (23.08.08 11:43) [131]

    > DVM ©   (23.08.08 11:19) [126]

    > Для эстетов:

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

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

    --
    Regards, LVT.
  • Тын-Дын © (23.08.08 12:46) [132]

    > Германн ©   (23.08.08 02:36) [110]
    >
    > > Тын-Дын ©   (23.08.08 02:02) [109]
    > >
    > >
    > > > Palladin ©   (22.08.08 20:35) [105]
    > >
    > >
    > > Хорошо сказано.
    > >
    > > Добавлю, что нужно быть очень осторожным и не скатываться
    >
    > > к догматизму во всём.
    > >
    >
    > Не забудь  и сказать, что кажный оператор begin должен сопрвождаться
    > оператором end.


    Для тебя специально:

    Не забудь, что руки перед едой нужно мыть.
  • {RASkov} © (23.08.08 12:57) [133]
    Ну хватит вам.... как маленькие :)
  • DVM © (23.08.08 14:25) [134]

    > Почему переменная в интерфейсной секции, если
    > можно вызвать функцию, возвращающую нужную строку.
    >

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


    > Пока я не вижу, чего, собс-но, нужно повторно пользовать.

    Код этого модуля, написанный единожды можно ПОВТОРНО ИСПОЛЬЗОВАТЬ В РАЗНЫХ ПРОЕКТАХ. Я в этом контексте понял. Или вы о каком другом понимании повторного использования говорите?


    > И речь шла об объектах в модулях, содержащих
    > глобальные переменные.
    >

    Речь шла о том что глобальные переменные (любые) - абсолютное ЗЛО и MD! Это ваши слова. В этой и соседней ветке. Ну и какой вред от глобальной переменной, что я привел? Правильно, никакого, а только сплошное удобство. И не согласиться с этим можно только из нежелания признавать очевидный факт.
  • Leonid Troyanovsky © (23.08.08 15:02) [135]

    > DVM ©   (23.08.08 14:25) [134]

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

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

    Хотя, это все полумеры, но уж меньшее зло.

    > Речь шла о том что глобальные переменные (любые) - абсолютное
    > ЗЛО и MD! Это ваши слова.

    Про абсолютное зло - это не мое.
    И кричать на нас не надо.

    > согласиться с этим можно только из нежелания признавать
    > очевидный факт.

    Не хочешь думать - не думай.
    Чужим умом не проживешь.

    --
    Regards, LVT.
  • Игорь Шевченко © (23.08.08 15:03) [136]
    Тын-Дын ©   (23.08.08 12:46) [132]


    > Не забудь, что руки перед едой нужно мыть.


    Че, отпуск кончился, можно троллить с новыми силами ?
  • DVM © (23.08.08 16:22) [137]

    > Leonid Troyanovsky ©   (23.08.08 15:02) [135]


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

    Согласен, так можно, был уверен, что так скажете, но зачем плодить лишние сущности? Плюс ко всему, а вдруг нам понадобится иметь возможность и менять значение этой глобальной переменной извне? Сделаем еще одну функцию? И того вместо одной сущности - три. Правильно, в этом случае вообще надо уж класс городить и делать переменную свойством в этом классе, а вышеупомянутые функции туда методами. Не слишком ли наворочено для всего лишь одной переменной? А если переменных таких 10? Будем делать 10 классов, 20 функций. Как хотите, но вы меня не переубедили.


    > Про абсолютное зло - это не мое.
    > И кричать на нас не надо.

    Сами начали писать MD заглавными буквами в разных ветках.


    > Не хочешь думать - не думай.
    > Чужим умом не проживешь.

    Чужим это вашим что ли? Вы мыслите догмами, которые сами себе выдумали и навязываете другим. На этом обсуждение заканчиваю ибо убедительных доводов против глобальных переменных я до сих пор не услышал - так болтология одна.
  • Leonid Troyanovsky © (23.08.08 16:43) [138]

    > DVM ©   (23.08.08 16:22) [137]

    > лишь одной переменной? А если переменных таких 10? Будем
    > делать 10 классов, 20 функций.

    Удивительная беспомощность.

    > убедительных доводов против глобальных переменных я до сих
    > пор не услышал

    А я и не приводил никаких доводов, бо они очевидны любому,
    знакомому с основами программирования.
    Я обратил внимание лишь на одно обстоятельство, осмыслить
    которое ты не сумел или не захотел.

    Ну, жизнь научит.

    --
    Regards, LVT.
  • Тын-Дын © (23.08.08 17:27) [139]

    > Игорь Шевченко ©   (23.08.08 15:03) [136]
    > Тын-Дын ©   (23.08.08 12:46) [132]
    >
    >
    > > Не забудь, что руки перед едой нужно мыть.
    >
    >
    > Че, отпуск кончился, можно троллить с новыми силами ?


    Мне конечно не хочется пустой флейм разводить, но может быть посмотреть на оппонента повнимательнее и не писать ерунды?
  • Renegat © (23.08.08 19:58) [140]
    Глобальные переменные не есть абсолютное зло. Да и с чего бы? Наоборот, они, отъедая совсем немного от секции данных, экономят не только операцию выделения под них стэка при вызове функции (и его освобождения при выходе, кстати), но и собственно место в стэке. Конечно, не стоит этим злоупотреблять, и юзать их только когда кончаются регистры.
  • Германн © (23.08.08 20:06) [141]

    > стэка

    - Вот послал бог дурака уполномоченного по копытам! - Сердился Остап. - Ничего поручить нельзя. Купил машинку с турецким акцентом.
    (с:)
  • Renegat © (23.08.08 20:08) [142]
    упс. Туплю, звиняйте... о_0
    ЗЫ: забыл где нахожусь %)
  • Anatoly Podgoretsky © (23.08.08 21:53) [143]
    > Renegat  (23.08.2008 20:08:22)  [142]

    А теперь еще узнай и что такое стек. Тут уже не туплю пахнет.
  • @!!ex © (23.08.08 22:08) [144]
    > [143] Anatoly Podgoretsky ©   (23.08.08 21:53)

    А в чем вопрос? Типа смещение указателя стэка операция не тратящая времени?
  • Anatoly Podgoretsky © (23.08.08 22:28) [145]

    > @!!ex ©   (23.08.08 22:08) [144]

    > но и собственно место в стэке.

    А ты тоже не представляешь как работает стек? Как можно в нем место съекономить, по сравнению с глобальными переменными?
  • @!!ex © (23.08.08 22:33) [146]
    > А ты тоже не представляешь как работает стек?

    Насколько мне известно: стэк - это заранее выделенный кусок памяти по которой перемещается указатель.
    Память в стэке - это фигня. Потому что чтобы сейчас переполнить стэк - нужно очень постаратся.
    А вот время на перемещени указатиеля не нулевое, и на этом омжно сэкономить, если идет частое обращение к переменной.
  • Плохиш © (23.08.08 22:39) [147]

    > @!!ex ©   (23.08.08 22:33) [146]

    А можно, пожалуйста, слово "стек" писать правильно? А то глаза режет.
  • @!!ex © (23.08.08 22:45) [148]
    > [147] Плохиш ©   (23.08.08 22:39)

    Неужели Stack произносится как стек?? И где же в слове Stack звук "е"??
  • Плохиш © (23.08.08 22:47) [149]

    > Неужели Stack произносится как стек?

    А, понял, поколение компютикус, "как слышится, так и пишется"... Всё ухожу, здесь мне делать нечего...
  • Anatoly Podgoretsky © (23.08.08 22:47) [150]
    > @!!ex  (23.08.2008 22:33:26)  [146]

    Вот именно, что заранее выделеный кусок и использование локальных переменных приводит к уменьшению потребности в памяти, а не наоборот, как написано у Ренегата. Поскольку стек повторно используемый. Про указатели речь не шла, а адресация относительная, позиционно-независимая, относительно фрейма стека. И память выделять не надо, так же и освобождать.
  • @!!ex © (23.08.08 22:49) [151]
    > [149] Плохиш ©   (23.08.08 22:47)

    В данном случае пишу так, как есть транскрипция с английского(оригинального) языка.
    На основании какого правила вы считаете, что правильно - "е"?
    Я всегда рад исправить свои ошибки. Но пока ошибки не вижу.
  • Smile (23.08.08 22:50) [152]
    А еще разумнее будет открыть ветку Мастеров (с авторством тех кого этот вопрос интересует) по этой проблеме, поскольку автор давно покинул "дискуссию".
  • Anatoly Podgoretsky © (23.08.08 23:09) [153]
    Не интересует, переменные никогда не обнуляю после использования, поскольку никогда повторно не использую. Если нужен гарантированое знание есть ли форма, то восспользуюсь надежным решением, вместо ламерского. А профессиональное решение в использование Screen.Forms
  • Германн © (24.08.08 00:26) [154]

    > @!!ex ©   (23.08.08 22:49) [151]
    >
    > > [149] Плохиш ©   (23.08.08 22:47)
    >
    > В данном случае пишу так, как есть транскрипция с английского(оригинального)
    > языка.

    А при чём тут транскрипция? Транскрипция описывает произношение, а не написание.
    > На основании какого правила вы считаете, что правильно -
    >  "е"?
    На основании принятого в современном русском языке написания.
  • Anatoly Podgoretsky © (24.08.08 00:45) [155]
    > Германн  (24.08.2008 0:26:34)  [154]

    Дети запомните правило

    булька, вилька пишутся без мягкого знака,
    а сол с мягким.
  • Германн © (24.08.08 00:59) [156]

    > Anatoly Podgoretsky ©   (24.08.08 00:45) [155]

    Похоже на анекдот. Кстати неплохой. Сам придумал?
  • Anatoly Podgoretsky © (24.08.08 01:04) [157]
    > Германн  (24.08.2008 0:59:36)  [156]

    Ни, грузинская мудрость.
  • Германн © (24.08.08 01:21) [158]

    > Anatoly Podgoretsky ©   (24.08.08 01:04) [157]

    Это провокация?
    :)

    Вспоминаю давний монолог Хазанова про "воронье" яйцо :)
    И ещё вспоминаю нашего (в МИФИ) преподавателя урматов. Грузина по национальности. Имя Отчество уже забыл, но фамилию помню. Бицадзе. Кстати у него есть по крайней мере один очень хороший учебник или сборник задач по урматам.
    Так вот он несколько раз вспоминал, как посещал общагу по велению парткома.
    "Ви думаете, что они там учатся? Нет. Они там все пияные валяются!".:)
  • Anatoly Podgoretsky © (24.08.08 01:47) [159]
    > Германн  (24.08.2008 1:21:38)  [158]

    Это про произношение, грузины просто под руку попали, как самое наглядное пособие.
  • Renegat © (24.08.08 01:54) [160]
    > [150] Anatoly Podgoretsky ©   (23.08.08 22:47)

    Вот именно что относительно фрейма. Я так думаю что вряд ли кадр (фрейм, если угодно) стэка можно создать, не смещая ESP. Ведь даже если делать как-то наподобие
    DWORD PTR [ESP-4*(k-1)], k є N
    то первый же PUSH затрёт какую-нибудь переменнную.

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

    Вот что я имел в виду под экономией.

    В принципе, Дядя Толя тоже прав - в общем случае никакой экономии не получится.
    Однако существует море частностей, которые кстати очень часто встречаются.

    ЗЫ: Простите, если что, за нетрезвый вид =)
  • Германн © (24.08.08 02:01) [161]

    > стэка

    Опять? Стек есть стек. Так  уж сложилось "написание" сего технического термина на русском. И не надо изобретать что-то иное.
  • @!!ex © (24.08.08 08:07) [162]
    > На основании принятого в современном русском языке написания.

    Кем оно принято??
    Мне просто очень интересно откуда в этом слове взялась буква "е"??
  • Leonid Troyanovsky © (24.08.08 08:53) [163]

    > @!!ex ©   (24.08.08 08:07) [162]

    > Мне просто очень интересно откуда в этом слове взялась буква
    > "е"??

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

    --
    Regards, LVT.
  • @!!ex © (24.08.08 09:37) [164]
    Мдя... А еще удивлялся, почему студенты в практических работах пишут Stek...
    Понятно откуда ножки растут...
  • @!!ex © (24.08.08 10:11) [165]
    Кстати, а можно какой нить источник, в котором бы указывалось, что stack надо через "е" писать.
    А то все говорят, что это обще принятое написание, а никаких ссылок не дают...
  • Юрий Зотов © (24.08.08 10:19) [166]
    > @!!ex ©   (24.08.08 10:11) [165]

    В общем-то, вряд ли удастся и найти правило, согласно которому слово "кОрова" надо писать через "О".

    :о)
  • @!!ex © (24.08.08 10:24) [167]
    > [166] Юрий Зотов ©   (24.08.08 10:19)

    На ладно? :))
    Корова. Образовано от «кор» – рог.

  • @!!ex © (24.08.08 10:26) [168]
    *Да ладно.
  • Юрий Зотов © (24.08.08 10:27) [169]
    > @!!ex ©   (24.08.08 10:24) [167]

    А короед питается носокорами...
  • @!!ex © (24.08.08 10:31) [170]
    > [169] Юрий Зотов ©   (24.08.08 10:27)

    А что не устраивает то? Откройте любой этимологический словарь, там прямо написано:
    Корова - от латинского "кор" - рог. Т.е. "корова" - рогатая, имеющая рога.

  • Юрий Зотов © (24.08.08 10:44) [171]
    > @!!ex ©   (24.08.08 10:31) [170]

    > словарь...

    В том-то и дело. Если открыть словарь лет этак тыщ 5 назад, то слова "корова" в нем запросто могло бы и не оказаться. А если открыть словарь лет этак через сто, то в нем запросто может оказаться слово "стек" (от англ. stack).

    Словарь лишь констатирует общепринятые написания слов, и не более того. А правила написания слова "кОрова" через "О" не существует. Так принято - вот и все правило.

    Просто слово "корова" - старое, в языке существует давно и поэтому в словарях оно есть. А слово "стек" (не в смысле "хлыст", а в смысле "стопка") - новое, в языке существует недавно, используется, в основном, как профессиональный термин и в словари еще не вошло. Если в языке приживется, то когда-нибудь войдет и в словари.
  • @!!ex © (24.08.08 11:28) [172]
    > [171] Юрий Зотов ©   (24.08.08 10:44)

    Согласен. Поэтому и не понял, с чего это вдруг оказалось, что написание "стек" общепринятое?
    Раз нет правила, значит можно и так и так писать. Приживется и попадет в словари один вариант... Вот когда он попадет, тогда и можно будет говорить об общепринятости.
  • Тын-Дын © (24.08.08 11:42) [173]

    > @!!ex ©   (24.08.08 11:28) [172]


    Вспомни, есть хоть одно слово через "э" в русском языке?

    Вот ведь некоторые субъекты не могут уняться по поводу произношения.
    лишь бы пофлудить и ветку загадить.
    Шли бы эти субъекты в чат и потрепаловку и там бы флудили.
  • @!!ex © (24.08.08 12:14) [174]
    > Вспомни, есть хоть одно слово через "э" в русском языке?

    полиэтилен?
    еще надо?
  • @!!ex © (24.08.08 12:16) [175]
    ПРимер портации слова с английского языка(стэк - это тоже портация с английского)
    Хэллоуин

    Хеллоуин должно быть?
  • Тын-Дын © (24.08.08 12:19) [176]

    > @!!ex ©   (24.08.08 12:14) [174]
    > > Вспомни, есть хоть одно слово через "э" в русском языке?
    >
    >
    > полиэтилен?
    > еще надо?


    Это составное слово. Поли- этилен.
    Т.е. "Э" в начале слова.


    > Хеллоуин должно быть?


    А кто сказал, что правильно через "е".

    Я бы сказал, что иностранные слова можно писать и в иностранной транскрипции, правила не запрещают, но правильней всё же через "е", в соответствии с традициями языка.
  • Тын-Дын © (24.08.08 12:20) [177]
    А спор и оффтопик тут некоторые начали ради самого флуда.
    Отвратительно.
  • @!!ex © (24.08.08 12:20) [178]
  • Renegat © (24.08.08 14:34) [179]
    *пригорюнившись* вот так и становятся спьяну троллями =(
    А ведь давайте таки вспомним, о чём-таки была тема в самом начале?

    > заNILить форму после Close

    !!1
  • {RASkov} © (24.08.08 14:40) [180]
    хотели занилить, в итоге - замылили
  • Leonid Troyanovsky © (24.08.08 19:27) [181]

    > @!!ex ©   (24.08.08 11:28) [172]

    > Согласен. Поэтому и не понял, с чего это вдруг оказалось,
    >  что написание "стек" общепринятое?

    Уж лет 50, как пишут.
    А ты чего, книг не читаешь?

    --
    Regards, LVT.
  • @!!ex © (24.08.08 19:49) [182]
    > А ты чего, книг не читаешь?

    На русском есть хорошие книги??
    АрхангЭльский, ФлЭнов? :))
  • Leonid Troyanovsky © (24.08.08 19:51) [183]

    > @!!ex ©   (24.08.08 19:49) [182]

    > На русском есть хорошие книги??

    А то.
    И не только про дельфи.

    --
    Regards, LVT.
  • @!!ex © (24.08.08 19:54) [184]
    > А то.

    Кстати, да..
    У меня две таких кондиционер поддерживают... очень хорошие книги... выкинуть жалко - так, пользу приносят.
    Пока единственное что толковое отечественное видел - это Ассемблер... Д аи то это не книга, а сборник лекций.
  • Leonid Troyanovsky © (24.08.08 20:33) [185]

    > @!!ex ©   (24.08.08 19:54) [184]

    > У меня две таких кондиционер поддерживают... очень хорошие
    > книги... выкинуть жалко - так, пользу приносят.

    Ну, примерно так мы и представляли.

    --
    Regards, LVT.
  • @!!ex © (24.08.08 20:53) [186]
    > [185] Leonid Troyanovsky ©   (24.08.08 20:33)

    Ну да... А чтож делать, если отечественные авторы писать не умеют, а переводы просто ужасные? ПРиходится довольствоваться книгами и статьями на английском, куда деваться...
 
Конференция "Начинающим" » заNILить форму после Close;
Есть новые Нет новых   [134442   +12][b:0.001][p:0.005]