Page 1 of 1

wxCalendarCtrl - date not getting set correctly

Posted: Wed Aug 15, 2018 8:38 am
by deepti
I have the following piece of code which creates a wxCalendarCtrl and sets it with a given date coming in the form of a string.

Code: Select all

wxCalendarCtrl* date = new wxCalendarCtrl(win, ++m_controlCount, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, !wxCAL_SHOW_HOLIDAYS);

wxDateTime::wxDateTime_t day, month, year;
month = atoi(l_tokenizer[1].c_str());
year = atoi(l_tokenizer[0].c_str());
if (l_tokenizer_day.count() > 1)
	day = atoi(l_tokenizer_day[0].c_str());

wxDateTime dt;
dt.SetDay(day);
dt.SetMonth((wxDateTime::Month)(month-1));
dt.SetYear(year);
bool b = date->SetDate(dt);
The calendar is displayed, but 2 dates are shown selected - today's date and the date (29th august 2018) I have set using the SetDate function above.
Also, when I navigate to a different month and then navigate back to August, only today's date is selected, but not the date selected through the "SetDate" function.
Please help!

Please see screenshot below:
calendarctrl.jpg
calendarctrl.jpg (15.3 KiB) Viewed 1521 times

Re: wxCalendarCtrl - date not getting set correctly

Posted: Wed Aug 15, 2018 10:03 am
by PB
Firstly, you are working with an invalid wxDateTime. If you used the debug version to debug the issue wxWidgets let you know that even without calling its IsValid() method.

Secondly, it is true that the calendar does not preserve the selected date when switching months. However, at least on MSW (tested on Win10) that seems to be the behaviour of the native control.

Re: wxCalendarCtrl - date not getting set correctly

Posted: Wed Aug 15, 2018 10:17 am
by deepti
Thanks for your response @PB.
I noticed that and corrected the code to the following, and the asserts are now gone:

Code: Select all

int day, month, year;
month = atoi(l_tokenizer[1].c_str());
year = atoi(l_tokenizer[0].c_str());
if (l_tokenizer_day.count() > 1)
  day = atoi(l_tokenizer_day[0].c_str());
wxDateTime dt((wxDateTime::wxDateTime_t)(day), (wxDateTime::Month)(month - 1), year);
But the issue with 2 dates (today's date and selected date) being in selected state still remains. Is there a way to get rid of this? Please let me know.

Re: wxCalendarCtrl - date not getting set correctly

Posted: Wed Aug 15, 2018 10:49 am
by PB
I am not sure but I believe that Today being always marked is a default style of the native control on Windows. Common controls version 4.70 (Vista+) supports MCS_NOTODAYCIRCLE but wxWidgets do not expose this option.

Unless you want to mess with the native control then perhahps the only solution would be using wxGenericCalendarCtrl instead of wxCalendarCtrl.

Edit
FWIW, here is the code to "fix" the issue on MSW (the bottom calendar has the MCS_NOTODAYCIRCLE style):
calendar.png
calendar.png (11.15 KiB) Viewed 1505 times

Code: Select all

#include <wx/wx.h>
#include <wx/calctrl.h>

#ifdef __WXMSW__
    #include <wx/msw/wrapcctl.h>
    #include <wx/platinfo.h>
#endif;


bool RemoveTodayCircle(wxCalendarCtrl* calendar)
{
#ifdef __WXMSW__
    if ( !wxPlatformInfo().CheckOSVersion(6, 0) )
        return false; // older than Vista
    
    HWND hWnd = calendar->GetHWND();
    wxCHECK(hWnd, false);
    
    LONG style = ::GetWindowLong(hWnd,  GWL_STYLE);

    if ( style == 0 )
        return false;

    style |= MCS_NOTODAYCIRCLE;
    if ( ::SetWindowLong(hWnd, GWL_STYLE, style) == 0 )
        return false;

    calendar->Refresh(); calendar->Update();
    return true;
#else    
    return false;
#endif // #ifdef __WXMSW__
}

class MyFrame : public wxFrame
{
public:
    MyFrame() : wxFrame(NULL, wxID_ANY, "Test")
    {                
        wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
        wxCalendarCtrl* calendar = NULL;
        wxDateTime dt(wxDateTime::Today());        
        short day = dt.GetDay();
                
        if ( day == 1 )
            day++;
        else
            day--;
        dt.SetDay(day);

        bSizer->Add(new wxCalendarCtrl(this, wxID_ANY, dt), 0, wxALL, 5);                        

        calendar = new wxCalendarCtrl(this, wxID_ANY, dt);
        RemoveTodayCircle(calendar);
        bSizer->Add(calendar, 0, wxALL, 5);                
        
        SetSizerAndFit(bSizer);
    }
};

class MyApp : public wxApp
{
public:
    bool OnInit()
    {
        (new MyFrame())->Show();
        return true;
    }
}; wxIMPLEMENT_APP(MyApp);

Re: wxCalendarCtrl - date not getting set correctly

Posted: Wed Aug 15, 2018 11:15 am
by deepti
Ok thank you @PB :)