2011-12-02 55 views
3

我们在其他窗体上插入了很少的TEdit窗体,但它们的标签在我更改窗口大小之前不显示。这种情况只发生在Windows Vista/Windows 7上.Windows XP的所有内容都标有正确的标签。德尔福 - TEdit标签不显示(仅适用于Windows 7/Vista)

我已经测试了重绘/刷新(只是TEdit /所有形式等),没有结果。

德尔福7

谢谢您的回答

坏版本 enter image description here

正确版本 enter image description here

代码将被添加很快:)

+5

什么是TEdit表单? TEdit没有标签。你能给我们一些代码,最好有足够的来源来重现。 –

+1

我和大卫一起感到困惑......你的意思是TLabeledEdit?只有我可以补充说的是,TLabels不是窗口控件,因此会出现在窗口控件后面。如果TLabel不共享与TEdits相同的父代,那么您可能看不到它们。如果这是一个TPanel,他们都坐在你的屏幕截图中,然后确保TLabels在该面板上,而不是形式。 –

+0

你真的插入一个表单到另一个?或者你谈论tFrame-Objects? tFames是非常特殊的(或者如果你更喜欢这个词的话,就是bugy)),特别是在旧的Delphi版本中。在该版本中,丑陋的“调整窗口大小后创建”技巧可能是像你这样的问题的最佳解决方法:(。 –

回答

2

我能够在我的项目中解决这个问题。这似乎是一个绘画顺序问题。最终的解决方案是在未正确显示帧的情况下调用frame.Refresh;。但是,找出放置Refresh的正确位置有点棘手,我在尝试了几个地方之后发现了一个可以工作的地方。在我选择的方法中,在选择要在选项面板上显示哪个嵌套框架并物理显示嵌套框架的方法中,请在围绕未正确绘制标签的最内层框架上调用frame.Refresh;。在内部框架上调用刷新而不是整个窗口的框架似乎是关键。

从您展示的屏幕截图看,您可能看起来像您可能具有类似的复杂框架设置,可能会在框架顶部显示框架,框架最初显示后可能会动态更改框架。这似乎是首先会造成问题的设置,最初显示的框架似乎从来没有出现问题。

但是,有一点需要注意的是,如果窗口离开屏幕或重新调整大小,另一个窗口在其前面拖动,或者正在消失的鼠标悬停按钮是这些操作可能导致问题重新出现 - 自发出现。可能还有其他地方,比如在窗口大小调整等的特殊处理程序中,或者在定时器上定期调用帧的刷新,类似于针对ALT Key错误提及的一些解决方案。似乎是问题,以及如何解决它的种类有一些重叠,但不完全相同的原因(这个bug似乎无论Alt键的情况发生)

0
{ 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; 

只要运行这个。

0

我得到的是同样的东西,除了它似乎只是一个问题,而应用程序是主题。如果它是未知的(即项目 - >选项 - >应用程序 - >外观 - >默认样式= Windows),它工作正常,不需要刷新或重新绘制。

似乎与TFrame类特别相关,所以我不知道是否有关于重绘处理程序的东西不是amok(与无效相关)。 ChangeNotify进程中的某些内容或VCL中的Windows消息泵可能无法在父控制链上发挥作用,并通过级联重绘来响应“无效”的所有内容。

另外一个cludge我曾尝试与成功是Visible属性设置主机控制为False在一个行,然后到真正的下一行,即:

procedure TFrame1.UpdatePanel; 
    Panel1.Visible := False; 
    Panel1.Visible := True; 
end; 

则调用此方法,其中正确的图纸是需要。

Panel1的所有其他子控件都是完美绘制的。如果在修改其中一个子控件(如TEdit或TMemo)的内容时发生更新,则可能必须缓存文本光标的位置。与寻找问题原因的时间相比,这应该是微不足道的。也许在有问题的控制主机(比如TPanel)上查看Setter方法的Visible属性的VCL源代码可能会提供一些有关重新构建和刷新似乎不起作用的问题,因为它们应该在这种情况下应用。

0

其实它比迄今为止提出的任何解决方案都简单得多。 唯一需要的是响应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. 

添加该单位的名称,以任何形式,其中这种行为被通缉的界面会话的使用条款和你做。只有确保将单位名称放在使用条款中的“表单”后面。不需要创建一个包,也不需要安装任何东西。这就是我称之为Visual Subclassing的原因,因为缺乏更好的术语。