我在Delphi 2006登录表单上有一个“用户名”TEdit。当应用程序启动时,系统会要求用户输入用户名。由于某种原因,TEdit得到了焦点并且插入符号位于其水平中心。只要输入任何东西,插入符号就会再次对齐,一切看起来都很正常。
奇怪的是,它并不总是这样。这种行为几年前突然开始(我相信我们当时仍然使用Delphi 6)。知道可能导致这种情况的原因吗?
其他信息(已被要求):
答案 0 :(得分:2)
我在Delphi 2007中也有同样的问题,
将TEdit放在一个模态形式中,双击一个Grid。
我做了一些测试,从TSpeedButton启动相同的Form。 我注意到TEdit的问题只在网格聚焦时出现。
经过多次测试后,问题似乎是VCL中的一个错误 在TCustomGrid.paint中有一个SetCaretPos调用,即使网格不在活动表单上。
../..
Focused := IsActiveControl;
if Focused and (CurRow = Row) and (CurCol = Col) then
begin
SetCaretPos(Where.Left, Where.Top);
Include(DrawState, gdFocused);
end;
../..
上面的代码来自Grids.pas中的TCustomGrid.paint 在此代码中,如果网格是父窗体的“activeControl”,则Focused设置为true,如果窗体处于活动状态,则代码不会考虑。
然后,如果需要重新绘制网格,则使用网格坐标调用setCaretPos,从而导致问题中提到的错误。
这个错误很难被注意到,因为大多数时候,插入符只是从活动形式中消失而不是在TEdit中间附近闪烁。
重现错误的步骤:
这就是全部:您可以启动应用程序并双击网格单元格。 如果您将模态窗体拖离主窗体,则需要重新绘制网格,然后使插入符从模式窗体中消失(或者如果您非常幸运,则显示在TEdit的中间)
所以,我认为在Grids.pas中需要修复。
在上面的grid.pas的摘录中,我建议通过调用一个名为IsFocusedControl的新函数来替换函数IsActiveControl的调用:
// new function introduced to fix a bug
// this function is a duplicate of the function IsActiveControl
// with a minor modification (see comment)
function TCustomGrid.IsFocusedControl: Boolean;
var
H: Hwnd;
ParentForm: TCustomForm;
begin
Result := False;
ParentForm := GetParentForm(Self);
if Assigned(ParentForm) then
begin
if (ParentForm.ActiveControl = Self) then
//Result := True; // removed by DamienD
Result := ParentForm.Active; // added by DamienD
end
else
begin
H := GetFocus;
while IsWindow(H) and (Result = False) do
begin
if H = WindowHandle then
Result := True
else
H := GetParent(H);
end;
end;
end;
此修复程序(在Delphi2007中制作)对我来说效果很好,但不保证。
(另外,do not modify directly units of the VCL)。
答案 1 :(得分:1)
另外几个问题:
如果它只在一台电脑上,我认为这是一个奇怪的注册表设置。如果它在更多的PC上,但你只有一个delphi开发的PC,它仍然可能是一个注册表设置。但还有其他可能性。
您可以尝试一些测试:
我真的认为这是一个注册表设置。根据你给我的信息,它发生在自Delphi 6以来,并且仍在发生。 它也可以是一个语言环境设置,但它必须在更多的程序中发生。
修改强> 感谢您的额外信息。 因此看起来问题可以被隔离到单个表单。但它发生在所有电脑上。
您可以做的是删除编辑,然后重新添加新编辑。这样可以节省搜索奇怪的属性值。
答案 2 :(得分:0)
你确定它是一个简单的TEdit吗?它可能用几个空格而不是空字符串初始化。然后onChange处理程序可能会在您开始键入时立即删除空格。 TEdit扩展名可能在居中而不是左侧设置文本对齐方式,并且仅在onChange上设置文本对齐方式。
[编辑] 请显示TEdit的事件处理程序。
答案 3 :(得分:0)
我也注意到了richedits中的这种行为。
我们的应用中的一个地方是双击网格,显示另一个包含RichEdit的屏幕。插入符号总是出现在Richedit中与双击网格的位置相同,即如果dblclick位于网格的第3行,则插入符号将在编辑时显示~3行。一旦按下一个键,插入符就会重置到左上角的正确位置。
它不仅限于某种形式或个人电脑,因为它发生在所有开发者机器上以及客户机器上。 该应用程序最初是在Delphi 5中开发的,但在我们搬到D2006之前,问题没有发生(或者没有被发现)。
这不是一个特别大的问题,只是......太刺激了。
答案 4 :(得分:0)
另一种解决方法:
在显示第二个表单之前,请阻止第一个表单上的网格执行Paint操作。代码段如下。
Gird.BeginUpdate;
try
//Show the second form here
finally
Grid.EndUpdate;
end;