Custom drawn cells on TCalendarView vanish with mouse movements

100 views Asked by At

I am trying to customize a TCalendarView on C++Builder 11 in the OnDrawDayItem event in order to draw some additional info into the cells in the future.

This drawing itself works OK when the program launches. However, once the mouse is moved over individual cells, they will vanish under the mouse cursor and just appear blank. I'm not sure what I'm missing here. When I click on any cell, everything gets redrawn correctly again, until I move the mouse.

I don't think the drawing code is really important, nevertheless below is a quick version just to test it. But the drawing itself is not the point, it's the fact that the cells vanish when moving the mouse over them.

This is what it looks like:

image

Once the mouse is moved outside of the calendar, for some reason all cells are redrawn correctly sometimes, but not always. Can't seem to find the mechanism here, tbh.

What am I doing wrong?

void __fastcall TForm1::cvDrawDayItem(TObject *Sender, TDrawViewInfoParams *DrawParams,
    TCellItemViewInfo *CalendarViewViewInfo)
{
    DrawParams->Handled = true; // set true to draw cell myself
    TCanvas *c = DrawParams->Canvas;

    Word day, month, year;
    DecodeDate (CalendarViewViewInfo->Date, year, month, day);

    // check for weekend days
    int dayOfWeek = CalendarViewViewInfo->Date.DayOfWeek();

    // fill weekends with a different color
    if (dayOfWeek==1 || dayOfWeek==7)
        c->Brush->Color = TColor (0xeeeeee);
    else // weekdays
        c->Brush->Color = TColor (0xfcfcfc);

    // get surrounding rect
    TRect rect = CalendarViewViewInfo->GlobalRect;

    // make drawing rect smaller to give a thin border
    int buffer = 1;
    rect.Inflate (-buffer, -buffer, -buffer, -buffer);

    // fill the cell background
    c->FillRect (rect);

    // set up font for the days
    c->Font->Name = "Segoe UI";
    c->Font->Height = -20;

    // print day in the center of the cell
    c->TextRect (rect, DrawParams->Text, TTextFormat () << tfSingleLine << tfCenter << tfVerticalCenter);

    // print abbreviated month on the first of the month
    c->Font->Height = -15;
    if (day==1)
    {
        c->TextRect (rect, DrawParams->GroupText, TTextFormat () << tfSingleLine << tfCenter << tfTop);
    }
}

I was thinking of calling the Invalidate() method of the TCalendarView somewhere, but I wouldn't know where and how, and whether that's even the correct approach. Maybe the drawing method itself is wrong somewhere, but I'm a bit stuck here. On other controls, the DoubleBuffered property sometimes fixes drawing or especially flickering issues I might have, but this is not available on this control.

Edit: Ok, I now tried to build an own class that inherits TCalendarView and implemented the OnMouseMove and OnMouseLeave event handlers which call Invalidate(). This seems like an ugly and very wrong workaround, but it kind of does the trick. It still flickers a bit when you move the mouse though, as the cells are still blanking for a split second. Plus it interferes with e. g. the animations when you go from day to month view, or from month to year or vice versa.

Is there any other (and probably much better) way how to handle this?

0

There are 0 answers