Fixing FireMonkey: TMemo/TEdit – OnExit

  

Currently in the Delphi XE3 release there is a bug in the OnExit processing of TMemo and TEdit (possibly others) controls.
Issue
If you make a change in a TEdit or TMemo control and then exit the control, after the OnExit event is called, another OnChange event is called. This shouldn’t happen.
This doesn’t occur in the VCL framework and shouldn’t happen in FireMonkey.
Solution
TEdit
The fix for the TEdit cause is pretty simple. Since the FNeedChange field in TCustomEdit is protected we can use a class cracker to fix it. You could put the fix into either a new control or in either an OnExit or OnChange handler in your application.

type
TEditClass = class(TEdit);

procedure Form1.OnExit(Sender: TObject);
begin
TEditClass(Edit1).FNeedChange := False;
end;

It’s interesting to note for TEdit, FNeedChange is protected. This is because in the TCustomEditBox descendant (used by TSpinBox and TNumberBox controls), the FNeedChange field is set to False after the overriden Change method is called. Perhaps this should have triggered the developer making that change, to actually fix the issue in the ancester class.
TMemo
The fix for TMemo is more interesting because unlike the TCustomEdit class, FNeedChange is private. Thankfully extended RTTI comes into play.
I put this code where the memo content was saved to disk, you could put the code in the same spot in your applications (if applicable), or place it in either OnChange or OnExit events.

var
LCtx: TRTTIContext;
LField: TRttiField;
LInst: TRttiInstanceType;
begin
// save your memo contents
LInst := LCtx.GetType(Memo1.ClassType).AsInstance;
LField := LInst.GetField(‘FNeedChange’);
if LField <> nil then
LField.SetValue(Memo1, False);
end;

If your save is triggered by the user selecting a control that takes focus from the memo, the OnExit event will trigger before executing the fix above. Under these circumstances, moving the fix to the OnExit event of the memo is advised.
Another TMemo Issue
The OnChange event is only triggered after typing two characters in a TMemo, the first character typed into the memo doesn’t trigger the OnChange event.

Comments are closed.