Some problems with CalendarGadget

Everything else that doesn't fall into one of the other PB categories.
Major
New User
New User
Posts: 3
Joined: Fri Apr 25, 2003 5:41 pm
Location: Denmark/Russia
Contact:

Some problems with CalendarGadget

Post by Major »

Huh! This is my first post since i bought PB 3.30. Why first? Because on all my questions i found answers at this fantastic forum. But...

Now i have problems with CalendarGadget.

1. There is not possible to insert year manually, it is necessary to use spinner.
2. The calendar begins with 1752 year. What to happen, if i wish to insert 1223 year? Nothing. The calendar will open on 1970 year.
3. If i wish to tnsert date which is less than 1970 with CalendarGadget(bla-bla-bla,Date(1800,12,22,0,0,0)), the calendar always opens on 1970.

Sorry for my bad English
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

#1. The Edit control has the #ES_READONLY style by default, so no input is accepted. You must use the spinner or up/down keys.

#2.
Platform SDK wrote:The month-calendar control is based on the Gregorian calendar, which was introduced in 1753. It will not calculate dates that are consistent with the Julian calendar that was in use prior to 1753.
#3.
PB Help - PureBasic - Date wrote:The Date library allows to handle Date and Time from 1970 up to 2034, using the unix way (number of seconds elapsed since the 1st January 1970).
Here's a Windows only method for setting CalendarGadget dates to < 1970

Code: Select all

#MCM_FIRST = $1000
#MCM_SETCURSEL = #MCM_FIRST + 2

fTime.FILETIME
sTime.SYSTEMTIME

Global sTime, fTime

Procedure.l CalDate(y, m, d, h, i, s)
  sTime\wYear = y
  sTime\wMonth = m
  sTime\wDay = d
  sTime\wHour = h
  sTime\wMinute = i
  sTime\wSecond = s
  cTime = SystemTimeToFileTime_(sTime, @fTime)
  ProcedureReturn fTime
EndProcedure

