假设您有一个可以向左展开以显示其他控件的表单:
折叠:
扩展:
在 Delphi 中实现这一点的最简单方法是使用alRight
作为所有控件的主要锚点(而不是alLeft
),然后只需调整表单的宽度和 X 坐标即可。您可以设置Width
and Left
单独属性,或者您可以使用同时设置它们的函数,例如
if FCollapsed then
SetWindowPos(Handle, 0, Left - Width, Top, 2 * Width, Height, 0)
else
SetWindowPos(Handle, 0, Left + Width div 2, Top, Width div 2, Height, 0)
问题问题是,在展开或折叠时,表单始终可见的部分(在本例中为按钮)存在相当明显的闪烁。自己尝试一下吧!
操作系统可以将窗体的大小向左调整而不会出现任何闪烁——只需使用鼠标抓住窗体的左边缘并向左或向右拖动鼠标即可——但我找不到任何闪烁Windows API 中的函数公开了这种大小调整。
我尝试过使用几种不同的 Windows API 函数来调整表单的大小和位置,尝试了它们的各种参数(例如,SWP_*
标志),尝试过LockWindowUpdate
, WM_SETREDRAW
, TForm.DoubleBuffered
等等都无济于事。我还研究了使用的可能性WM_SYSCOMMAND
SC_SIZE
方法。
我还不确定问题是出在操作系统层面还是VCL层面。
有什么建议么?
Edit:我很惊讶地看到这个问题获得了接近的票数。让我尝试澄清一下:
创建一个新的 VCL 表单应用程序。
-
在主窗体的右侧添加一些按钮,并在左侧添加一个备忘录。放Anchors
to [alTop, alRight]
on all控制。上OnClick
按钮的处理程序,添加以下代码:
if FCollapsed then
SetWindowPos(Handle, 0, Left - Width, Top, 2 * Width, Height, 0)
else
SetWindowPos(Handle, 0, Left + Width div 2, Top, Width div 2, Height, 0);
FCollapsed := not FCollapsed;
where FCollapsed
是表单的私有布尔字段(初始化为false
).
Now, click the buttons repeatedly. (Or give one of them keyboard focus and hold the Enter key for a few seconds.) You will probably notice that the region with the buttons on your monitor will not display a perfect still image, but will flicker. In addition, you might actually see 'ghosts' of the buttons to the left of the actual column of buttons.
我无法使用屏幕捕获来捕获这种毫秒闪烁,因此我使用数码相机来记录我的屏幕:
https://privat.rejbrand.se/VCLFormExpandFlicker.mp4
在此视频剪辑中,很明显,按钮列不是屏幕上的静态图像;而是一列按钮。相反,每次调整表单大小时都会有几毫秒的时间,该区域会出现不正常的情况。同样明显的是,左侧有一列“幽灵”按钮。
我的问题是是否有任何相当简单的方法来消除这些视觉伪影(至少对我来说,即使您一次展开/折叠表单,这些视觉伪影也是非常明显的)。
在我工作的 Windows 10/Delphi 10.1 计算机上,当我使用鼠标拖动窗体的最左边缘时,窗体会以完美的方式调整大小:窗体的未受影响的客户区域在显示器上完全静态。然而,在我家里的 Windows 7/Delphi 2009 PC 上,我确实看到当我执行此操作时会发生很多重新定位。