“控件''没有父窗口”错误

问题描述 投票:3回答:3

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

  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。”

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

delphi delphi-xe
3个回答
0
投票

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

UNIT cAssociateExt;

INTERFACE

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

TYPE
  TAssociateFileExt = class(TGroupBox)
  private
  protected
  public
    btnAssociate   : TButton;
    btnAssociateDel: TButton;
    chkAllUsers    : TCheckBox;
    constructor Create(aOwner: TComponent); override;
    procedure AfterConstruction;  override;
    procedure CreateWindowHandle(const Params: TCreateParams); override;
    ...
  published
  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;
 ...
end;

-1
投票

你应该在构造函数中添加这一行:

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

-1
投票

重要说明:在创建组件时,需要在构造函数过程中使用此行以避免“控制没有父窗口”。

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

© www.soinside.com 2019 - 2024. All rights reserved.