Hello,
Has anyone experience with MONTHDAYSTATE? I'm trying to display a monthcalendar control on a form with specific days in different colours depending on various User settings. I just need to get pointed in the right direction; I'll figure it out after that.
Here is the code I started with:
#define BOLDDAY(ds, iDay) \
if (iDay > 0 && iDay < 32)(ds) |= (0x00000001 << (iDay - 1))
case WM_NOTIFY:
if (((LPNMHDR)lParam)->code == MCN_GETDAYSTATE)
{
MONTHDAYSTATE rgMonths[12] = { 0 };
int cMonths = ((NMDAYSTATE*)lParam)->cDayState;
for (int i = 0; i < cMonths; i++)
{
BOLDDAY(rgMonths[i], 1);
BOLDDAY(rgMonths[i], 15);
}
((NMDAYSTATE*)lParam)->prgDayState = rgMonths;
return TRUE;
}
break;
Thanks.
Hi Clive,
I am working on this one now. Looks like I need to add the MCS_DAYSTATE window style during calendar creation in order for the MCN_GETDAYSTATE to fire. I have done that and am catching the WM_NOTIFY in AllEvents of the parent form. It is not working as expected... yet. I will keep working on this and try to figure it out.
This has been bothering me all morning. I could not understand why I was not receiving the MCN_GETDAYSTATE notification.
Turns out, it appears that the notification code is defined incorrectly in the commctrl.bi file.
'// As defined in commctrl.bi
' const MCN_GETDAYSTATE = culng(MCN_FIRST + 3)
'// Per Jose's includes it looks like the FB team are using the pre-Vista value for MCN_GETDAYSTATE
' %MCN_GETDAYSTATE = %MCN_FIRST + 3 ' Prior to Windows Vista
'// As defined in commctrl.h (this is the correct post-Vista value)
' #define MCN_GETDAYSTATE (MCN_FIRST - 1) // -747
Changing to the correct code, I can now get the notification whenever the calendar display needs to display a range of days.
I now need to work on an elegant way to make it easy for the user to set which days to display in bold.
Hi Clive,
Here you go. At least it appears to work correctly on my computer. Hopefully it will for you also.
You need to download the attachments and overwrite your existing WinFormsX files
Here is the translated code that you posted:
#define BOLDDAY(ds, iDay) if (iDay > 0 AND iDay < 32) then (ds) = (ds) or (&H00000001 shl (iDay - 1))
''
''
Function frmMain_AllEvents( ByRef sender As wfxForm, ByRef e As EventArgs ) As LRESULT
select case e.Message
case WM_NOTIFY
dim pNMH as NMHDR ptr = cast(NMHDR ptr, e.lParam)
if pNMH then
select case pNMH->code
case (MCN_FIRST - 1) 'correct value for MCN_GETDAYSTATE
dim as NMDAYSTATE ptr pNMDayState = cast(NMDAYSTATE ptr, e.lParam)
dim as MONTHDAYSTATE rgMonths(12)
dim as long cMonths = pNMDayState->cDayState
for i as long = 0 to cMonths - 1
BOLDDAY(rgMonths(i), 1)
BOLDDAY(rgMonths(i), 15)
next
pNMDayState->prgDayState = @rgMonths(0)
e.Handled = true
end select
end if
end select
Function = 0
End Function
Also, in the WM_NOTIFY code you should also test the pNMH->hwndFrom value in addition to the pNMH->code notification value to ensure that it is your calendar control sending the notification.
Thanks very much, Paul! I'll report back...
Works great, Paul, thanks again.
Excellent - I am happy it works for you!