"控制''没有父窗口"错误

时间:2014-04-26 20:24:17

标签: delphi delphi-xe

当我将控件放在表单上时出现此错误。 错误出现在这里:

  TAssociateFileExt = class(TGroupBox)
  private
  protected
  public
    btnAssociate   : TButton;
    constructor Create(aOwner: TComponent); override;
  end;

constructor TAssociateFileExt.Create(aOwner: TComponent);
begin
 inherited Create(aOwner);
 Caption:= '';                       <-------- error here
 ClientHeight:= 125;                 <-------- and here
 ClientWidth := 170;
 DoubleBuffered:= TRUE;

 btnAssociate:= TButton.Create(Self);
 btnAssociate.Parent:= Self;
 btnAssociate.Visible:= TRUE;
 btnAssociate.Left:= 17;
 btnAssociate.Top:= 26;
 btnAssociate.Width:= 142;
 btnAssociate.Height:= 25;
 btnAssociate.Hint:= 'Associate this application with its files. When you double click a file this program will automatically start and load that file.';
 btnAssociate.Caption:= 'Associate';
 btnAssociate.DoubleBuffered:= TRUE;
 btnAssociate.ParentDoubleBuffered:= FALSE;
 btnAssociate.TabOrder:= 0;
 btnAssociate.OnClick:= btnAssociateClick;

 btnAssociateDel:= TButton.Create(Self);
 btnAssociateDel.Parent:= Self;
 btnAssociateDel.Visible:= TRUE;
 btnAssociateDel.Left:= 17;
 btnAssociateDel.Top:= 53;
 btnAssociateDel.Width:= 142;
 btnAssociateDel.Height:= 25;
 btnAssociateDel.Hint:= 'Remove association';
 btnAssociateDel.Caption:= 'Remove association';
 btnAssociateDel.DoubleBuffered:= TRUE;
 btnAssociateDel.ParentDoubleBuffered:= FALSE;
 btnAssociateDel.TabOrder:= 1;
 btnAssociateDel.OnClick:= btnAssociateDelClick;

 chkAllUsers:= TCheckBox.Create(Self);
 chkAllUsers.Parent:= Self;
 chkAllUsers.Visible:= TRUE;
 chkAllUsers.Left:= 31;
 chkAllUsers.Top:= 97;
 chkAllUsers.Width:= 115;
 chkAllUsers.Height:= 17;
 chkAllUsers.Hint:= 'Please note that if you want to do this for all users then you need administrator/elevated rights.';
 chkAllUsers.Caption:= 'Do this for all users';
 chkAllUsers.DoubleBuffered:= TRUE;
 chkAllUsers.ParentDoubleBuffered:= FALSE;
 chkAllUsers.TabOrder:= 2;
 chkAllUsers.OnClick:= chkAllUsersClick;
end;

答案可能是'标题需要有效的窗口句柄'。对?但是,David Intersimone(here)的一篇文章说可以在构造函数中设置Caption。

  1. 文章错了吗?
  2. 我应该在CreateWnd中移动代码(Caption和TButton.Create)(因为AfterConstruction不是一个好地方)?问题是可以多次调用CreateWnd:“首次创建控件时或者必须销毁并重新创建底层屏幕对象以反映属性更改时,会自动调用CreateWnd。”

  3. 更新:
    (aOwner:TComponent)(如J ...建议)添加到构造函数的声明(在实现中)后,错误移到下一行(clientheight:= 90);

3 个答案:

答案 0 :(得分:0)

我在CreateWindowHandle中移动了代码。现在它有效。 完整代码:

UNIT cAssociateExt;

INTERFACE

USES
  Windows, Messages, SysUtils, Classes, Controls, ExtCtrls, Forms, StdCtrls;

TYPE
  TAssociateFileExt = class(TGroupBox)
  private
    FFileType: string;
    FAssocName: string;
  protected
  public
    btnAssociate   : TButton;
    btnAssociateDel: TButton;
    chkAllUsers    : TCheckBox;
    constructor Create(aOwner: TComponent); override;
    procedure AfterConstruction;  override;
    procedure CreateWindowHandle(const Params: TCreateParams); override;

    procedure chkAllUsersClick  (Sender: TObject);
    procedure btnAssociateClick (Sender: TObject);
    procedure btnAssociateDelClick(Sender: TObject);
  published
    property FileType : string read FFileType  write FFileType;                                    { Example:   FileType:= '.txt'  }
    property AssocName: string read FAssocName write FAssocName;                                   { Example:   Winamp Audio File  }
  end;


