Recent

Author Topic: [SOLVED] Any way to Exit a control when form is clicked?  (Read 3023 times)

egsuh

  • Hero Member
  • *****
  • Posts: 1273
[SOLVED] Any way to Exit a control when form is clicked?
« on: October 05, 2020, 08:49:16 am »
Let's assume that I have a TMEMO in a form.  When I click the TMemo, TMemo.OnEnter is called. But OnExit is not called when I click on the vacant area of the form which contains the TMemo. OnExit is called when I click on another control in the same form.

Is there anyway that I can make the OnExit event handler is called when I click on the form?
« Last Edit: October 10, 2020, 12:45:30 am by egsuh »

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: Any way to Exit a control when form is clicked?
« Reply #1 on: October 05, 2020, 09:11:43 am »
OnExit is only triggered when it's losing focus. Clicking the form does not make the Memo to lose focus. Clicking other control (on the same form) will make that control to receive focus and that will send a signal to the Memo to trigger the OnExit.

Can you explain more detail why you need to trigger the event when user click the form?

-edit-
You can make form click to trigger Memo.OnExit. Try this code:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Memo1: TMemo;
  17.     procedure FormClick(Sender: TObject);
  18.     procedure Memo1Exit(Sender: TObject);
  19.   end;
  20.  
  21. var
  22.   Form1: TForm1;
  23.  
  24. implementation
  25.  
  26. {$R *.lfm}
  27.  
  28. { TForm1 }
  29.  
  30. procedure TForm1.Memo1Exit(Sender: TObject);
  31. begin
  32.   Caption := Random(100).ToString;
  33. end;
  34.  
  35. procedure TForm1.FormClick(Sender: TObject);
  36. begin
  37.   Memo1Exit(Self);
  38. end;
  39.  
  40. end.
« Last Edit: October 05, 2020, 09:21:54 am by Handoko »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Any way to Exit a control when form is clicked?
« Reply #2 on: October 05, 2020, 09:23:48 am »
Add a handler for the form's OnClick event which does this:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormClick(Sender: TObject);
  2. begin
  3.   if Memo.Focused then Memo.PerformTab(True); { Or False to go backwards }
  4. end;

It will move the focus away from the memo and trigger its OnExit event. Note that for it to work there must be some other focusable control in the form, say, a button or alike; otherwise PerformTab will do nothing.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

egsuh

  • Hero Member
  • *****
  • Posts: 1273
Re: Any way to Exit a control when form is clicked?
« Reply #3 on: October 05, 2020, 09:57:58 am »
Quote
Can you explain more detail why you need to trigger the event when user click the form?
What I need is to store the content of controls whenever it is changed.  I'm looking for the most secure way. Practically exiting control may happen in many cases .. by directly entering into another control, clicking on a form, closing the form by clickicking on the small x button, or closing form by pressing Alt-F4, etc. Just want to know any event that will be called everytime.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Any way to Exit a control when form is clicked?
« Reply #4 on: October 05, 2020, 10:22:56 am »
You could maybe harness your controls' OnEditingDone event.

egsuh

  • Hero Member
  • *****
  • Posts: 1273
Re: Any way to Exit a control when form is clicked?
« Reply #5 on: October 05, 2020, 11:44:13 am »
Quote
You could maybe harness your controls' OnEditingDone event.

Nothing is 100% reliable. I'll search for other methods.

Sieben

  • Sr. Member
  • ****
  • Posts: 310
Re: Any way to Exit a control when form is clicked?
« Reply #6 on: October 05, 2020, 12:14:20 pm »
Very often you will have to watch more than a single event to cover all situations. But in most cases you need to write just one handler since most of them are simple TNotifyEvents. Stop searching for THE EVENT...
Lazarus 2.2.0, FPC 3.2.2, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

BrunoK

  • Sr. Member
  • ****
  • Posts: 452
  • Retired programmer
Re: Any way to Exit a control when form is clicked?
« Reply #7 on: October 05, 2020, 01:58:09 pm »
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Memo1: TMemo;
  16.     procedure FormClick(Sender: TObject);
  17.     procedure FormShow(Sender: TObject);
  18.     procedure Memo1Enter(Sender: TObject);
  19.     procedure Memo1Exit(Sender: TObject);
  20.   private
  21.     FDummyWinC: TWinControl;
  22.     procedure DummyWinCEnter(Sender: TObject);
  23.   public
  24.  
  25.   end;
  26.  
  27. var
  28.   Form1: TForm1;
  29.  
  30. implementation
  31.  
  32. {$R *.lfm}
  33.  
  34. { TForm1 }
  35.  
  36. procedure TForm1.FormShow(Sender: TObject);
  37. begin
  38.   if not Assigned(FDummyWinC) then begin
  39.     FDummyWinC := TWinControl.Create(Self);
  40.     FDummyWinC.Parent := Self;
  41.     FDummyWinC.SetBounds(0,0,0,0);
  42.     FDummyWinC.OnEnter:=@DummyWinCEnter;
  43.  
  44.     { If it has to respond to TAB, include next 2 lines }
  45.     FDummyWinC.TabStop := true;
  46.     FDummyWinC.TabOrder:=Memo1.TabOrder+1;
  47.   end;
  48. end;
  49.  
  50. procedure TForm1.FormClick(Sender: TObject);
  51. begin
  52.   FDummyWinC.SetFocus;
  53. end;
  54.  
  55. procedure TForm1.Memo1Enter(Sender: TObject);
  56. begin
  57.   Memo1.Lines.Add('Entered:'+FormatDateTime('hh:nn:ss',now));
  58. end;
  59.  
  60. procedure TForm1.Memo1Exit(Sender: TObject);
  61. begin
  62.   Memo1.Lines.Add('Exited:'+FormatDateTime('hh:nn:ss',now));
  63. end;
  64.  
  65. procedure TForm1.DummyWinCEnter(Sender: TObject);
  66. begin
  67.   FDummyWinC.PerformTab(True); // Tab to next control
  68. end;
  69.  
  70. end.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Any way to Exit a control when form is clicked?
