TheRidiculousChannel
TheRidiculousChannel

Reputation: 23

Constant Flickering of ExtTextOut text, and after a set amount of time the text reverts to the default font

This is my first post, so please forgive any mistakes.

I am working with win32 c++, and I have a basic window that will give the date and time (including seconds), and update accordingly. Additionally, I've made it so the text will change position a slight amount according to the mouse position (almost like this demo, https://css-tricks.com/animate-a-container-on-mouse-over-using-perspective-and-transform/ but it moves x and y, not z according to mouse position). Whenever I run my code, however, I get this flickering on my text where it goes white for an instant then appears on the screen again. I think this is because I'm painting certain pixels twice, but I can't figure out how to fix it. Furthermore, after a certain amount of time (say 1-2 minutes), my font on my text will revert to the default font. During debug I can see the process memory continuously increases to 20, then the font changes to the default and it goes down again. Any ideas? I think somewhere in this section I messed up:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {


switch (message)
{
case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    }
    break;
  #define SECOND_TIMER 2
case WM_TIMER:
    if (wParam == SECOND_TIMER)
    {
        InvalidateRect(hWnd, NULL, TRUE); // invalidate whole window
    }
    break;
//case WM_ERASEBKGND:
  //  return 1;

case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);

        POINT point;
        GetCursorPos(&point);
        ScreenToClient(hWnd, &point);
        ClickAnim(point.x, point.y, hdc);

        SetTimer(hWnd, SECOND_TIMER, SECOND_TIMER, NULL);

        HFONT hFont = CreateFont(70, 30, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
            CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, TEXT("Segoe UI Light"));
        SelectObject(hdc, hFont);

        TCHAR time[100];
        TCHAR date[100];
        SYSTEMTIME localTime;
        GetLocalTime(&localTime);
        wsprintfW(time, L"%.2u:%.2u:%.2u", localTime.wHour, localTime.wMinute, localTime.wSecond);
        switch (localTime.wMonth)
        {
            case 1:
                wsprintfW(date, L"Jan %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 2:
                wsprintfW(date, L"Feb %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 3:
                wsprintfW(date, L"Mar %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 4:
                wsprintfW(date, L"Apr %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 5:
                wsprintfW(date, L"May %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 6:
                wsprintfW(date, L"Jun %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 7:
                wsprintfW(date, L"Jul %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 8:
                wsprintfW(date, L"Aug %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 9:
                wsprintfW(date, L"Sep %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 10:
                wsprintfW(date, L"Oct %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 11:
                wsprintfW(date, L"Nov %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
            case 12:
                wsprintfW(date, L"Dec %.2u, %.2u", localTime.wDay, localTime.wYear);
                break;
        }

        RECT desktop;
        // Get a handle to the desktop window
        const HWND hDesktop = GetDesktopWindow();
        // Get the size of screen to the variable desktop
        GetClientRect(hDesktop, &desktop);
        // TODO: Add any drawing code that uses hdc here...
        //get dimensions of window
        RECT rect;
        GetClientRect(hWnd, &rect);

        HWND desktophWnd = GetDesktopWindow();


        ExtTextOut(hdc, rect.right / 2 - 95 - point.x / 100, rect.bottom / 2 - 40 - point.y / 100, ETO_OPAQUE, NULL, time, _tcslen(time), NULL);

        HFONT smallFont = CreateFont(35, 15, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
            CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, TEXT("Segoe UI"));
        SelectObject(hdc, smallFont);
        ExtTextOut(hdc, rect.right / 2 - 85 - point.x / 100, rect.bottom / 2 - 70 - point.y / 100, ETO_OPAQUE, NULL, date, _tcslen(date), NULL);



        EndPaint(hWnd, &ps);

    }
    break;
case WM_DESTROY:
    PostQuitMessage(0);
    break;
default:
    return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;

}

Upvotes: 2

Views: 287

Answers (1)

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32732

You call CreateFont a couple of times during your paint, but you never unselect that font from the device context, nor do you delete the font objects. Since the fonts are the always the same, just create them once and reuse that object. This will cut down some on the paint time.

As for the flicker, the third parameter to InvalidateRect should be FALSE (so that the background is not erased when BeginPaint is called). When you go to paint your window, erase the part of the window that you will be filling (possibly including the previous location of the time). Also do as much work as possible before calling BeginPaint. This will reduce the flicker but may not eliminate it entirely. To eliminate it entirely will require some sort of double buffering.

Upvotes: 1

Related Questions