If OpenWindow(0, 0, 0, 220, 200, #PB_Window_SystemMenu | #PB_Window_ScreenCentered,"CalendarGadget < 1970") And CreateGadgetList(WindowID())
  ; -> For years prior to 1970, we need to convert our date
  ; --> to a FILETIME
  CalDate(1800, 12, 22, 0, 0, 0)
  ; --> Now we need to convert the FILETIME to a SYSTEMTIME
  FileTimeToSystemTime_(fTime, @sTime)
  ; --> Load our Calendar Gadget with todays date
  CalendarGadget(0, 10, 10, 200, 180, Date())
  ; --> Change CalendarGasdget date to 1800, December, 22
  SendMessage_(GadgetID(0), #MCM_SETCURSEL, 0, sTime)
  Repeat
    event = WaitWindowEvent()
  Until event = #PB_Event_CloseWindow
EndIf
End
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Major
New User
New User
Posts: 3
Joined: Fri Apr 25, 2003 5:41 pm
Location: Denmark/Russia
Contact:

Post by Major »

#1. OK. But there is no information in a help about this style. And how can i remove readonly style?
#2. Bad news :(
#3. Mmmm... very useful code

Thanks for your answers.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

You're welcome Major :)

I'll see what I can do about removing the #ES_READONLY. ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Sparkie wrote:I'll see what I can do about removing the #ES_READONLY. ;)
Well it wasn't as easy as I expected, but here's what I came up with.

Code: Select all

#MCM_FIRST = $1000 
#MCM_SETCURSEL = #MCM_FIRST + 2 
#MCM_GETCURSEL = #MCM_FIRST + 1

fTime.FILETIME 
sTime.SYSTEMTIME 

Global sTime, fTime, oldCallback

; --> Procedure to allow CalendarGadget dates < 1970
Procedure.l CalDate(y, m, d, h, i, s) 
  sTime\wYear = y 
  sTime\wMonth = m 
  sTime\wDay = d 
  sTime\wHour = h 
  sTime\wMinute = i 
  sTime\wSecond = s 
  cTime = SystemTimeToFileTime_(sTime, @fTime) 
  ProcedureReturn fTime 
EndProcedure 

; --> SubClass procedure for CalendarGadget 
Procedure CalCallback(hwnd, msg, wparam, lparam) 
  result = CallWindowProc_(oldCallback, hwnd, msg, wparam, lparam) 
  Select msg 
    Case #WM_COMMAND 
      Select wparam >>16
        Case #EN_SETFOCUS
          ; --> Edit control is activated. It has a new handle each time it's activated.
          ; --> Allow Numbers only
          SetWindowLong_(lparam, #GWL_STYLE, GetWindowLong_(lparam, #GWL_STYLE) | #PB_String_Numeric)
          ; --> Remove the ReadOnly flag
          SendMessage_(lparam, #EM_SETREADONLY, 0, 0)
          ; --> Set limit to 4 numbers
          SendMessage_(lparam, #EM_LIMITTEXT, 4, 0)
        Case #EN_CHANGE
          ; --> Find the spinner
          hSpin = FindWindowEx_(GadgetID(0), 0, "msctls_updown32", 0)
          ; --> Get the current date in CalendarGadget
          SendMessage_(GadgetID(0), #MCM_GETCURSEL, 0, @sTime)
          ; --> Buffer for Edit control text (year)
          eText$ = Space(5)
          ; --> Get the text (year)
          SendMessage_(lparam, #WM_GETTEXT, 5, @eText$)
          ; --> Get the value of the text
          spinPos = Val(eText$)
          If spinPos > 1752
            ; --> If the year is valid, update CalendarGadget
            SendMessage_(hSpin, #UDM_GETPOS, 0, 0)
            sTime\wYear = Val(eText$)
            SendMessage_(GadgetID(0), #MCM_SETCURSEL, 0, sTime)
          EndIf
      EndSelect 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

If OpenWindow(0, 0, 0, 220, 200, #PB_Window_SystemMenu | #PB_Window_ScreenCentered,"CalendarGadget < 1970") And CreateGadgetList(WindowID()) 
  ; -> For years prior to 1970, we need to convert our date to a FILETIME 
  CalDate(1800, 12, 22, 0, 0, 0) 
  ; --> Now we need to convert the FILETIME to a SYSTEMTIME 
  FileTimeToSystemTime_(fTime, @sTime) 
  ; --> Load our Calendar Gadget with todays date 
  CalendarGadget(0, 10, 10, 200, 180, Date()) 
  ; --> Change CalendarGasdget date to 1800, December, 22 
  SendMessage_(GadgetID(0), #MCM_SETCURSEL, 0, sTime)
  ; --> Subclass CalendarGadget so we receive events for UpDown control
  oldCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @CalCallback())
  Repeat 
    event = WaitWindowEvent() 
  Until event = #PB_Event_CloseWindow 
EndIf 
End
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Major
New User
New User
Posts: 3
Joined: Fri Apr 25, 2003 5:41 pm
Location: Denmark/Russia
Contact:

Post by Major »

Thank you, Sparkie
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4792
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Sparkie!

Post by Fangbeast »

You are on your way to being a legend and you aren't even dead yet!!! It's a pleasure to persuse through your code and I wish some of your genius could rub off on me.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

The Date library allows to handle Date and Time from 1970 up to 2034, using the unix way (number of seconds elapsed since the 1st January 1970).
Oh my God !!! :shock:

Now i know when Earth is going to be destroyed!!!!

Unix engineers knew.... They knew ....
MikeB
Enthusiast
Enthusiast
Posts: 183
Joined: Sun Apr 27, 2003 8:39 pm
Location: Cornwall UK

Post by MikeB »

This is probably a daft question, but why is the year now limited to >1752?
Also if you comment out the bit setting it to December 22nd. 1800

Code: Select all

CalDate(1800, 12, 22, 0, 0, 0) 
  ; --> Now we need to convert the FILETIME to a SYSTEMTIME 
  ;FileTimeToSystemTime_(fTime, @sTime) 
  ; --> Load our Calendar Gadget with todays date 
  CalendarGadget(0, 10, 10, 200, 180, Date()) 
  ; --> Change CalendarGasdget date to 1800, December, 22 
  ;SendMessage_(GadgetID(0), #MCM_SETCURSEL, 0, sTime) 
You now have a calendar that gives you todays date and still lets you go back to 1753 (giving correct dates according to my checking), but as far as I can see the procedure CalDate() is never called.
Excuse my ignorance, I find the API calls heavy going at times.

MikeB
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@Major:
You're welcome. :)

@Fangbeast:
You're far too generous with your compliments. :oops: But thank you just the same. :) All I am doing is finding a solution to the challenge. Having the right tools and using logic helps it all come together. 8)

@Num3:
Not to worry, I'm able to squeeze 4 more years out of the PB date commands. :)

Code: Select all

date = Date(1970, 1, 1, 0, 0, 0) + $7FFFFFFF
; --> Date() works up to 2038 01 19 03:14:07
Debug "Date: " + Str(date)
Debug FormatDate("%yyyy %mm %dd %hh:%ii:%ss", date)
Debug "Day of Week: " + Str(DayOfWeek(date))
Debug "Day of Year: " + Str(DayOfYear(date))
Debug "Year: " + Str(Year(date))
Debug "Month: " + Str(Month(date))
Debug "Day: " + Str(Day(date))
Debug "Hour: " + Str(Hour(date))
Debug "Minute: " + Str(Minute(date))
Debug "Second: " + Str(Second(date))
; --> ParseDate works up to 2038 01 18 22:14:7
Debug ParseDate("%yyyy/%mm/%dd/%hh/%ii/%ss", "2038/1/18/22/14/7")
@MikeB:
The CalendarGadget can always handle dates > 1752, but due to PB Date limitations, you can't set the date with SetGadgetState using a date < 1970. That's where the API comes in.

To seta a date < 1970, we use this:

Code: Select all

SendMessage_(GadgetID(0), #MCM_SETCURSEL, 0, sTime)
Instead of this, which will fail:

Code: Select all

SetGadgetState(0, Date(1800, 12, 22, 0, 0, 0))
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Post Reply