« Reply #8 on: October 05, 2020, 04:42:35 pm »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.DummyWinCEnter(Sender: TObject);
  2. begin
  3.   FDummyWinC.PerformTab(True); // Tab to next control
  4. end;

If you're going to do that you might just as well do it as I wrote before, making the memo do PerformTab(). You simply introduced a "phantom" control in the "focus" chain and doing it this way you might accidentally find yourself "tabing" back to the memo, depending on the controls's tab order. And it also complicates the program unneccesarily.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

BrunoK

  • Sr. Member
  • ****
  • Posts: 452
  • Retired programmer
Re: Any way to Exit a control when form is clicked?
« Reply #9 on: October 05, 2020, 06:08:21 pm »
If you're going to do that you might just as well do it as I wrote before, making the memo do PerformTab(). You simply introduced a "phantom" control in the "focus" chain and doing it this way you might accidentally find yourself "tabing" back to the memo, depending on the controls's tab order. And it also complicates the program unneccesarily.
Tested on Win10 :
If the only control on the form is the Memo then MemoExit is not called.

wp

  • Hero Member
  • *****
  • Posts: 11855
Re: Any way to Exit a control when form is clicked?
« Reply #10 on: October 05, 2020, 06:32:47 pm »
I think it is not a very user-friendly concept to change the focus when a click on the form occurs, this is against all conventions and the users will become very frustrated.

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: Any way to Exit a control when form is clicked?
« Reply #11 on: October 05, 2020, 07:13:45 pm »
Tested on Win10 :
If the only control on the form is the Memo then MemoExit is not called.

Yes, I said that too but, frankly, if the memo is the only control and all that is needed is to trigger its OnExit event one might as well call the handler directly from the form's OnClick one.

In fact, from the OP's  description:
What I need is to store the content of controls whenever it is changed.  I'm looking for the most secure way. Practically exiting control may happen in many cases .. by directly entering into another control, clicking on a form, closing the form by clickicking on the small x button, or closing form by pressing Alt-F4, etc. Just want to know any event that will be called everytime.
what I would do is to add a "SaveMemo" method to the form and call from whatever event(s) it should be called or, anyway, from the form's OnCloseQuery handler, when you know the contents are finally fixed.

I have got a program, kind of a "notes to self/things to remember" pad, which needs to do something similar and one of the options I looked into for an "auto-save" feature was to intercept the <Enter> key (in the memo's OnKeyUp event) and save the contents then, but I finally realized it was a futile exercise and what I did was to use a TXMLPropStorage to store some session properties and to save/load the memo contents using its events. After a few false starts (first time I ever used that component) all was a piece of cake compared to, say, dealing with the shortcomings of TMemo ;D
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Handoko

  • Hero Member
  • *****
  • Posts: 5130
  • My goal: build my own game engine using Lazarus
Re: Any way to Exit a control when form is clicked?
« Reply #12 on: October 05, 2020, 07:33:29 pm »
If the OP's intention is to save the user provided values to disk, I think it should not be performed if user simply clicks on the form.

When providing value on a textbox or memo I might clicking the form several times but that does not mean I already finish with that item. For example, after typing some text, I forget and need to do some copy/paste something from other applications. That could be a web browser, help file or my personal-saved text files. And I always have multiple applications running and showing on my screen. So I may need to click on the form to bring the application to the front, move the form a better location on the screen, the go back and continue providing the value for the textbox.
« Last Edit: October 05, 2020, 07:35:45 pm by Handoko »

egsuh

  • Hero Member
  • *****
  • Posts: 1273
Re: Any way to Exit a control when form is clicked?
« Reply #13 on: October 09, 2020, 04:10:39 pm »
I found this issue was discussed in StackOverflow, and found that simplest way is to write

    Self.ActiveControl := nil;

which will call the OnExit procedure of focused control.  I tested this, and reliable --- this calls OnExit event of focused control when I press other tab, or close the Windows by clicking F4 or samll x of the window (on Windows 10).

But I cannot do this in Frame. There are no ActiveControl in Frame. Is there any work-around?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Any way to Exit a control when form is clicked?
« Reply #14 on: October 09, 2020, 05:31:36 pm »
ActiveControl is a TCustomForm property.
So you could try
Code: Pascal  [Select][+][-]
  1. ParentForm.ActiveControl := Nil;

 

TinyPortal © 2005-2018