2014-02-20 12 views
-4

Я хочу проверить процедуру Form1.OnCreate обработчика событий, если конструктор Form1 Create завершил задание с заполнением всех компонентов в Form1. Затем вы хотели бы использовать Form1 для прокрутки компонентов и изменения свойства Text. Я пробовал:Delphi XE5 - Ожидание заполнения групп объектов TForm.OnCreate()

WHILE NOT Assigned(Form1) DO 
    Sleep(100); 

... но это не сработало.

Теперь, когда я пытаюсь использовать Form1, я получаю ошибку «Нарушение прав доступа».

+0

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

+2

Кажется, вы пытаетесь получить доступ к классу, а не к экземпляру? Класс называется TForm1, переменная экземпляра называется Form1? Вы не можете использовать Assigned в классе? – whosrdaddy

+2

'while not Assigned (Form1) do Sleep (100)' тоже не поможет. Это цикл, который никогда не заканчивается. Я призываю вас объяснить настоящую проблему. –

ответ

5

Событие OnCreate инициируется в конце конструкции объекта формы. Компоненты формы создаются во время процесса строительства до того, как будет запущено событие OnCreate. Нет необходимости в «проверьте .., если конструктор Form1 Create завершил работу«, поскольку это в принципе гарантировано. После запуска OnCreate вы можете получить доступ к компонентам.

Если объект Form1 создается с помощью TApplication.CreateForm() при запуске программы, то переменная Form1 будет назначен действительный но неинициализированный объект до того, как конструктор вызывается, и, таким образом, будет указывать на действительный объект в OnCreate случае.

Если объект Form1 создается путем вызова конструктора в коде, то переменная Form1 будет не назначаться, пока после выхода конструктора, и, таким образом, не будет указывать на действительный объект в OnCreate случае.

В любом случае, вы не должны использовать переменную Form1 внутри события OnCreate для объекта Form1 для начала. Вместо этого используйте указатель Self или введите тип события Sender. Оба будут указывать на тот же объект Form1, который был создан.

+0

Спасибо, также много важной и полезной информации для меня. –

5

Это отвечает на то, что я считаю реальной проблемой, как стало видно из ваших комментариев. Вы должны отредактировать вопрос, чтобы включить те детали, которые на данный момент появляются только в комментариях.

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

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

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

Или вы хотите использовать глобальную переменную Form1, которая составляет nil во время создания формы. Но вам было бы желательно удалить эту глобальную переменную Form1 в любом случае. Глобальные переменные, как правило, вызывают проблемы. Поскольку вы находитесь внутри метода вашей формы, в обработчике метода для OnCreate вы можете получить доступ к форме, используя Self. Всегда используйте Self, если это возможно.

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

Это, как я бы решить вашу проблему:

  1. Объявите новую форму, полученную из TForm, называемой, например, TMyBaseForm.
  2. Процедура AfterConstruction, с директивой override.
  3. Внесите TMyBaseForm.AfterConstruction, чтобы позвонить, используя ваш код. На этом этапе существует все время контроля времени разработки и потоки данных.
  4. Убедитесь, что все формы в вашем приложении получены от TMyBaseForm.

Этот проект дает вам возможность применять последовательное поведение по всем элементам GUI в вашей программе.

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

+0

Благодарим вас за принятие. Надеюсь, я понял тебя правильно. Я был бы признателен, если бы вы могли отредактировать вопрос, чтобы спросить, на что я верю, что вы действительно имели в виду. –

+0

Спасибо, ты бог из города Дельфы ;-) надеюсь, что правки теперь в порядке? –