我想创建一个从TPanel派生的自定义控件,其中包含一个图像和一堆其他控件.编写代码后,我的程序中有一些奇怪的行为.我意识到一些应该在TDisplay.Resize(override)中初始化的变量从未被初始化,因为从未执行过Resize.
为了"解决它",我在一个表单上放了一个按钮并调用了LoadSample函数,该函数调用ClientHeight,它第一次调用Resize!
constructor TDisplay.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Ready := FALSE;
Parent := Owner as TWinControl;
Width := 200;
Height := 86;
Color := clSilver;
Caption := '';
DoubleBuffered:= TRUE;
InternalDisplay:= TImage32.Create(Self);
with Display DO
begin
Parent := Self;
Bitmap.Width := 1;
Bitmap.Height := 1;
RepaintMode := rmOptimizer;
Align := alClient;
SetupBitmap(TRUE, clBlack32);
Visible := TRUE;
OnMouseDown := DMouseDown;
end;
...
end;
Run Code Online (Sandbox Code Playgroud)
更新:
在我在运行时手动调整表单(控件)之前,InternalDisplay也不会与其父级大小对齐.只有这样它才会按照它应该采取的行动(与alClient保持一致).
更新2:
Resize声明如下:procedure Resize; 覆盖;
更新3:
我从我的construnctor中删除了ClientHeight行并将其移到此处:
procedure TDisplay.LoadSample(VAR Obj: TMySample; CONST bReleaseOnExit: boolean)
begin
ClientHeight; <--------- this will call Resize for the first time and my code will be finally initialized. But until this point my display will look odd because the code was never initialized. So the user will see weird stuff until it pushes the 'LoadSample' button.
more code here....
end;
Run Code Online (Sandbox Code Playgroud)
更新4:
我使用了大卫建议的HandleNeeded,它解决了初始化问题.但是,除非我手动调整表单/控件的大小,否则Image仍然不会与整个客户区对齐.
更新5
继续这里,正如大卫建议:TImage将不会与父母对齐
您的控件来自TWinControl,并响应消息TWinControl调用.因此,除非已创建控件的窗口句柄,否则不会调用它.ResizeWM_SIZEResize
Resize在分配时Height,或者实际上Width因为尚未分配窗口句柄时,不会调用该方法.
评估ClientHeight属性时,会导致创建窗口句柄,然后Resize调用.那是因为看起来像这样的GetClientHeight电话GetClientRect:
function TWinControl.GetClientRect: TRect;
begin
Winapi.Windows.GetClientRect(Handle, Result);
end;
Run Code Online (Sandbox Code Playgroud)
这Handle是强制窗口句柄存在的属性的评估.
| 归档时间: |
|
| 查看次数: |
1528 次 |
| 最近记录: |