Delphi 如何在构造函数运行后设置CreateParams?

Delphi 如何在构造函数运行后设置CreateParams?,delphi,window,delphi-xe2,vcl,Delphi,Window,Delphi Xe2,Vcl,这不起作用,因为窗口句柄是在TForm的构造过程中创建的,所以CreateParams运行得太早,FAppWindow总是False 编写自定义构造函数也不起作用,因为在将任何数据保存到实例之前,必须最终调用创建句柄的继承构造函数: TForm1 = class(TForm) procedure FormCreate(Sender: TObject); end; TForm2 = class(TForm) private FAppWindow: Boolean;

这不起作用,因为窗口句柄是在TForm的构造过程中创建的,所以
CreateParams
运行得太早,
FAppWindow
总是
False

编写自定义构造函数也不起作用,因为在将任何数据保存到实例之前,必须最终调用创建句柄的继承构造函数:

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

  TForm2 = class(TForm)
  private
    FAppWindow: Boolean;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    property AppWindow: Boolean read FAppWindow write FAppWindow;
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Form2 := TForm2.Create(Self);
  Form2.AppWindow := True;
  Form2.Show;
end;

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited;
  if FAppWindow then begin
    Params.Style := Params.Style or WS_EX_APPWINDOW;
    Params.WndParent := 0;
  end;
end;
有没有办法:

  • 延迟窗口句柄的创建
  • 创建窗口句柄后是否更改窗口样式
  • 在构造函数运行后重新创建窗口句柄
  • 还有什么我还没想到的选择吗

如何从类的“外部”更改窗体的样式?

这似乎可以重新创建句柄,我是从
重新创建一个POUP
VCL方法得到这个想法的:

constructor TForm2.CreateAppWindow(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FAppWindow := True;
end;

最简单的解决方案是将参数传递给构造器中的表单,而不是等到它完成创建

这意味着您需要为
TForm2
引入一个构造函数,该构造函数接受您需要在
CreateParams
中传递的任何信息作为参数


在调用继承的构造函数之前,记下任何状态。此外,当您将所有者设置为零时,无需设置
WS_EX_APPWINDOW

Delphi的优点是派生构造函数不必调用继承的
构造函数作为其第一条语句。因此,您可以先设置
FAppWindow
成员,然后调用
inherited
构造函数来流化DFM并创建窗口,例如:

procedure TForm2.SetAppWindow(const Value: Boolean);
begin
  FAppWindow := Value;
  if HandleAllocated then
    RecreateWnd
  else
    UpdateControlState;
end;

为该属性编写一个setter,它将
重新创建wnd
。或者,如果不想重新创建窗口,可以执行
更改AppWindow
内部过程所做的操作。它通过
SetWindowLong
在一对
ShowWindow
调用中设置样式(
SW\u HIDE
SW\u SHOW
SW\u MINIMIZE
对)。我更喜欢在这里重新创建。在调用inherited之前记下参数。是的,
CreateParented
doe当我尝试类似的方法时,我遇到了访问冲突,但现在它似乎起作用了,很好奇。在某些情况下,
Self
是否可能没有在构造函数中初始化?1)您调用构造函数时没有赋值<代码>TMyClass.Create()而不是
c:=TMyClass.Create()2)使用变量而不是类调用构造函数<代码>c.Create()3)您正在使用尚未初始化的
Self
变量。您可以读取和写入字段,但它们将默认初始化。
procedure TForm1.FormCreate(Sender: TObject);
begin
  Form2 := TForm2.CreateAppWindow(Self);
  Form2.Show;
end;

constructor TForm2.CreateAppWindow(AOwner: TComponent);
begin
  FAppWindow := True;
  inherited Create(AOwner);
end;