Repository navigation
SysWin Gui MonthCal
Home › All Categories › sys/win › sys/win/gui › MonthCal
Reads and sets the selected date, range, today and colours of a month calendar control.
A month calendar control shows one or more months as a grid of days and lets the user pick a
date, or a run of dates with the MCS_MULTISELECT style. Create one with
CWindow.AddControl( "MonthCal", ... ) (or "MonthCalendar"). Every function here takes the
control's handle first and is written with the namespace: MonthCal.GetCurSel( hMonthCal ).
Dates travel in SYSTEMTIME structures; the control ignores the time members. Functions that
take a range take an array of two SYSTEMTIME: element 0 is the earlier date, element 1
the later. When the user picks a date the parent receives WM_NOTIFY with MCN_SELECT (a
click) and MCN_SELCHANGE (any change). Points and rectangles are client coordinates of the
control.
SizeRectToMin and the functions from
GetCalendarGridInfo on in the table below need version 6 of the common
controls: call EnableVisualStyles() at start-up or give the program a manifest.
#import "sys/win"
#import "sys/win/gui"
using win, guiA calendar limited to this year and next, opened on 4 July of this year, sized to the space one month needs; the caption shows each date the user picks.
#import "sys/win"
#import "sys/win/gui"
using win, gui
const IDC_CAL = 101
declare function WndProc( byval hwnd as HWND, byval uMsg as UINT, byval wParam as WPARAM, byval lParam as LPARAM ) as LRESULT
function main() as long
SetProcessDpiAwareness( PROCESS_SYSTEM_DPI_AWARE )
EnableVisualStyles()
dim pWindow as CWindow = "MonthCalDemo"
dim hWin as HWND = pWindow.Create( NULL, "Pick a date", @WndProc )
dim hCal as HWND = pWindow.AddControl( "MonthCal", hWin, IDC_CAL, "", 10, 10, 250, 200 )
var (l, t, r, b) = MonthCal.GetMinReqRect( hCal )
SetWindowPos( hCal, NULL, 0, 0, r, b, SWP_NOMOVE or SWP_NOZORDER )
SetWindowClientSize( hWin, r + 20, b + 20 )
pWindow.Center()
dim today as SYSTEMTIME = MonthCal.GetToday( hCal )
dim rg(1) as SYSTEMTIME
rg(0).wYear = today.wYear : rg(0).wMonth = 1 : rg(0).wDay = 1
rg(1).wYear = today.wYear + 1 : rg(1).wMonth = 12 : rg(1).wDay = 31
MonthCal.SetRange( hCal, GDTR_MIN or GDTR_MAX, @rg(0) )
dim st as SYSTEMTIME
st.wYear = today.wYear : st.wMonth = 7 : st.wDay = 4
MonthCal.SetCurSel( hCal, st )
return pWindow.DoEvents( SW_NORMAL )
end function
function WndProc( byval hwnd as HWND, byval uMsg as UINT, byval wParam as WPARAM, byval lParam as LPARAM ) as LRESULT
select case uMsg
case WM_NOTIFY
dim pnmh as NMHDR ptr = cast( NMHDR ptr, lParam )
if pnmh->idFrom = IDC_CAL andalso pnmh->code = MCN_SELECT then
dim st as SYSTEMTIME = MonthCal.GetCurSel( pnmh->hwndFrom )
SetWindowText( hwnd, st.wDay & "/" & st.wMonth & "/" & st.wYear )
end if
return 0
case WM_DESTROY
PostQuitMessage( 0 )
return 0
end select
return DefWindowProcW( hwnd, uMsg, wParam, lParam )
end function
end main()| Function | Does |
|---|---|
| GetCurSel | Returns or reads the selected date. |
| SetCurSel | Selects a date and brings it into view. |
| GetSelRange | Reads the selected run of dates. |
| SetSelRange | Selects a run of dates. |
| GetMaxSelCount | Returns the most days that can be selected. |
| SetMaxSelCount | Sets the most days that can be selected. |
| GetRange | Reads the earliest and latest dates allowed. |
| SetRange | Sets the earliest and latest dates allowed. |
| GetToday | Returns or reads the date the control treats as today. |
| SetToday | Sets the date the control treats as today. |
| GetMonthRange | Reads the first and last dates on display. |
| GetFirstDayOfWeek | Returns the day each week starts on. |
| SetFirstDayOfWeek | Sets the day each week starts on. |
| GetMonthDelta | Returns how many months a scroll button moves. |
| SetMonthDelta | Sets how many months a scroll button moves. |
| GetColor | Returns the colour of a part of the control. |
| SetColor | Sets the colour of a part of the control. |
| SetDayState | Sets which days are drawn bold. |
| HitTest | Finds which part of the control is at a point. |
| GetMinReqRect | Returns the size one month needs. |
| SizeRectToMin | Shrinks a rectangle to whole months. |
| GetMaxTodayWidth | Returns the width of the "Today" line. |
| GetCalendarGridInfo | Reads the rectangle or dates of a part of the grid. |
| GetCalendarBorder | Returns the border around each month. |
| SetCalendarBorder | Sets the border around each month. |
| GetCalendarCount | Returns the number of months on display. |
| GetCurrentView | Returns whether days, months, years or decades are shown. |
| SetCurrentView | Shows days, months, years or decades. |
| GetCALID | Returns the calendar system in use. |
| SetCALID | Sets the calendar system. |
function GetCurSel overload( byval hMonthCal as HWND, byval pst as SYSTEMTIME ptr ) as boolean
function GetCurSel overload( byval hMonthCal as HWND, byref st as SYSTEMTIME ) as boolean
function GetCurSel overload( byval hMonthCal as HWND ) as SYSTEMTIMEReads the selected date, with wDayOfWeek filled in (0 is Sunday). A control with the
MCS_MULTISELECT style has a run of dates instead: use GetSelRange.
Returns true on success, or the date (third form; all zero on failure).
Example
dim st as SYSTEMTIME = MonthCal.GetCurSel( hCtrl )
print st.wDay; "/"; st.wMonth; "/"; st.wYearMicrosoft Learn: MCM_GETCURSEL
function SetCurSel overload( byval hMonthCal as HWND, byval pst as SYSTEMTIME ptr ) as long
function SetCurSel overload( byval hMonthCal as HWND, byref st as SYSTEMTIME ) as longSelects a date, scrolling it into view when it is not shown. It fails for a date outside the
allowed range and for a MCS_MULTISELECT control. No notification is sent.
Returns nonzero on success, 0 on failure.
Example
dim st as SYSTEMTIME
st.wYear = 2024 : st.wMonth = 2 : st.wDay = 29
MonthCal.SetCurSel( hCtrl, st )Microsoft Learn: MCM_SETCURSEL
function GetSelRange( byval hMonthCal as HWND, byval rgst as SYSTEMTIME ptr ) as longReads the first and last selected dates of a MCS_MULTISELECT control into the two-element
array at rgst.
Returns nonzero on success; 0 for a control without MCS_MULTISELECT.
Example
dim rg(1) as SYSTEMTIME
if MonthCal.GetSelRange( hCtrl, @rg(0) ) then print "from"; rg(0).wDay; " to"; rg(1).wDayMicrosoft Learn: MCM_GETSELRANGE
function SetSelRange( byval hMonthCal as HWND, byval rgst as SYSTEMTIME ptr ) as booleanSelects the run of dates from rgst[0] to rgst[1] in a MCS_MULTISELECT control. The run
may not be longer than GetMaxSelCount days.
Returns true on success; false for a control without MCS_MULTISELECT.
Example
dim rg(1) as SYSTEMTIME
rg(0).wYear = 2025 : rg(0).wMonth = 8 : rg(0).wDay = 4
rg(1) = rg(0) : rg(1).wDay = 8
MonthCal.SetSelRange( hCtrl, @rg(0) ) ' a working weekMicrosoft Learn: MCM_SETSELRANGE
function GetMaxSelCount( byval hMonthCal as HWND ) as DWORDReturns the most days the user can select at once: 1 for a control without
MCS_MULTISELECT.
Example
print "up to"; MonthCal.GetMaxSelCount( hCtrl ); " days"Microsoft Learn: MCM_GETMAXSELCOUNT
function SetMaxSelCount( byval hMonthCal as HWND, byval iMax as UINT ) as booleanSets the most days the user can select at once, in a MCS_MULTISELECT control.
Returns true on success; false for a control without MCS_MULTISELECT.
Example
MonthCal.SetMaxSelCount( hCtrl, 14 )Microsoft Learn: MCM_SETMAXSELCOUNT
function GetRange( byval hMonthCal as HWND, byval rgst as SYSTEMTIME ptr ) as DWORDReads the earliest allowed date into rgst[0] and the latest into rgst[1].
Returns which limits are set: GDTR_MIN, GDTR_MAX, both, or 0 for none.
Example
dim rg(1) as SYSTEMTIME
if MonthCal.GetRange( hCtrl, @rg(0) ) and GDTR_MAX then print "nothing after"; rg(1).wYearMicrosoft Learn: MCM_GETRANGE
function SetRange( byval hMonthCal as HWND, byval fWhichLimit as DWORD, byval rgst as SYSTEMTIME ptr ) as booleanSets the earliest (rgst[0]) and latest (rgst[1]) dates the user can reach. fWhichLimit
says which of the two are set: GDTR_MIN, GDTR_MAX or both; a limit left out is removed.
Returns true on success.
Example
dim rg(1) as SYSTEMTIME
rg(0).wYear = 2020 : rg(0).wMonth = 1 : rg(0).wDay = 1
rg(1).wYear = 2030 : rg(1).wMonth = 12 : rg(1).wDay = 31
MonthCal.SetRange( hCtrl, GDTR_MIN or GDTR_MAX, @rg(0) )Microsoft Learn: MCM_SETRANGE
function GetToday overload( byval hMonthCal as HWND, byval pst as SYSTEMTIME ptr ) as boolean
function GetToday overload( byval hMonthCal as HWND, byref st as SYSTEMTIME ) as boolean
function GetToday overload( byval hMonthCal as HWND ) as SYSTEMTIMEReads the date the control circles as today: the system date, unless SetToday has changed it.
Returns true on success, or the date (third form).
Example
dim td as SYSTEMTIME = MonthCal.GetToday( hCtrl )
print "today is"; td.wDay; "/"; td.wMonth; "/"; td.wYearMicrosoft Learn: MCM_GETTODAY
sub SetToday overload( byval hMonthCal as HWND, byval pst as SYSTEMTIME ptr )
sub SetToday overload( byval hMonthCal as HWND, byref st as SYSTEMTIME )Makes the control treat another date as today. A NULL pointer goes back to the system date.
Example
dim st as SYSTEMTIME
st.wYear = 2025 : st.wMonth = 7 : st.wDay = 4
MonthCal.SetToday( hCtrl, st )Microsoft Learn: MCM_SETTODAY
function GetMonthRange( byval hMonthCal as HWND, byval gmr as DWORD, byval rgst as SYSTEMTIME ptr ) as longReads the first and last dates on display into the two-element array at rgst. With
GMR_VISIBLE only whole months count; with GMR_DAYSTATE the greyed days of the months before
and after count too, which is the span SetDayState needs.
Returns the number of months the span covers: for one month on display, 1 with
GMR_VISIBLE and 3 with GMR_DAYSTATE.
Example
dim rg(1) as SYSTEMTIME
print MonthCal.GetMonthRange( hCtrl, GMR_VISIBLE, @rg(0) ); " month(s) from"; rg(0).wMonth; " to"; rg(1).wMonthMicrosoft Learn: MCM_GETMONTHRANGE
function GetFirstDayOfWeek( byval hMonthCal as HWND ) as DWORDReturns the day shown in the first column, in the low word: 0 is Monday, 6 is Sunday. The high word is nonzero when it differs from the user's locale setting.
Returns the day and the flag in one value.
Example
print "weeks start on day"; LOWORD( MonthCal.GetFirstDayOfWeek( hCtrl ) )Microsoft Learn: MCM_GETFIRSTDAYOFWEEK
function SetFirstDayOfWeek( byval hMonthCal as HWND, byval iDay as long ) as DWORDSets the day shown in the first column: 0 for Monday through 6 for Sunday, or -1 to follow the locale.
Returns the previous day in the low word, and in the high word nonzero when that day differed from the locale.
Example
MonthCal.SetFirstDayOfWeek( hCtrl, 0 ) ' MondayMicrosoft Learn: MCM_SETFIRSTDAYOFWEEK
function GetMonthDelta( byval hMonthCal as HWND ) as longReturns how many months the display moves when a scroll button is clicked; unless changed, the number of months on display.
Example
print "scrolls by"; MonthCal.GetMonthDelta( hCtrl ); " month(s)"Microsoft Learn: MCM_GETMONTHDELTA
function SetMonthDelta( byval hMonthCal as HWND, byval iDelta as long ) as longSets how many months a scroll button moves the display; 0 goes back to the default.
Returns the previous setting, 0 when it was the default.
Example
MonthCal.SetMonthDelta( hCtrl, 3 ) ' a quarter at a timeMicrosoft Learn: MCM_SETMONTHDELTA
function GetColor( byval hMonthCal as HWND, byval iColor as long ) as COLORREFReturns the colour of one part: MCSC_BACKGROUND, MCSC_MONTHBK, MCSC_TEXT,
MCSC_TITLEBK, MCSC_TITLETEXT or MCSC_TRAILINGTEXT (the days of the neighbouring months).
Returns the colour, or -1 on failure.
Example
print "title background: &h"; hex( MonthCal.GetColor( hCtrl, MCSC_TITLEBK ) )Microsoft Learn: MCM_GETCOLOR
function SetColor( byval hMonthCal as HWND, byval iColor as long, byval clr as COLORREF ) as COLORREFSets the colour of one part, named as for GetColor.
Returns the previous colour, or -1 on failure.
Example
MonthCal.SetColor( hCtrl, MCSC_MONTHBK, BGR( 255, 255, 224 ) )Microsoft Learn: MCM_SETCOLOR
function SetDayState( byval hMonthCal as HWND, byval cbds as long, byval rgds as MONTHDAYSTATE ptr ) as booleanSets which days are drawn bold, for a control with the MCS_DAYSTATE style. rgds is an array
of cbds MONTHDAYSTATE values, one per month of the GMR_DAYSTATE span of
GetMonthRange; bit n of each value (bit 0 is day 1) makes that day bold.
Returns true on success; false for a control without MCS_DAYSTATE.
Example
dim rg(1) as SYSTEMTIME, ds(11) as MONTHDAYSTATE
dim n as long = MonthCal.GetMonthRange( hCtrl, GMR_DAYSTATE, @rg(0) )
ds(1) = ( 1 shl 0 ) or ( 1 shl 14 ) ' the 1st and 15th of the month on display
MonthCal.SetDayState( hCtrl, n, @ds(0) )Microsoft Learn: MCM_SETDAYSTATE
function HitTest overload( byval hMonthCal as HWND, byval pinfo as MCHITTESTINFO ptr ) as DWORD
function HitTest overload( byval hMonthCal as HWND, byref info as MCHITTESTINFO ) as DWORDFinds which part of the control is at pt, in client coordinates. The function fills in
cbSize. When the point is on a day, st receives its date.
Returns an MCHT_* code, also stored in uHit: MCHT_CALENDARDATE, MCHT_TITLEBTNNEXT,
MCHT_TODAYLINK, MCHT_NOWHERE and so on.
Example
dim mhi as MCHITTESTINFO
GetCursorPos( @mhi.pt ) : ScreenToClient( hCtrl, @mhi.pt )
if MonthCal.HitTest( hCtrl, mhi ) = MCHT_CALENDARDATE then print "over day"; mhi.st.wDayMicrosoft Learn: MCM_HITTEST
function GetMinReqRect overload( byval hMonthCal as HWND, byval prc as RECT ptr ) as boolean
function GetMinReqRect overload( byval hMonthCal as HWND, byref rc as RECT ) as boolean
function GetMinReqRect overload( byval hMonthCal as HWND ) as ( long, long, long, long )Reads the smallest rectangle that shows one whole month, "Today" line included; left and
top are 0, so right and bottom are the width and height. The size depends on the
control's font. The tuple form sets GetLastError() to 1 on success and 0 on failure.
Returns true on success, or the four edges.
Example
var (l, t, r, b) = MonthCal.GetMinReqRect( hCtrl )
SetWindowPos( hCtrl, NULL, 0, 0, r, b, SWP_NOMOVE or SWP_NOZORDER )Microsoft Learn: MCM_GETMINREQRECT
function SizeRectToMin overload( byval hMonthCal as HWND, byval prc as RECT ptr ) as long
function SizeRectToMin overload( byval hMonthCal as HWND, byref rc as RECT ) as long
function SizeRectToMin overload( byval hMonthCal as HWND ) as ( long, long, long, long )Works out how many whole months fit in the rectangle given and shrinks it, in place, to the
size those months need: a 600 × 220 rectangle becomes 457 × 172 (two months side by side) with
the default font. The tuple form starts from an empty rectangle and so returns the size of one
month; it sets GetLastError() to the control's reply.
Returns the control's reply; the result is the rectangle.
Example
dim rc as RECT
rc.right = 600 : rc.bottom = 220
MonthCal.SizeRectToMin( hCtrl, rc )
SetWindowPos( hCtrl, NULL, 0, 0, rc.right, rc.bottom, SWP_NOMOVE or SWP_NOZORDER )Microsoft Learn: MCM_SIZERECTTOMIN
function GetMaxTodayWidth( byval hMonthCal as HWND ) as DWORDReturns the width in pixels of the "Today" line at the bottom of the control.
Example
print "today line:"; MonthCal.GetMaxTodayWidth( hCtrl ); " pixels"Microsoft Learn: MCM_GETMAXTODAYWIDTH
function GetCalendarGridInfo overload( byval hMonthCal as HWND, byval pInfo as MCGRIDINFO ptr ) as boolean
function GetCalendarGridInfo overload( byval hMonthCal as HWND, byref info as MCGRIDINFO ) as booleanReads the rectangle, dates or text of one part of the grid. Set dwPart (MCGIP_CALENDAR,
MCGIP_CALENDARHEADER, MCGIP_CALENDARCELL, MCGIP_CALENDARCONTROL …), dwFlags
(MCGIF_RECT, MCGIF_DATE, MCGIF_NAME) and, for a cell, iCalendar, iRow and iCol; the
function fills in cbSize.
Returns true on success.
Example
dim gi as MCGRIDINFO
gi.dwPart = MCGIP_CALENDARCONTROL : gi.dwFlags = MCGIF_RECT
if MonthCal.GetCalendarGridInfo( hCtrl, gi ) then print "grid:"; gi.rc.right; " x"; gi.rc.bottomMicrosoft Learn: MCM_GETCALENDARGRIDINFO
function GetCalendarBorder( byval hMonthCal as HWND ) as DWORDReturns the space around each month, in pixels; 4 unless changed.
Example
print "border:"; MonthCal.GetCalendarBorder( hCtrl )Microsoft Learn: MCM_GETCALENDARBORDER
sub SetCalendarBorder( byval hMonthCal as HWND, byval fset as boolean, byval xyborder as long )With fset true, sets the space around each month to xyborder pixels; with false, goes
back to the default and ignores xyborder.
Example
MonthCal.SetCalendarBorder( hCtrl, true, 8 )Microsoft Learn: MCM_SETCALENDARBORDER
function GetCalendarCount( byval hMonthCal as HWND ) as DWORDReturns the number of months on display, which grows when the control is made larger.
Example
print MonthCal.GetCalendarCount( hCtrl ); " month(s) shown"Microsoft Learn: MCM_GETCALENDARCOUNT
function GetCurrentView( byval hMonthCal as HWND ) as DWORDReturns what the control shows: MCMV_MONTH (days, 0), MCMV_YEAR (months),
MCMV_DECADE (years) or MCMV_CENTURY (decades). Clicking the title moves up a level.
Example
if MonthCal.GetCurrentView( hCtrl ) <> MCMV_MONTH then MonthCal.SetCurrentView( hCtrl, MCMV_MONTH )Microsoft Learn: MCM_GETCURRENTVIEW
function SetCurrentView( byval hMonthCal as HWND, byval dwNewView as DWORD ) as booleanSwitches the control to MCMV_MONTH, MCMV_YEAR, MCMV_DECADE or MCMV_CENTURY.
Returns true on success.
Example
MonthCal.SetCurrentView( hCtrl, MCMV_YEAR ) ' show the twelve monthsMicrosoft Learn: MCM_SETCURRENTVIEW
function GetCALID( byval hMonthCal as HWND ) as CALIDReturns the calendar system the control uses, a CAL_* value: CAL_GREGORIAN (1) unless
changed.
Example
if MonthCal.GetCALID( hCtrl ) = CAL_GREGORIAN then print "Gregorian calendar"Microsoft Learn: MCM_GETCALID
sub SetCALID( byval hMonthCal as HWND, byval calid as UINT )Makes the control use another calendar system, a CAL_* value such as CAL_JAPAN or
CAL_HIJRI.
Example
MonthCal.SetCALID( hCtrl, CAL_GREGORIAN )Microsoft Learn: MCM_SETCALID
- sys/win/gui
- DTP, a date field that drops down a month calendar
-
CWindow for
AddControl( "MonthCal", ... ) -
Window text and styles for
EnableVisualStyles -
gui macros and helpers for reading
WM_NOTIFY
tiko-lang · Home · Feature Index · Keyword Index · License
FreeBASIC manual pages reproduced under the GNU FDL 1.3.
- Generics
- Interfaces
- For Each
- Iterators
- Tuples
- Array Results
- Defer
- Lambdas
- Block Strings
- String Slices
- Embed
- Typed Variadics
- C Header Import
- Foreign Library Linking
- UString
- Fixed-Width Types
- Nullptr
- String Library
- Format
- Array
- Map
- Set
- LinkedList
- OrderedMap
- OrderedSet
- Sorting
- Optional
- Result
- Smart Pointers
- Date and Time (Chrono)
- Filesystem
- File Streams
- Config (INI and TOML)
- Codec
- Hash
- UUID
- OS
- Process
- Net
- HTTP and TLS
- Math Library
- Finance
- Logging
- Terminal TUI Library
- PsControls
- tkControls
- sys/win
- Goroutines and Channels
- LLVM Backend
- tiko build
- TIKO_COMPILER
- Variable Declarations
- Standard Data Types
- User Defined Types
- Procedures
- Operators
- Control Flow Statements
- Converting Data Types
- Array Functions
- String Functions
- Mathematical Functions
- Bit Manipulation
- Date and Time Functions
- File I/O Functions
- Console Functions
- User Input (Runtime Library)
- User Input Functions (Graphics Library)
- Screen Functions
- 2D Drawing Functions
- Graphics Library Reference
- Graphics Keyword List
- Memory Functions
- Threading Support Functions
- Error Handling Functions
- Operating System Functions
- Preprocessor
- Intrinsic Defines
- Miscellaneous Keywords
- Modularizing