|
Anyone interested in random selection? It is implemented by me and I can post the code here if people are interested. It features the following:
<br />
- randomly select any days individually over an unlimited time range<br />
- max days supported<br />
- can get selected days as CList of COleDateTime, ascending order<br />
- 2 selection "drawing" modes on mouse move: select or toggle (select mode: single click to deselect)<br />
- extra: optional date range limit which works in all selection modes<br />
The stuff is implemented using DWORD bitfields which are allocated on the fly as user selects more days over several months (similar to the special days of CMonthCalCtrl) and stored in a CMap with year-month as key value.
Koen Zagers
|
|
|
|
|
To fix add
m_rectToday.SetRectEmpty();
m_rectScrollRight.SetRectEmpty();
m_rectScrollLeft.SetRectEmpty();
m_rectNone.SetRectEmpty();
in
CFPSMiniCalendarCtrl::CFPSMiniCalendarCtrl();
|
|
|
|
|
|
Aha, done! After a long hour of tracking, I found out!
To mark a special day (bold font), you make a comparison between the dt object and the day you want to mark, and if they're match, return TRUE. For example:
Today is 14/4/06.
This stuff code:
BOOL CALLBACK IsSpecialDateCallback(COleDateTime &dt)
{
COleDateTime dtNow = COleDateTime::GetCurrentTime();
if (dt.GetDay()==dtNow.GetDay())
return TRUE;
return FALSE;
}
will mark the day 14 of all months as bold. And the rest is up to you!
Hope this helps!
|
|
|
|
|
1. Should destroy the month selection list window before deleting it:
if (m_pHeaderList) {
m_pHeaderList->DestroyWindow ();
delete m_pHeaderList;
m_pHeaderList = NULL;
}
2. When moving between months using the small arrows, the control is very sluggish. It takes appr. 500 milliseconds to step to the next/previous month even in a 1 row * 1 columnn view. Solution: ?
3. The selection is hardly visible. With my default XP colours, the selected days are drawn with white letters over a light gray background. So I've changed it in CFPSMiniCalendarCtrl::DrawDays :
if (IsDateSelected(dt))
{
cBackColor = ::GetSysColor(COLOR_HIGHLIGHT);
cTextColor = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
|
|
|
|
|
As for 2.):
I've changed all RedrawWindow() calls to Invalidate (FALSE) .
The control was drawn twice for each step so I've removed the Invalidate (previously RedrawWindow ) call from OnLButtonUp .
The main reason the control was sluggish is that the scrolling is not handled in OnLButtonDblClk . I've copied these parts from OnLButtonDown now it works like a charm.
However, if I move the mouse with the button pressed, the control is redrawn for each slightest move or noise. I believe it to be a bug so I've commented the scrolling part out from OnMouseMove .
|
|
|
|
|
Hi Yogurt,
Good fixes, I have included all of them in my code here too.
There are some small misalignments of graphics still, but it is getting there.
|
|
|
|
|
- "Today" is shorter than "None" in some languages. Drawing both buttons according to "Today"s size results in clipping "None". I've calculated text extent for both strings and used the bigger.
- The date string is not "month year" in some languages but "year month". So I've changed the first lines of CFPSMiniCalendarCtrl::DrawHeader to the following:
SYSTEMTIME rST;
::ZeroMemory (&rST, sizeof (rST));
rST.wYear = static_cast<WORD> (iYear);
rST.wMonth = static_cast<WORD> (iMonth);
rST.wDay = 1;
TCHAR strText[256] = _T("");
::GetDateFormat (LOCALE_USER_DEFAULT, DATE_YEARMONTH, &rST, NULL, strText, sizeof (strText) / sizeof (TCHAR));
and all other places accordingly where GetMonthName was used.
- The days cannot be abbreviated simply getting the first letters of their names in some languages. I've changed CFPSMiniCalendarCtrl::SetFirstDayOfWeek as follows:
if (iDayOfWeek > 0 && iDayOfWeek <= 7)
{
m_iFirstDayOfWeek = iDayOfWeek;
TCHAR dayName[256] = _T("");
::GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1, dayName, sizeof (dayName) / sizeof (TCHAR));
m_arDaysOfWeekNames[(9 - iDayOfWeek) % 7] = dayName;
::GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME2, dayName, sizeof (dayName) / sizeof (TCHAR));
m_arDaysOfWeekNames[(10 - iDayOfWeek) % 7] = dayName;
::GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME3, dayName, sizeof (dayName) / sizeof (TCHAR));
m_arDaysOfWeekNames[(11 - iDayOfWeek) % 7] = dayName;
::GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME4, dayName, sizeof (dayName) / sizeof (TCHAR));
m_arDaysOfWeekNames[(12 - iDayOfWeek) % 7] = dayName;
::GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME5, dayName, sizeof (dayName) / sizeof (TCHAR));
m_arDaysOfWeekNames[(13 - iDayOfWeek) % 7] = dayName;
::GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME6, dayName, sizeof (dayName) / sizeof (TCHAR));
m_arDaysOfWeekNames[(7 - iDayOfWeek) % 7] = dayName;
::GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME7, dayName, sizeof (dayName) / sizeof (TCHAR));
m_arDaysOfWeekNames[(8 - iDayOfWeek) % 7] = dayName;
}
and CFPSMiniCalendarCtrl::ComputeSize to
iWidthByDaysOfWeek = 0;
iDaysOfWeekHeight = 0;
CSize textSize;
for (iX = 0; iX < 7; iX++) {
textSize = pDC->GetTextExtent (m_arDaysOfWeekNames[iX]);
if (iWidthByDaysOfWeek < textSize.cx)
iWidthByDaysOfWeek = textSize.cx;
if (iDaysOfWeekHeight < textSize.cy)
iDaysOfWeekHeight = textSize.cy;
}
|
|
|
|
|
Good fix, however you must also change the nCount-argument to DrawText in DrawDaysOfWeek() to -1.
Otherwise these new day abbrevs will still yield just one character.
|
|
|
|
|
This should not be a big problem, as the code does use some MFC and Windows API internationalization features.
I have pinpointed these potential problems:
1. The default font which is used in the control is hard coded as "Tahoma," which will kill all characters that this font doesn't include.
2. There are calls to setlocale() in the code, that will reset the current locale setting in the user's thread. It will probably be reset to the user locale setting, but it shouldn't do it anyway.
3. The code is written using the non-portable MBCS character system.
4. There are hard coded strings in the code, but not much more than "Today" and "None."
5. The code relies on the ability of the selected font to render latin characters and numbers a-z , A-Z and 0-9.
6. The code relies on the height of at least one of A-Z latin characters to equal or exceed all the other characters that will be displayed
I currently have a fix for problems 1-4, and I am not sure if 5 and 6 are really going to be problems.
Thanks,
John
|
|
|
|
|
Just an update.
As I said, I have patched this code a bit.
I set the font from DEFAULT_GUI_FONT, removed the setlocale() calls, ported to TCHAR character support for UNICODE builds, and moved hard coded strings to resources.
I have now tested the control on English, Swedish and full Japanese systems, and all of them show locally translated calendars.
I can offer to return my patch to Matt, if anyone is interrested.
John
|
|
|
|
|
Sorry for the delay in responding.
I received the first notification several days ago, but it became buired in a deluge of emails. Since then I have been totally slammed at work.
I appreciate the effort and I am glad people are finding this code useful. If you want, you can email me the source code and I will post it onto CP. Please don't be offended if I can't post it quickly, but I will do my best to get it updated within a week or two.
Thanks,
Matt Gullett
|
|
|
|
|
Hey Matt,
Don't worry about delayed response, I am very guilty of the same..
Unfortunately, I have since added configurable week numbers to the control, and in doing this I used the boost date/time library (boost.org).
I will send you the code anyway, but I realize MFC based programmers may not be the most keen boost users, so that dependency spoils the example a little.
|
|
|
|
|
Hi John,
Would you please publish your fixes anywhere? It seems it took Matt a month to reply at all to your comment, it took you another month to comment his comment, now it's another month without any updates. I expect you to reply within another month, or so.
|
|
|
|
|
Hey Yogurt,
I sent my sources to your e-mail, maybe you can put them somewhere so that people can use it.
I still know of one bug in the code, under chinese traditional (or another country with more than one character to abbreviate weekdays) the weekdays use the wrong abbreviation-character, I think it should always use the last character if there are more than one. On these systems, weekdays all appear to have the same name.
|
|
|
|
|
I'll put it on a server in a few days along with my fixes. The first-character-of-the-weekdays issue is solved, I think, because I completely got rid of this stuff and I use the correct weekday abbreviations. Even in English I found it ugly to see two "T"s and two "S"s. Of course, I can deduce which is Tuesday and which is Thursday, it's still not too user-friendly.
(The most extreme example I know is in the Hungarian language: "H", "K", "Sze", "Cs", "P", "Szo", "V". As you see, Wed and Sat can be abbreviated with no less than 3 characters to make them different.)
|
|
|
|
|
Yogurt wrote:
I'll put it on a server in a few days along with my fixes.
Could I get an address to this updated version? I am looking forward to modifying it to use a custom date object that defines its own set of months and weekdays.
|
|
|
|
|
Hello Matt,
first, great work. the component looks very cool.
i´m not very familar with c++, but i want to use the component in my c# application for selecting dates. to do this i must have a dll to link from my application. i don´t find out how to do this.
what must i do? can anyone help me?
thanks
christoph
|
|
|
|
|
hi, I need a smart monthcalendar control for c#
can you help me???
thanks in advance...
Javi
--------------------------------
petercode123 wrote: ForumMS Outlook style miniature calendar control
Subject:Re: dll possible?
Sender:petercode123
Date:6:22 5 Feb '04
Hello Matt,
first, great work. the component looks very cool.
i´m not very familar with c++, but i want to use the component in my c# application for selecting dates. to do this i must have a dll to link from my application. i don´t find out how to do this.
what must i do? can anyone help me?
thanks
christoph
|
|
|
|
|
hey javi,
puh, long time ago. that was in my old company I was looking for such a control. I didn´t find, what I used in that project. but maybe the following link is interessting for you.
http://www.binarymission.co.uk/bndpicknet.aspx[^]
regards
christoph
|
|
|
|
|
Thank you for your reply. I didn't find a solution too. I was watching the link you posted, and I think is so expensive for us.
I continue looking for a smart monthview ocx with multiselect, doubleclick, backcolor for special dates, enabling/disabling month selector, and no more.
Thanks for all... if you can help me in the searching, ...I thank you a lot.
If I found something, I tell you, ok?
Thanks again
|
|
|
|
|
I have problems with this control when using it on systems where there are Russian or Bulgarian alphanets. Any workaround for successfully displaying cyrillic characters (month name)?
Thanks in advance
|
|
|
|
|
Can you please give me some example how to set special days? For example from array defined and filled outside the IsSpecialDateCallback function.
Thanks for great class.
Pavle
|
|
|
|
|
DrawDays() is called in OnPaint
int CFPSMiniCalendarCtrl::DrawDays(CDC &dc, int iY, int iLeftX, int iMonthRow, int iMonthCol, int iMonth, int iYear)
{
...
CFont* pOldFont = dc.SelectObject(m_DaysFontInfo.m_pFont);
dc.SetBkColor(::GetSysColor(COLOR_BTNFACE));
dc.SetTextColor(m_DaysFontInfo.m_cColor);
dc.SetBkMode(TRANSPARENT);
...
for (int iRow = 1; iRow <= 6; iRow++)
{
...
...
//FIX: pOldFont is already filled up. Do not overwrite this value
if (IsSpecialDate(dt))
/*pOldFont = */dc.SelectObject(m_SpecialDaysFontInfo.m_pFont);
else
/*pOldFont = */dc.SelectObject(m_DaysFontInfo.m_pFont);
...
}
dc.SelectObject(pOldFont);
...
return iReturn;
}
|
|
|
|
|
Hmmm... Good catch. I have not had time to look at it in detail, but it certainly appears to be a resource leak.
Thanks,
Matt Gullett
|
|
|
|
|