Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

Author Topic: TDateTime picker - how to determine if first or last part is focused?  (Read 574 times)

korba812

• Sr. Member
• Posts: 307
TDateTime picker - how to determine if first or last part is focused?
« on: September 21, 2022, 09:03:33 pm »
Hi.
I can check the currently highlighted part of TDateTimePicker with GetSelectedDateTimePart function, I can determine the type of first part with GetDateTimePartFromTextPart(1) function. But how can I check that the last part is highlighted?
Do I have to determine it from properties (Kind, HideDateTimePart, DateDisplayOreder, etc) or is there an easier solution?

Nicole

• Sr. Member
• Posts: 496
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #1 on: September 21, 2022, 11:57:25 pm »
Not sure, what you mean exactly.
Do you think, you can post some screenshots?

DateTimePicker1.Time
and
DateTimePicker1.Date

KodeZwerg

• Hero Member
• Posts: 559
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #2 on: September 22, 2022, 12:39:05 am »
Hi.
I can check the currently highlighted part of TDateTimePicker with GetSelectedDateTimePart function, I can determine the type of first part with GetDateTimePartFromTextPart(1) function. But how can I check that the last part is highlighted?
Do I have to determine it from properties (Kind, HideDateTimePart, DateDisplayOreder, etc) or is there an easier solution?
you should not check for (1), use proper names!
dtpYear, dtpDay, dtpMonth, dtpHour, dtpMinute, dtpSecond, dtpMiliSec

« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

korba812

• Sr. Member
• Posts: 307
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #3 on: September 22, 2022, 12:01:44 pm »
Thanks for the answers, but I want to know if first or last part of date or time is highlighted. See attached image.

Zoran

• Hero Member
• Posts: 1751
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #4 on: September 22, 2022, 12:56:44 pm »
Hi.
I can check the currently highlighted part of TDateTimePicker with GetSelectedDateTimePart function, I can determine the type of first part with GetDateTimePartFromTextPart(1) function. But how can I check that the last part is highlighted?
Do I have to determine it from properties (Kind, HideDateTimePart, DateDisplayOreder, etc) or is there an easier solution?

First, as you can use GetDateTimePartFromTextPart, which is protected, you can also use GetSelectedDateTimePart, which is also protected. Perhaps that is all you need?

Also, about GetDateTimePartFromTextPart, are you sure that it returns what you need?
You should know that what GetDateTimePartFromTextPart(1) returns is not the first visible part; this function is used internally and it serves well for what is needed there, but this might not be what you expect.
For example, when kind property is dtkTime, it will return some date part (not time part, not dtpHour), even though it is not visible (which part exactly it returns, depends on DateDisplayOrder). So, GetDateTimePartFromTextPart(1) will never return dtpHour (and GetDateTimePartFromTextPart(4) will always return dtpHour, it does not matter if hour is displayed or not).

On the other hand, GetSelectedDateTimePart will always return the part which is currently selected.

Zoran

