Visual C++ MFC CScrollView: caret stops flashing

Zoltán Hegedüs 101 Reputation points
2021-04-05T08:49:58.047+00:00

My English is not perfect. I am using Visual C++ 2019 16.9.3 Community Edition with MFC, AMD64 Release. Single-document and multiple-document programs are concerned so. Example program: a single-document program.

Base of View class is CScrollView. The caret flashs only some seconds, after it, stops flashing.

void CsdView::OnDraw(CDC *pDC) {
    HideCaret();
    CPoint  const pos = GetDeviceScrollPosition();
    CRect rect;
    GetClientRect(&rect);
    OffsetRect(&rect, pos.x, pos.y);
    pDC->FillSolidRect(rect, 0xFFFFFF);
    CFont   font;
    font.CreatePointFont(90, L"Consolas");
    const auto  oldfont = pDC->SelectObject(&font);
    wchar_t a[12];
    for (int y = (pos.y / 54) * 54; y < rect.bottom; y += 54)
        pDC->TextOutW(8, y, _itow(y, a, 10));
    pDC->SelectObject(oldfont);
    ShowCaret();
}

void CsdView::OnInitialUpdate() {
    CScrollView::OnInitialUpdate();
    CScrollView::SetScrollSizes(MM_TEXT, { 2560, 40000 });
}

BOOL CsdView::OnEraseBkgnd(CDC *) {
    return  TRUE;
}

void CsdView::OnSize(UINT nType, int x, int y) {
    CScrollView::OnSize(nType, x, y);
    SetScrollSizes(MM_TEXT,
        {2560, 40000},
        {(x/20)*20, (y/54)*54},
        {20, 54});
}

void CsdView::OnSetFocus(CWnd *pOldWnd) {
    CScrollView::OnSetFocus(pOldWnd);
    CreateSolidCaret(4, 48);
    SetCaretPos({0, 0});
    ShowCaret();
}

void CsdView::OnKillFocus(CWnd *pNewWnd) {
    CScrollView::OnKillFocus(pNewWnd);
    HideCaret();
}

I am using a high DPI monitor, there is 3 * 96 dpi = 288 dpi at setting in Windows.

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,526 questions
0 comments No comments
{count} votes

Accepted answer
  1. Viorel 112.1K Reputation points
    2021-04-05T10:39:28.957+00:00

    The same behaviour can be observed for other programs, such as Notepad, or various fields of system dialogs. It seems that there is a system-wide configuration parameter: https://www.bing.com/search?q=CaretTimeout+OR+SPI_SETCARETTIMEOUT. The limitation was probably added purposely.

    If for some reason you do not like the recommended behaviour, maybe create a timer, using an interval that depends on setting values, handle WM_TIMER, call HideCaret and ShowCaret. Stop the timer if the view is unfocused.


0 additional answers

Sort by: Most helpful