Постоянное мерцание текста ExtTextOut, и по прошествии определенного времени текст возвращается к шрифту по умолчанию - PullRequest
1 голос
/ 29 мая 2020

Это мой первый пост, поэтому прошу прощения за любые ошибки.

Я работаю с win32 c ++, и у меня есть основное окно c, в котором будут указаны дата и время (включая секунды) и обновите соответственно. Кроме того, я сделал так, чтобы текст немного менял положение в зависимости от положения мыши (почти как в этой демонстрации, https://css-tricks.com/animate-a-container-on-mouse-over-using-perspective-and-transform/, но он перемещает x и y, а не z в соответствии с положением мыши) . Однако всякий раз, когда я запускаю свой код, у меня появляется это мерцание на моем тексте, который на мгновение становится белым, а затем снова появляется на экране. Я думаю, это потому, что я дважды закрашиваю определенные пиксели, но не могу понять, как это исправить. Кроме того, через определенное время (скажем, 1-2 минуты) мой шрифт в моем тексте вернется к шрифту по умолчанию. Во время отладки я вижу, что память процесса постоянно увеличивается до 20, затем шрифт меняется на значение по умолчанию и снова падает. Любые идеи? Думаю, где-то в этом разделе я напортачил:

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;

}

1 Ответ

1 голос
/ 30 мая 2020

Вы вызываете CreateFont пару раз во время рисования, но вы никогда не снимаете выделение этого шрифта в контексте устройства и не удаляете объекты шрифта. Поскольку шрифты всегда одни и те же, просто создайте их один раз и повторно используйте этот объект. Это немного сократит время рисования.

Что касается мерцания, третий параметр InvalidateRect должен быть FALSE (чтобы фон не стирался при вызове BeginPaint). Когда вы go закрашиваете окно, сотрите ту часть окна, которую вы будете заполнять (возможно, включая предыдущее местоположение времени). Также сделайте как можно больше работы, прежде чем звонить по номеру BeginPaint. Это уменьшит мерцание, но не может полностью его устранить. Чтобы полностью его устранить, потребуется какая-то двойная буферизация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...