我们在另一个窗口中插入了几个TEdit表单,但是它们的标签直到我改变窗口大小才会显示出来。这只会在Windows Vista / Windows 7上发生。Windows XP则正确显示所有标签。
我已经尝试了重绘/刷新(仅针对TEdit / 整个表单等),但没有结果。
使用Delphi 7。
谢谢你的回答。
错误版本:
正确版本:
代码很快就会添加 :)
我已经尝试了重绘/刷新(仅针对TEdit / 整个表单等),但没有结果。
使用Delphi 7。
谢谢你的回答。
错误版本:
![enter image description here](https://istack.dev59.com/50rio.webp)
![enter image description here](https://istack.dev59.com/WxZRJ.webp)
frame.Refresh;
。但是,在找到适当的刷新位置之前,我尝试了几个位置,这有点棘手。对我有效的地方是,在我选择要在选项面板上显示和物理显示嵌套框架的方法中,在围绕未绘制正确的标签的最内部框架上调用frame.Refresh;
。调用内部框架而不是整个窗口的框架似乎是关键。procedure TButton.CNCtlColorBtn(var Message: TWMCtlColorBtn);
begin
with ThemeServices do
{
if ThemesEnabled then
begin
DrawParentBackground(Handle, Message.ChildDC, nil, False);
// Return an empty brush to prevent Windows from overpainting we just have created.
Message.Result := GetStockObject(NULL_BRUSH);
end
else
}
inherited;
end;
{ Labels no Windows Vista, 7, 8 to Fix the problem, Delphi 7 32 bits }
在FormShow事件中:
var
i : Integer;
begin
For i := 0 to (Form1.ComponentCount - 1) do
begin
If (Form1.Components[i].ClassType = TLabel) then
TLabel(Form1.Components[i]).Refresh;
end;
end;
只需运行这个。
我遇到了同样的问题,但只有在应用程序主题化时才会出现问题。如果取消主题化(即项目->选项->应用程序->外观->默认样式=Windows),它就可以正常工作,不需要刷新或重绘。
似乎与TFrame类有关,因此我想可能是重绘处理程序中的某些内容出了问题(与Invalidate有关)。VCL中的ChangeNotify过程或Windows消息泵中的某些内容可能没有沿着父控件链向上传递,并响应级联重绘,从而回流到“无效”的所有内容。
我尝试过的另一个方法是将主机控件的Visible属性设置为False,然后在下一行将其设置为True:
procedure TFrame1.UpdatePanel;
Panel1.Visible := False;
Panel1.Visible := True;
end;
然后在需要适当绘制的位置调用此方法。
Panel1的所有其他子控件都完美地绘制出来了。如果您的更新发生在修改TEdit或TMemo等子控件的内容时,可能需要缓存文本光标的位置。与寻找问题原因的几个小时相比,这应该是微不足道的。也许查看有问题的控件宿主(如TPanel)上的Visible属性的Setter方法的VCL源代码可以为解决在此情况下Repaint和Refresh似乎无法正常工作的整体问题提供一些见解。
实际上,它比迄今为止提出的任何解决方案都要简单得多。 唯一需要的是响应WM_UPDATEUISTATE消息。 在表单中添加以下过程:
...
protected
procedure WmUpdateUIState(var Msg: TMessage); message WM_UPDATEUISTATE;
...
procedure TForm1.WmUpdateUIState(var Msg: TMessage);
begin
inherited;
Invalidate;
end; { WmUpdateUIState }
完成!
在 Windows 10 64 位上进行了测试。
可以通过创建这样的单元来加快速度:
unit FixAltKeyForm;
interface
uses
Windows, Messages, Classes, Forms;
type
TForm = class(Forms.TForm)
protected
procedure WmUpdateUIState(var Msg: TMessage); message WM_UPDATEUISTATE;
end; { TForm }
implementation
{ TForm }
procedure TForm.WmUpdateUIState(var Msg: TMessage);
begin
inherited;
Invalidate;
end; { WmUpdateUIState }
end.
procedure TForm1.Button1Click(Sender: TObject); var Edit1: TEdit; begin Edit1 := TEdit.Create(Self); with Edit1 do begin Parent := Self; Left := 50; Top := 50; Width := 100; Height := 20; end; end;
这段代码会在点击一个按钮时,在窗体上创建一个TEdit对象,并将其放置在(50,50)的位置,宽度为100,高度为20。 - David Heffernan