Winapi - живопись богатых править тонкую границу - PullRequest
0 голосов
/ 14 января 2020

По умолчанию элемент управления rich edit имеет «3d» рамку. Я рисую тонкую границу вокруг элемента управления расширенного редактирования следующим образом:

if (message == WM_NCPAINT)
{
    RECT rc;
    HDC  hdc;
    HPEN  pen;
    HBRUSH brush;
    HGDIOBJ oldP, oldB;
    POINT tl, br;

    ::GetWindowRect(hWnd, &rc);
    hdc = ::GetDC(hWnd);
    tl.x = rc.left;
    tl.y = rc.top;
    br.x = rc.right;
    br.y = rc.bottom;
    ::ScreenToClient(hWnd, &tl);
    ::ScreenToClient(hWnd, &br);
    pen = ::CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
    brush = (HBRUSH) ::GetStockObject(HOLLOW_BRUSH);
    oldP = ::SelectObject(hdc, pen);
    oldB = ::SelectObject(hdc, brush);
    ::Rectangle(hdc, tl.x, tl.y, br.x, br.y);
    ::SelectObject(hdc, oldP);
    ::SelectObject(hdc, oldB);
    ::DeleteObject(pen);
    ::ReleaseDC(hWnd, hdc);

    return 0;
}

Граница выглядит хорошо, но область под старой границей не перерисовывается. Похоже, мне нужно перерисовать все содержимое элемента управления rich edit. После этого текст не должен быть немного вырезан снизу. Здесь вы можете видеть, что я имею в виду (второй элемент управления rich edit имеет собственную рамку). Как этого добиться?

1 Ответ

0 голосов
/ 15 января 2020

GetDC возвращает D C для клиентской области. В этом случае вам нужно GetWindowDC для всего окна richedit.

В любом случае переопределение цвета границы при редактировании и расширенном редактировании может быть затруднено, поскольку вам также придется обрабатывать рисование полосы прокрутки в WM_NCPAINT* 1006. *

Предполагая, что вам не нужна вертикальная и / или горизонтальная полоса прокрутки, используйте GetWindowDC следующим образом:

LRESULT CALLBACK RichEditProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
    UINT_PTR, DWORD_PTR)
{
    static int border_thickness = 1;
    switch(msg)
    {
    case WM_NCPAINT:
    {
        HDC hdc = GetWindowDC(hwnd);
        RECT rc;
        GetClientRect(hwnd, &rc);
        rc.right += 2 * border_thickness + 1;
        rc.bottom += 2 * border_thickness + 1;

        HBRUSH hbrush = (HBRUSH)GetStockObject(NULL_BRUSH);
        HPEN hpen = CreatePen(PS_SOLID, 2 * border_thickness, RGB(255, 0, 0));
        HBRUSH oldbrush = (HBRUSH)SelectObject(hdc, hbrush);
        HPEN oldpen = (HPEN)SelectObject(hdc, hpen);
        Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
        SelectObject(hdc, oldpen);
        SelectObject(hdc, oldbrush);
        DeleteObject(hpen);
        DeleteObject(hbrush);

        ReleaseDC(hwnd, hdc);
        return 0;
    }

    case WM_NCCALCSIZE:
        if(lp)
        {
            NCCALCSIZE_PARAMS* sz = (NCCALCSIZE_PARAMS*)lp;
            InflateRect(&sz->rgrc[0], -border_thickness, -border_thickness);
            return 0;
        }
        break;

    case WM_NCDESTROY:
        RemoveWindowSubclass(hwnd, RichEditProc, 0);
        break;
    }

    return DefSubclassProc(hwnd, msg, wp, lp);
}

По умолчанию WM_NCCALCSIZE не вызывается в процедуре подкласса, вы должны вызвать SetWindowPos с SWP_FRAMECHANGED

HWND hrichedit = CreateWindowEx(...);
SetWindowSubclass(hrichedit, RichEditProc, 0, 0);
SetWindowPos(hrichedit, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);

Если вам нужна горизонтальная / вертикальная полоса прокрутки, вы можете рассмотреть возможность использования richedit без полей, а затем рисовать вокруг расширенного элемента управления в процедуре WM_PAINT родительского окна.

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