|  | 
| Фреймы, как визуальные компоненты, изменение наследованияИсточник: delphi2010 Александр Божко Фреймы в Delphi - интересная штука, которая может создать проблемы "на ровном месте". Вам случалось получать подобное сообщение об ошибке при создании потомка класса TFrame? --------------------------- Error Reading Form --------------------------- Error reading TDioptreFrame.ClientHeight: Property ClientHeight does not exist. Ignore the error and continue? NOTE: Ignoring the error may cause components to be deleted or property values to be lost. --------------------------- Ignore Cancel Ignore All --------------------------- И что странно: потомки TFrame не имеют свойства ClientHeight. Если вы нажмете Cancel, то получите следующее сообщение об ошибке: --------------------------- Error --------------------------- Error creating form: Error reading TDioptreFrame.ClientHeight: Property ClientHeight does not exist. --------------------------- OK --------------------------- У меня такое случалось, и здесь я объясню причину, из-за которой это может происходить. Обычно, когда вы создаете фрейм (скажем, TBaseFrameComponent), вы используете панель инструментов (или меню File > New > Other > Delphi Files > Frame). При этом создается новый TbaseFrameComponent, который наследуется от TFrame. Когда вы хотите создать фрейм (допустим, TMyFrameComponent), основанный на TBaseFrameComponent, вы также используете панель инструментов, (или File > New > Other > Inheritable Items > BaseFrameComponent). Так создается новый TMyFrameComponent, который наследуется от TBaseFrameComponent. Но если у вас уже имеется TMyExistingFrameComponent, унаследованный от TFrame и вы хотите сделать его наследником TBaseFrameComponent? Вы меняете эту декларацию:  {$i Defines.Inc}
 unit MyExistingFrameComponentUnit;
 interface
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls;
 type
   TCustomMyExistingFrameComponent = class(TFrame)
   end;
   TMyExistingFrameComponent = class(TCustomMyExistingFrameComponent)
   end;
 implementation
 {$R *.dfm}
 end.На эту:  {$i Defines.Inc}
 unit MyExistingFrameComponentUnit;
 interface
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls, BaseFrameComponentUnit;
 type
   TCustomMyExistingFrameComponent = class(TBaseFrameComponent)
   end;
   TMyExistingFrameComponent = class(TCustomMyExistingFrameComponent)
   end;
 implementation
 {$R *.dfm}
 end.
Если вы оставите такой код без изменений, то рано или поздно получите приведенную выше ошибку. object CustomMyExistingFrameComponent: TCustomMyExistingFrameComponent Left = 0 Top = 0 ClientHeight = 71 ClientWidth = 156 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = True PixelsPerInch = 96 TextHeight = 13 end Новый фрагмент .dfm: inherited CustomMyExistingFrameComponent: TCustomMyExistingFrameComponent Left = 0 Top = 0 ClientHeight = 71 ClientWidth = 156 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = True PixelsPerInch = 96 TextHeight = 13 end После перевода отображения .dfm файла из текстового вида в вид формы и обратно, новый .dfm фрагмент чудесным образом преобразуется в что-то подобное:    inherited CustomMyExistingFrameComponent: TCustomMyExistingFrameComponent
    Width = 71
    Height = 156
    ParentFont = False
    ExplicitWidth = 71
    ExplicitHeight = 156
   endТеперь, как только вы перекомпилируете пакет компонентов, формы/фреймы перезагрузятся с учетом компонентов, размещенных на фрейме, и все будет нормально размещено. В заключение маленькое резюме. Как конвертировать фрейм -компонент TMyFrame который наследуется непосредственно от TFrame в аналогичный, наследуемый от TBaseFrameComponent. |