我在 Delphi 2007 中也遇到了同样的问题,
将 TEdit 放置在通过双击 Grid 调用的模态表单中。
我做了一些测试,从 TSpeedButton 启动相同的表单。
我注意到 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 中间附近闪烁。
重现错误的步骤:
- 启动新的 VCL 表单应用程序。
- 将 TStringGrid 添加到其中。
- 向应用添加第二个表单,其中只有一个 TEdit。
- 以主窗体 (unit1) 返回并从网格 DblClick 事件中调用 form2.showmodal。
就是这样:您可以启动应用程序并双击网格单元格。
如果您将模态窗体拖离主窗体,则需要重新绘制网格,然后导致插入符号从模态窗体中消失(或者如果您非常幸运,它会出现在 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)。