• Hero Member
• Posts: 1751
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #5 on: September 22, 2022, 01:08:32 pm »
And, for completeness only (as I don't think it is what you need here), let me add that there is a dtpoResetSelection option. When this option is set, then the selection will always return to the first visible part when the control receives focus.

korba812

• Sr. Member
• Posts: 307
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #6 on: September 22, 2022, 01:25:27 pm »
So I can't check it easily now?
Could we have a method that returns an array of TDateTimePart that contains the sequential visible items? Then I could check which item (in order) is currently highlighted:
Code: Pascal  [Select][+][-]
1. type
2.   TDateTimeParts = array of TDateTimePart;
3. function TCustomDateTimePicker.GetVisibleParts: TDateTimeParts;
4. ...
5.
then I could check:
Code: Pascal  [Select][+][-]
1. var
2.   VisibleParts: TDateTimeParts;
3. begin
4.   VisibleParts := GetVisibleParts;
5.   if GetSelectedDateTimePart = VisibleParts[0] then
6.     // first focused
7.   ...
8.   if GetSelectedDateTimePart = VisibleParts[Pred(Length(VisibleParts))] then
9.     // last focused
10.

I would like to use TDateTimePicker as an editor control for DBGrid and react appropriately to left / right cursor keys - if first part is selected and left key is pressed then it should finish editing and move focus to previous DBGrid cell. Similarly, in the case of the highlighted last part and the right key.

KodeZwerg

• Hero Member
• Posts: 559
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #7 on: September 22, 2022, 02:13:51 pm »
No you can not, since not all computers have same Time Display Format, in many parts of Europe exemplary Day.Month.Year, you see that it aint "easy".
And however your "array sort order" than may be, it f*cks up due different formats...
I would put a button in that opens a mini-form with just that datetimepicker, present it modal, so you just need to wait that user close form so you can export selection into your database.
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

korba812

• Sr. Member
• Posts: 307
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #8 on: September 22, 2022, 02:49:30 pm »
TDateTimePicker has necessary information internally, also about date format, hidden/visible parts and their order, but this information is not exposed.

rvk

• Hero Member
• Posts: 5017
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #9 on: September 22, 2022, 03:46:30 pm »
Yeah. FSelectedTextPart is declared private (for no apparent reason) so you can't even 'hack' it.

BTW. You can probably hack it if you are in the same unit as TCustomDateTimePicker itself (at least that's the case in Delphi).
But outside the unit there is no way to get to the private parts

Because there is a TCustomDateTimePicker.GetSelectedText which uses FSelectedTextPart, I would expect FSelectedTextPart itself also to be public, or at least protected, but not provate.

The problem with checking every GetSelectedText for the visible parts is that you could have a date as "2011-11-11 11:11:11".
Yeah, good luck checking where GetSelectedText (i.e. "11") got it from

You can just move the FSelectedTextPart from the private to the public part and recompile Lazarus.
After that you can just reach it normally.

Code: Pascal  [Select][+][-]
1.   TCustomDateTimePicker = class(TCustomControl)
2.   // ...
3.   private
4.     // FSelectedTextPart: TTextPart; // <-- remove this one
5.   public
6.     FSelectedTextPart: TTextPart; // <-- add this one
7.     constructor Create(AOwner: TComponent); override;

Just tried it and you can put this in a TTimer just fine:
Code: Pascal  [Select][+][-]
1.   Label1.Caption := Integer(DateTimePicker1.FSelectedTextPart).ToString;

Don't forget to repeat when you update Lazarus

korba812

• Sr. Member
• Posts: 307
Re: TDateTime picker - how to determine if first or last part is focused?
« Reply #10 on: September 22, 2022, 05:03:53 pm »
Thanks rvk, but I'll do it the way I mentioned before:
Code: Pascal  [Select][+][-]
1. type
2.   TDateTimePartArray = array of TDateTimePart;
3. ...
4. function TCustomDateTimePicker.GetVisibleDateTimeParts: TDateTimePartArray;
5. begin
6.   Result := [];
7.   case FEffectiveDateDisplayOrder of
8.     ddoMDY: begin
9.       if not (dtpMonth in FEffectiveHideDateTimeParts) then
10.         Result := Concat(Result, [dtpMonth]);
11.       if not (dtpDay in FEffectiveHideDateTimeParts) then
12.         Result := Concat(Result, [dtpDay]);
13.       if not (dtpYear in FEffectiveHideDateTimeParts) then
14.         Result := Concat(Result, [dtpYear]);
15.     end;
16.     ddoDMY: begin
17.       if not (dtpDay in FEffectiveHideDateTimeParts) then
18.         Result := Concat(Result, [dtpDay]);
19.       if not (dtpMonth in FEffectiveHideDateTimeParts) then
20.         Result := Concat(Result, [dtpMonth]);
21.       if not (dtpYear in FEffectiveHideDateTimeParts) then
22.         Result := Concat(Result, [dtpYear]);
23.     end;
24.     ddoYMD: begin
25.       if not (dtpYear in FEffectiveHideDateTimeParts) then
26.         Result := Concat(Result, [dtpYear]);
27.       if not (dtpMonth in FEffectiveHideDateTimeParts) then
28.         Result := Concat(Result, [dtpMonth]);
29.       if not (dtpDay in FEffectiveHideDateTimeParts) then
30.         Result := Concat(Result, [dtpDay]);
31.     end;
32.     otherwise;
33.   end;
34.   if not (dtpHour in FEffectiveHideDateTimeParts) then
35.     Result := Concat(Result, [dtpHour]);
36.   if not (dtpMinute in FEffectiveHideDateTimeParts) then
37.     Result := Concat(Result, [dtpMinute]);
38.   if not (dtpSecond in FEffectiveHideDateTimeParts) then
39.     Result := Concat(Result, [dtpSecond]);
40.   if not (dtpMiliSec in FEffectiveHideDateTimeParts) then
41.     Result := Concat(Result, [dtpMiliSec]);
42.   if not (dtpAMPM in FEffectiveHideDateTimeParts) then
43.     Result := Concat(Result, [dtpAMPM]);
44. end;
45.
Do we need such a feature in the official code (I do, but it doesn't matter )? Should I create an issue in the bug tracker?