8

I have a form in an application written using FireMonkey. On that (modal) form there's an OK button for which I have set Default property to True. There's also a memo component. Now if type press enter while typing in the memo, then the form is closed instead of inserting line break into memo.

What I would like to accomplish, is that when enter (or shift+enter or smth like that) is pressed in memo component, then line break is enter. In other components, where you cannot type line breaks, I would still like hitting enter to close the form. The best I have found thus far is adding following code into forms OnCloseQuery action:

if (Focused.GetObject.ClassName = 'TMemo') and (ModalResult = mrOk) then
begin
  CanClose := False;
  Memo := TMemo(Focused.GetObject);
  Memo.InsertAfter(Memo.CaretPosition, sLineBreak, [TInsertOption.ioMoveCaret,
    TInsertOption.ioCanUndo]);
end
else
  CanClose := True;

This works, but there's now there's a small annoying delay after hitting enter and before the line break appears. Also I would like solution, that would be less hacky.

I should also point out, that I also have forms which contain the OK button, but not the memo component, however a memo will be moved to that form at runtime by changing its parent property.

Avo Muromägi
  • 1,563
  • 1
  • 12
  • 21
  • 1
    Try `Memo.Lines.BeginUpdate;` before changing Memo content and `Memo.Lines.EndUpdate;` after that. – Abelisto Mar 16 '13 at 10:53
  • 3
    Emba missed to implement TMemo WantReturns, WantTabs properties :o( I would use an OnIdle Event on the form to check if there is a focused TMemo to set the Default property. But Emba also have no TApplicationEvent for FMX :o( Only TActionList has OnUpdate Event which fired on idle if at least one action is defined and assigned to a control – Sir Rufo Mar 16 '13 at 11:19
  • 1
    In your default button `OnClick` event, test if the memo is focused and set `ModalResult` to mrNone if that is the case. – LU RD Mar 16 '13 at 11:31
  • @LURD The problem is caused by TButton.Default := True so pressing RETURN has no effect on TMemo. If TButton.ModalResult is set, there is no need for an OnClick event – Sir Rufo Mar 16 '13 at 11:35
  • @SirRufo, you are correct, my mistake. – LU RD Mar 16 '13 at 11:39
  • @Abelisto BeginUpdate/EndUpdate was a good idea I failed to try, but unfortunately delay comes from somewhere else (code in OK buttons event handler). – Avo Muromägi Mar 16 '13 at 12:28
  • @LURD I tried your advice and I realized that delay actually was caused by the code in OnClick event handler and by checking the focused item type I can now skip the code that caused the delay if memo is focused. So basically the delay issue is resolved. Thanks! – Avo Muromägi Mar 16 '13 at 12:38
  • 2
    That has to be an FMX bug. When the memo has focus, it should consume the ENTER key press. – David Heffernan Mar 16 '13 at 14:12

1 Answers1

2

Set btnOk.Default to False in your memo's OnEnter, and back to True in the memo's OnExit

iMan Biglari
  • 4,674
  • 1
  • 38
  • 83
  • It's not always that easy. I have forms where memo is on another form that is embedded into form with the OK button (like in http://stackoverflow.com/a/9048640/721309). Therefore sometimes memo has no way of knowing whether there's a button. – Avo Muromägi Mar 17 '13 at 18:25
  • 1
    In that case, you could create a descendant of `TMemo` which searches through its parent's controls for a button with `Default` set to `True`, and set it to `False` in the `CMEnter()` method, and back to `True` in `CMExit()` – iMan Biglari Mar 18 '13 at 07:59