Why are carriages suddenly focused in the edit box?

I have a TEdit "username" in the Delphi 2006 login form. When the application starts, the user is prompted for a username. TEdit gets focus, and for some reason, the carriage is placed in the horizontal center. As soon as something is typed, the carriage is aligned again, and everything looks fine.

It is also strange that this was not always the case. This behavior suddenly started a few years ago (I believe that we were still using Delphi 6 at that time). Any idea what could be causing this?

Additional information (was proposed):

The problem is widespread: D2006 and D6 (I believe), 5 or 6 Delphi instances on as many computers as all applications using this login form. The effect is limited in form, however, it is not found on other TEdits. TEdit is not filled with spaces (which would be strange to do first).
Additional information (November 13): The carriage is not centered exactly, it is almost centered. Currently, this only happens in the DLL. The same login dialog is used in regular executables and does not show a problem there (although I believe this happened at some time). An edit field is a password change, the OnChange handler sets only an integer field of this form, there are no other event handlers in this edit field. I added another simple TEdit, which is also an ActiveControl, so that it has focus when the form is displayed (as it was with the password change). I also deleted the default text "Edit1". Now the problem in this TEdit is similar. The "centered" carriage returns to normal if either a character is entered, or if I insert controls - when I return to TEdit, it looks fine. It was the same with a password change.
+4
source share
5 answers

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 ).

+2
source

A few additional questions:

  • Is this a problem on one PC or on other PCs?
  • Does this happen in one application or in all applications?
  • Does this happen only in Delphi applications or in all applications?

If it is only on one PC, I think this is a strange registry setting. If there is more on the computer, but you have only one delphi development processor, it can still be a registry parameter. But there are other possibilities.

You can try several tests:

  • Create a simple application on your computer and run it on another. Does this mean an effect.
  • Use an application created by Delphi, but built on another PC that does not show the effect, and runs it on the dev computer, does this show the effect?

I really think this is a registry setting. According to the information you gave me, this happened to Delphi 6 and is still happening. It can also be a locale setting, but then it should happen in more programs.

Edit: Thanks for the additional information. Thus, it seems that the problem can be isolated from one form. But this happens on all computers.

What you can do is delete the edit and re-add the new one. This saves the search for strange property values.

  • Are there events on TEdit that can explain the consequences?
  • What property values โ€‹โ€‹are set? (But I prefer to look at dfm and code, because then I can reproduce the effect.)
+1
source

Are you sure this is a simple TEdit? It can be initialized with several spaces instead of an empty string. The onChange handler can then simply remove the spaces as soon as you start typing. The TEdit extension can have text alignment located in the center, not the left, and set text alignment only on onChange.

[edit] Please show the TEdit event handlers.

0
source

I also noticed this behavior in richedits.

One place in our application is a double click on the grid, which displays another screen containing RichEdit. It seems that the carriage appears in Richedit in the same place as double-clicking on the grid, i.e. If dblclick was on the third line of the grid, the carriage will be displayed ~ 3 lines down when editing. As soon as the key is pressed, the carriage is reset to the correct position of the upper left corner.

It is not limited to a specific form or PC, as is the case on all development machines, as well as on client machines. The application was originally developed in Delphi 5, but the problem did not arise (or was not noticed) until we moved to D2006.

This is not a particular problem, just ... annoying.

0
source

Another workaround:

Before showing the second form, do not let the grid in the first form perform the Paint action. Code snippet as shown below.

 Gird.BeginUpdate; try //Show the second form here finally Grid.EndUpdate; end; 
0
source

All Articles