Изменение родительского контейнера вызывает повторный вызов Createwnd, Delphi 6

У нас есть некоторые устаревшие пользовательские компоненты Delphi, которые переопределяют createwnd. Эти компоненты располагаются на панели внутри формы.

Когда форма и панель создаются, то же самое делают и компоненты, и createwnd вызывается один раз. Это имеет смысл.

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

Например, при определенных обстоятельствах я могу изменить родительский контейнер Panel1 на Form2.panel2. В основном рисование Panel1 внутри панели Form2 во время выполнения.

TForm1.buttonclick(..)
begin
..
  Panel1.parent := Form2.panel2;
..
end;

Почему пользовательские компоненты в Panel1 создаются заново при изменении родительского компонента?

И является ли поведение одинаковым для всех компонентов в Panel1, даже для тех, которые не являются пользовательскими, например, если бы у меня также был TButton на Panel1, он также был бы воссоздан при переключении родителей? Я не думаю, что это так, поэтому я был так удивлен.

Наконец, если это поведение неверно, как мне сделать так, чтобы createwnd не вызывался при изменении родительских контейнеров.

Спасибо!


person sse    schedule 18.04.2013    source источник
comment
Поведение не является неправильным. Это так, как задумано.   -  person David Heffernan    schedule 19.04.2013
comment
На самом деле то, что называется, TControl.RecreateWnd. Посмотрите исходный код VCL, если он у вас есть; он ведет себя точно так, как задумано.   -  person Ken White    schedule 19.04.2013


Ответы (1)


У всех элементов управления на панели, происходящих от TWinControl, пересоздаются дескрипторы окна, а также дескриптор окна панели (причина в другом).

Если ваш код должен вызываться только один раз за время жизни программы, то CreateWnd не подходит. Вместо этого попробуйте конструктор.

Кроме того, замена панели из одной формы в другую может привести к спутыванию прав собственности на панель и привести к непредвиденному поведению или даже ошибкам. См.: Как отсоединить панель и отобразить ее в отдельном окне?

person NGLN    schedule 18.04.2013
comment
Спасибо за ответ и понимание. Я буду перемещать код в конструктор. - person sse; 19.04.2013
comment
Также может показаться, что простое изменение стиля формы, например, с fsMdichild на fsNormal, также запускает создание компонентов. - person sse; 19.04.2013