Double Click = one Click in TDateEdit, and other key handling problems. lazarus / 31-LCL ---------------------------------------------------------------------- ArminLinder · 2017-01-26 14:57 Hi all, what is the best method to change the default behaviour of the TDateEdit control? Per Default, when the calendar view is dropped down, it does need a double-clik to select a specific day. I want a single click. I tried myself, but is seems like the text field of the control and the dropped down calendar view share common onkey/up/down event handlers, so if I do some stuff tehre I affect both. And onClick fires only in the text field, but not in the calendar view? Asked in a more general way, I am not very happy with the default key handling of the LCL library. I have a similar kind of problem in the ComboBox as well. The Combo drops down a list, from which I can select, but if I hit [Tab] to select the current entry and proceed to the next input, I end up in the ComboBoxe's own text field instead of, like expected, in the next focusabe control on the form. Another issue related is that I'd like to re-map the [Enter] key entirely so that regardless of the focused control this key does always trigger a "Save" button. I can probably overwrite every control's onKey method ans do some magic there to fire up the Button's onClick handler, but isn't there a more global way so that I do this only once for all controls of a form? Any clues welcome, Armin. ---------------------------------------------------------------------- ASerge · 2017-01-26 15:48 Quote from: Nimral on January 26, 2017, 03:57:28 pmPer Default, when the calendar view is dropped down, it does need a double-clik to select a specific day. I want a single click. TDateTimePicker work by one click QuoteI have a similar kind of problem in the ComboBox as well. The Combo drops down a list, from which I can select, but if I hit [Tab] to select the current entry and proceed to the next input, I end up in the ComboBoxe's own text field instead of, like expected, in the next focusabe control on the form. Stay dropdown state in some field. For example in Tag, and do like this Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.ComboBox1DropDown(Sender: TObject);begin  ComboBox1.Tag := 1;end; procedure TForm1.ComboBox1Exit(Sender: TObject);begin  ComboBox1.Tag := 0;end; procedure TForm1.ComboBox1KeyUp(Sender: TObject; var Key: Word;  Shift: TShiftState);begin  if (Key = 9) and (ComboBox1.Tag > 0) then    SelectNext(ComboBox1, not (ssShift in Shift), True);end; QuoteAnother issue related is that I'd like to re-map the [Enter] key entirely so that regardless of the focused control this key does always trigger a "Save" button. I can probably overwrite every control's onKey method ans do some magic there to fire up the Button's onClick handler, but isn't there a more global way so that I do this only once for all controls of a form? Put any button. Set Form.KeyPreview = True and do this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin  if (Key = 13) and (Shift = []) then    Button1.Click;end; ---------------------------------------------------------------------- ArminLinder · 2017-01-26 16:24 Serge, you're my hero, once more :-) If you ever come to Bavaria (Munich area), don't forget do drop me a PM some days before so we can meet and I'll drown you in Bavarian beer and Weißwurst. Greetz Armin. ---------------------------------------------------------------------- ArminLinder · 2017-02-03 09:07 Handling [Return] in a form's OnKeyUp handler seems to have unwanted side effects on messageboxes. My Button.onClick handler has a confirmation dialog (MessageBox, MB_YESNO) at the end, "Do you really want to ....". the onKeyUp code causes and endless loop of messageboxes. I can terminate the messagebox without loop if I use the mouse, or if I press [Space] instead of [Return] in the Messagebox. Seems that, if the user presses [Enter] in the Messagebox, this keystroke goes to the form's onKeyUp handler as well, this causing an endless loop of "Button.click" calls. I made several attempts to fix this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);begin  if (Key = VK_Return) then    if not Flag then      // attempt #4      if Application.ModalLevel = 0 then;     // attempt #2        ButtonSave.Click;end; procedure TForm1.ButtonSaveClick(Sender: TObject);begin// Attempt #3:  if Widgetset.MessageBox(Form1.Handle,PChar('Are you sure you know what you are doing?'),PChar('Please confirm'),MB_YESNO) = idYES then  Self.KeyPreview := false;   // attempt #1  Flag := true;              // Attempt #4  if Application.MessageBox('Are you sure you know what you are doing?','Please confirm',MB_YESNO) = idYES then    StatusBar1.SimpleText:='Then go with it, and live with the consequences'  else   StatusBar1.SimpleText:='better safe than sorry, eh?';  Flag := false;              // Attempt #4  Self.KeyPreview := true;    // attempt #1end; procedure TForm1.FormCreate(Sender: TObject);begin  Flag := false;  // attempt #4end;  But none succeeded. The problem has, in various forms, also hit others who use a form based key handler and a messagebox, like http://stackoverflow.com/questions/28684686/c-builder-how-to-clear- keys-pressed-during-messagebox. Any ideas how I can get my Enter key handler working, and why my attempts to fix the issue didn't work? Thx, Armin. ---------------------------------------------------------------------- balazsszekely · 2017-02-03 09:59 @Nimral If I understood the issue correctly, when the user press the Enter key to close the MessageBox, the FormKeyUp event is fired, which calls again the ButtonSaveClick...and so on. I'm I right? If yes then all you have to do is declare a boolean variable in the private section, then: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);begin  if FBreakTheLoop then  //add this if  begin    FBreakTheLoop := False;    Exit;  end;  if (Key = VK_Return) then    ButtonSave.Click;end; procedure TForm1.ButtonSaveClick(Sender: TObject);begin  if Application.MessageBox('Are you sure you know what you are doing?','Please confirm',MB_YESNO) = idYES then  begin    FBreakTheLoop := True; //add this line    StatusBar1.SimpleText:='Then go with it, and live with the consequences';      end;  else   StatusBar1.SimpleText:='better safe than sorry, eh?';end; ---------------------------------------------------------------------- Zoran · 2017-02-03 10:19 Quote from: Nimral on February 03, 2017, 08:45:52 amLet's start with TDateTime Picker. It has an annoying behaviour regarding the focus: if you use a date format like dd.mm.yyyy, and leave the control while either the mm or yyyy part is focused, and you [tab] back to the TDateTimePicker control, the focus will return to where the control was left last. Instead, it should always focus the leftmost input field (dd in my example). I am surprised that you find this annoying - I would always prefer this behaviour as it is now - for me it is nice to have DateTimePicker remember where the selection was when I left it. I could easily implement this (when DateTimePicker gets focus, the selected part would be the first item), or I could add a boolean property (I can't think how it should be named), which would control this behaviour. But I will not do it unless you convince me that most people would like this. Now I'm just afraid that you are alone in this, and too many properties which have little use makes mess. You can change the source of datetimepicker.pas - find procedure TCustomDateTimePicker.DoEnter and add line "FSelectedTextPart := 1;", so that it becomes: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TCustomDateTimePicker.DoEnter;begin  inherited DoEnter;  FSelectedTextPart := 1;  Invalidate;end; Quote from: Nimral on February 03, 2017, 08:45:52 amThis seems to be the same in Delphi, there is a workaround described for Delphi (change the DateFormat to dfLong and back to dfShort), see http://stackoverflow.com/questions/23628192/returning-focus-to-first- part-of-delphi-tdatetimepicker-control, but this cannot be done in Lazarus, there is no DateTime Member in TDateTimePicker. I tried variations of this trick with various other members of TDateTimePicker, but none reset the focus to the leftmost field. One way to do such workaround here could be to set this procedure to each DateTimePicker's OnEnter event: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.DateTimePicker1Enter(Sender: TObject);var  Kind: TDateTimeKind;begin  DisableAutoSizing; // prevent flicker  try    Kind := TDateTimePicker(Sender).Kind;    try// yes, you do need both these lines, written in this order, to work for any original kind:    TDateTimePicker(Sender).Kind := dtkTime;      TDateTimePicker(Sender).Kind := dtkDate;    finally      TDateTimePicker(Sender).Kind := Kind;    end;  finally    EnableAutoSizing;  end;end; ---------------------------------------------------------------------- ArminLinder · 2017-02-03 15:57 Hi Zoran, thanks for your valuabele Input, I will build this in my code in a minute. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       TDateTimePicker(Sender).Kind := dtkTime;      TDateTimePicker(Sender).Kind := dtkDate;  (hit me on my forehed really hard, I didn't try this because I was focused on displaying a Date, set the field type to dtkTime didn't come to my mind) Regarding the "keep focus" thing, well, contrary of what you say, I cannot imagine any situation where I'd find it useful, but there is at least one common use (mine ...) where it is an annoyance :-) But there is absolutely no reason to go into discussions about matters of taste, I can get what I want with a minor code change, may others be happy with TDateTime Picker exactly like it is :-) Thanks, Armin. P.S: Workaround tried ... worls exactly like I wanted. ---------------------------------------------------------------------- wittbo · 2019-03-06 13:17 @Zoran: I also find this behaviour annoying, since it happens with BackTab and Tab. I have a simple form to collect appointments using one edit field, one TDateTimePicker for the date and one for the time. After having collected these three Dates for one appointment, the user clicks "Save" and starts the next collection cycle immediatly. And then it is really annoying if the datepicker focus is not the first element. Thanks for the hint you gave. I will change the behaviour of the component. ---------------------------------------------------------------------- Zoran · 2019-03-07 11:35 Okay, you convinced me. I added option dtpoResetSelection, see http://wiki.freepascal.org/Date TimeCtrls_Package#Options:_TDateTimePickerOptions