procedure Register;


IMPLEMENTATION


procedure TAssociateFileExt.AfterConstruction;
begin
 inherited;         //Not a good place here
end;


procedure TAssociateFileExt.CreateWindowHandle(const Params: TCreateParams);
begin
 inherited;

 //DO NOT CREATE CONTROLS HERE! See: Sertac Akyuz's comment

 Caption:= '';    
 ClientHeight:= 125;
 ClientWidth := 170;
end;



constructor TAssociateFileExt.Create(aOwner: TComponent);
begin
 inherited Create(aOwner);
 DoubleBuffered:= TRUE;

 btnAssociate:= TButton.Create(Self);
 btnAssociate.Parent:= Self;
 btnAssociate.Visible:= TRUE;
 btnAssociate.Left:= 17;
 btnAssociate.Top:= 26;
 btnAssociate.Width:= 142;
 btnAssociate.Height:= 25;
 btnAssociate.Hint:= 'Associate this application with its files. When you double click a file this program will automatically start and load that file.';
 btnAssociate.Caption:= 'Associate';
 btnAssociate.DoubleBuffered:= TRUE;
 btnAssociate.ParentDoubleBuffered:= FALSE;
 btnAssociate.TabOrder:= 0;
 btnAssociate.OnClick:= btnAssociateClick;

 btnAssociateDel:= TButton.Create(Self);
 btnAssociateDel.Parent:= Self;
 btnAssociateDel.Visible:= TRUE;
 btnAssociateDel.Left:= 17;
 btnAssociateDel.Top:= 53;
 btnAssociateDel.Width:= 142;
 btnAssociateDel.Height:= 25;
 btnAssociateDel.Hint:= 'Remove association';
 btnAssociateDel.Caption:= 'Remove association';
 btnAssociateDel.DoubleBuffered:= TRUE;
 btnAssociateDel.ParentDoubleBuffered:= FALSE;
 btnAssociateDel.TabOrder:= 1;
 btnAssociateDel.OnClick:= btnAssociateDelClick;

 chkAllUsers:= TCheckBox.Create(Self);
 chkAllUsers.Parent:= Self;
 chkAllUsers.Visible:= TRUE;
 chkAllUsers.Left:= 31;
 chkAllUsers.Top:= 97;
 chkAllUsers.Width:= 115;
 chkAllUsers.Height:= 17;
 chkAllUsers.Hint:= 'Please note that if you want to do this for all users then you need administrator/elevated rights.';
 chkAllUsers.Caption:= 'Do this for all users';
 chkAllUsers.DoubleBuffered:= TRUE;
 chkAllUsers.ParentDoubleBuffered:= FALSE;
 chkAllUsers.TabOrder:= 2;
 chkAllUsers.OnClick:= chkAllUsersClick;
end;


procedure TAssociateFileExt.chkAllUsersClick(Sender: TObject);
begin
 btnAssociate   .ElevationRequired:= chkAllUsers.Checked;
 btnAssociateDel.ElevationRequired:= chkAllUsers.Checked;
end;


procedure TAssociateFileExt.btnAssociateClick(Sender: TObject);
begin
 if AssocName= ''
 then AssocName:= Application.ExeName;

 if AssociateWith(FileType, AssocName, chkAllUsers.Checked, TRUE)
 then MesajInfo('The program will now automatically start when you double click a '+ FileType+ ' file.')
 else
    if chkAllUsers.Checked AND NOT AppHasAdminRights
    then MesajInfo('On Windows Vista/7 you need to run the program with administrator rights in order to set file association for ALL users in the system!');
end;


procedure TAssociateFileExt.btnAssociateDelClick(Sender: TObject);
begin
 if AssociationReset(FileType, chkAllUsers.Checked)
 then MesajInfo('Association removed.')
 else MesajInfo('Cannot delete file association.');
end;


procedure Register;
begin
  RegisterComponents('Samples', [TAssociateFileExt]);
end;

end.

答案 1 :(得分:-1)

您应该在构造函数中添加以下行:

constructor TAssociateFileExt.Create(aOwner: TComponent);
begin
 inherited Create(aOwner);
 Parent := aOwner;     <--- this line
 Caption:= '';
 ....
end;

答案 2 :(得分:-1)

重要: 在创建组件时,您需要在构造函数过程中使用这一行,以避免&#34;控件没有父窗口&#34;。

继承Create(AOwner);  父:= TWinControl(AOwner);