wxCalendarCtrl - date not getting set correctly

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
deepti
Earned some good credits
Earned some good credits
Posts: 115
Joined: Tue Jul 17, 2018 5:38 pm

wxCalendarCtrl - date not getting set correctly

Post 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 1490 times
Last edited by deepti on Wed Aug 15, 2018 10:21 am, edited 2 times in total.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxCalendarCtrl - date not getting set correctly

Post 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.
deepti
Earned some good credits
Earned some good credits
Posts: 115
Joined: Tue Jul 17, 2018 5:38 pm

Re: wxCalendarCtrl - date not getting set correctly

Post 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.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxCalendarCtrl - date not getting set correctly

Post 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 1474 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);
Last edited by PB on Wed Aug 15, 2018 11:29 am, edited 2 times in total.
deepti
Earned some good credits
Earned some good credits
Posts: 115
Joined: Tue Jul 17, 2018 5:38 pm

Re: wxCalendarCtrl - date not getting set correctly

Post by deepti »

Ok thank you @PB :)
Post Reply