MonthCalendar SetDayState in VB.net

I had to resort to Interop code, because MonthCalendar.UpdateBoldedDates recreates the window, and messes up the current date ranges.

First, declare some Interop functions and data structures

    Const MCM_SETDAYSTATE As Integer = &H1008

    <StructLayout(LayoutKind.Sequential)> _
    Structure MONTHDAYSTATE
        Dim dw As UInt32
    End Structure

    <DllImport("user32.dll", EntryPoint:="SendMessage", _
        SetLastError:=True, CharSet:=CharSet.Auto)> _
    Shared Function SetDayState( _
     ByVal hWnd As IntPtr, _
     ByVal Msg As IntPtr, _
     ByVal wParam As IntPtr, _
     <[In](), Out()> ByVal lpD() As MONTHDAYSTATE) As IntPtr
    End Function

MCM_SetDayState has to be passed an array of MONTHDAYSTATE, the size of which includes the two months that may be partially displayed before the first month and after the last month.

Also note that the bitField for 1st of the month is the least significant bit.

Here’s a test code

Sub Test

        MonthCalendar1.CalendarDimensions = New System.Drawing.Size(2, 1)

        Dim mds(0 To 3) As MONTHDAYSTATE
        mds(0).dw = &amp;H0         ' -- partial month
        mds(1).dw = &amp;H10101010  ' -- 1st month
        mds(2).dw = &amp;H10000000  ' -- 2nd month
        mds(3).dw = &amp;H0         ' -- partial month

        Dim Ret As Integer
        Ret = SetDayState(MonthCalendar1.Handle, MCM_SETDAYSTATE, 4, mds)
        Debug.Assert(Ret <> 0)
End Sub

You should follow me on twitter here

Leave a Reply