I had the same problem in Delphi 2007,
with TEdit placed in a modal form called double-click in the grid.
I have done some tests running the same form from TSpeedButton. I noticed that the problem with TEdit appears only when the grid is focused.
after additional tests, the problem seems to be a bug in VCL .
in TCustomGrid.paint there is a call to SetCaretPos, even if the grid is not in active form.
../.. Focused := IsActiveControl; if Focused and (CurRow = Row) and (CurCol = Col) then begin SetCaretPos(Where.Left, Where.Top); Include(DrawState, gdFocused); end; ../..
the above code from TCustomGrid.paint in Grids.pas in this Focused code is set to true, if the grid is the "activeControl" of the parent form, the code does not take into account whether the form is active or not.
then, if the grid should be redrawn, setCaretPos is called with the grid coordinates, causing the error mentioned in the question.
The error is very difficult to notice, because most of the time the carriage simply disappears from the active form, and does not blink around the middle of TEdit.
steps to reproduce the error:
- launch the new VCL application.
- add a TStringGrid to it.
- add the second form to the application only with TEdit.
- return to the main form (unit1) and call form2.showmodal from the DblClick grid event.
that's all: you can start the application and double-click the grid cell. if you drag the modal form from the main form, the grid will need to be redrawn, and then make the carriage disappear from the modal form (or appear in the middle of TEdit, if you're lucky)
So, I think a fix is โโneeded in Grids.pas.
In the excerpt from grid.pas above, I suggest replacing the call to the IsActiveControl function with the call to the new IsFocusedControl function:
// 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;
this fix (made in Delphi2007) worked well for me, but is not guaranteed.
(also do not directly modify VCL units ).