Конференция "Начинающим" » Как зарегистрировать TFormClass имея string "TForm2" [D7, WinXP]
 
  • веловня (08.03.17 14:43) [0]
    Привет!
    Есть вопрос:
    В проекте имеется 2 формы, Form1: TForm1 и Form2: TForm2.
    Form1 - auto-create, Form2 - available.
    Как создать Form2 в коде Form1, не регистрируя заранее класс TForm2?
    Т.е. у меня в рантайме имеется на входе string "TForm2", и мне надо в рантайме зарегистрировать формкласс TForm2 имея только эту строку. Форма такая в проекте конечно есть.
    Честно пытался найти, не нашел варианта регистрации TFormClass.
    Нужно мне это для автоматического создания тех форм, которые были открыты в предыдущем сеансе.
  • Игорь Шевченко © (08.03.17 19:28) [1]
    FindClass не предлагать ?
  • Юрий Зотов © (08.03.17 22:44) [2]
    Найти класс по его строковому имени можно лишь тогда, когда он УЖЕ зарегистрирован. Поэтому предлагаю:

    1. При запуске программа регистрирует TForm2, TForm3 и т.д. Для этого нужно только прописать их юниты в uses, больше ничего не требуется.

    2. Далее программа откуда-то из своих настроек читает строковые имена классов ('TForm2', 'TForm3' и т.д.).

    3. А далее - FindClass.
  • Юрий Зотов © (08.03.17 22:48) [3]
    Не уверен, но смутно помню, что классы используемых  в проекте форм, вроде бы, регистрируются  автоматически, без нашего участия. Если это так, то первый пункт - лишний.
  • веловня (09.03.17 00:02) [4]
    В uses конечно Form2 прописана.
    Но, строка:
    TFormClass(FindClass('TForm2')).create(application);
    вызывает ошибку:
    Class TForm2 not found.
  • веловня (09.03.17 00:05) [5]
    Я много искал на эту тему, и самое близкое решение - это регистрация классов:
    RegisterClass(TForm2);
    Но у меня нет класса, у меня есть только строка 'TForm2'.
  • веловня (09.03.17 00:13) [6]
    Т.е. строка:
    Form2:=TForm2.create(application);
    работает.
    Вместо неё в том же месте строка:
    TFormClass(FindClass('TForm2')).create(application);
    не работает.
  • sniknik © (09.03.17 00:20) [7]
    > без нашего участия.
    и также без нашего участия оптимизатор вырежет все что не упоминается в коде... в строках само собой не объекты туда не смотрит.
    ну, возможно.

    > вызывает ошибку:
    > Class TForm2 not found.
    оптимизатор отключи.

    а вообще блаж какая то. почему просто не написать -
    if строка = 'TForm2' then
     TForm2.Create;
    и вообще как работать с неизвестным классом? если у всех общие методы то просто классика ООП, а если нет, ну вот вызываешь ты Create, а он у класса перекрыт и та еще параметры нужны, или вообще другой конструктор определен.
  • веловня (09.03.17 00:34) [8]
    Вот я сделал демо проект:
    http://mail.stavropol-consulting.ru/01.zip
  • веловня (09.03.17 00:43) [9]
    > sniknik

    Это не просто блажь.
    Мне нужно будет добавлять в исходниках:
    if строка = 'TForm2' then TForm2.Create;
    для каждой формы.
    Это ересь пред догматом автоматизации.
  • веловня (09.03.17 00:51) [10]
    Отключение оптимизатора кстати не помогает.
  • Германн © (09.03.17 02:26) [11]

    > веловня   (09.03.17 00:43) [9]
    >
    > > sniknik
    >
    > Это не просто блажь.
    > Мне нужно будет добавлять в исходниках:
    > if строка = 'TForm2' then TForm2.Create;
    > для каждой формы.

    Блажь это или не блажь может быть понятно только после описания задачи.
    А пока сам вопрос блажь. Зачем приспичило
    TFormClass(FindClass('TForm2')).create(application);
    В стандартном приложении написанном на Дельфи нет нужды в таком извращении.
  • Юрий Зотов © (09.03.17 05:16) [12]
    1. Автор хочет, чтобы при старте приложения автоматически восстанавливались все формы, которые были открыты при завершении предыдущего сеанса. Нормальное желание, а никакое не извращение.

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

    3. Возник вопрос с поиском класса при запуске программы. Все верно, он и должен был возникнуть. См. [2] и код ниже.

    4. Для восстановления состояния программы мало создать все ранее открытые формы. Надеюсь, автор это понимает.

    5. А формы создаются очень просто (см. [2]).

    uses
     Unit2;

    procedure TForm1.FormCreate(Sender: TObject);
    var
     C: TFormClass;
     F: TForm;
    begin
     RegisterClass(TForm2);
     // ... Здесь читаем настройки, а в них - строку 'TForm2'
     C := TFormClass(FindClass('TForm2'));
     F := C.Create(Application);
     F.Show
    end;
  • sniknik © (09.03.17 08:30) [13]
    > Это ересь пред догматом автоматизации.
    с чего это? по тому что тут озвучено "ТЗ", самое то.

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

    > 5. А формы создаются очень просто (см. [2]).
    так создать то вроде и не проблема, проблема сделать
    RegisterClass(TForm2);
    без TForm2, только с 'TForm2', т.к. до этого одно просто строка, другое просто описание типа в исходниках, и без этого в скомпилированные обьекты - к использованию в рантайме не попадает.
  • rrrrr © (09.03.17 08:32) [14]
    Я много искал на эту тему, и самое близкое решение - это регистрация классов:

    для этого решения нужно предварительно найти ссылку на класс.
    но когда ты ее получил, ты просто сразу можешь вызвать конструктор без всякой регистрации. тем более что все уже давно зарегистрировано, так как все твои оба класса живут в одном exe.
  • icWasya © (09.03.17 09:40) [15]
    >проблема сделать
    >RegisterClass(TForm2);
    >без TForm2, только с 'TForm2', т.к. до этого одно просто строка,
    После того, как сделаете RegisterClass(TForm2), будет работать FindClass('TForm2').
    Где это сделать - лучше всего в каждом юните, где у Вас описан класс формы, например, TForm2,добавить в самом конце

    initialization
    RegisterClass(TForm2);

  • sniknik © (09.03.17 10:16) [16]
    icWasya ©   (09.03.17 09:40) [15]
    чтобы продать что нибудь не нужное нужно сначала купить что нибудь не нужное, а у "нас"/автора денег нет. © простоквашино.
    т.е. так, как ему, пишет нужно -
    initialization
    RegisterClass(FindClass('TForm2'));


    не работает. ;)
  • ухты © (09.03.17 14:41) [17]
    так как автор хочет то надо регистрировать все что может восстанавливаться, регистрировать как в [15] например
    но согласен с тем что это всё не автоматизация а ерунда )) ифов хватает за глаза
  • ухты © (09.03.17 14:57) [18]
    или ртти использовать, только в д7 все ли как надо отработает уже не в курсе
  • Юрий Зотов © (09.03.17 16:31) [19]
    [15] - хорошее решение.

    > ифов хватает за глаза

    В проекте появилось 10 новых форм. Будем наращивать в IF еще 10 этажей?

    Или используем [15] в сочетании с [12] - и все произойдет автоматически.
 
Конференция "Начинающим" » Как зарегистрировать TFormClass имея string "TForm2" [D7, WinXP]
Есть новые Нет новых   [118236   +9][b:0][p:0.001]