Как выровнять текст по вертикали в элементе управления редактирования в MFC [дубликат]

Я отвечу ужасным, нарисованным рукой комиком. Второе изображение является причиной того, что result является undefined в вашем примере кода.

7
задан poundifdef 22 November 2013 в 04:07
поделиться

4 ответа

Вот класс, который наследует CEdit и позволяет вертикальное выравнивание

/// HEADER //////////////////////////////////////////

class CEditVC : public CEdit
{
public:
    CEditVC();

protected:
    CRect m_rectNCBottom;
    CRect m_rectNCTop;

public:
    virtual ~CEditVC();

protected:
    afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp);
    afx_msg void OnNcPaint();
    afx_msg UINT OnGetDlgCode();

    DECLARE_MESSAGE_MAP()
};

/// IMPLEMENTATION /////////////////////////////////////////

CEditVC::CEditVC()
    : m_rectNCBottom(0, 0, 0, 0)
    , m_rectNCTop(0, 0, 0, 0)
{
}

CEditVC::~CEditVC()
{
}

BEGIN_MESSAGE_MAP(CEditVC, CEdit)
    ON_WM_NCCALCSIZE()
    ON_WM_NCPAINT()
    ON_WM_GETDLGCODE()
END_MESSAGE_MAP()

void CEditVC::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
{
    CRect rectWnd, rectClient;

    //calculate client area height needed for a font
    CFont *pFont = GetFont();
    CRect rectText;
    rectText.SetRectEmpty();

    CDC *pDC = GetDC();

    CFont *pOld = pDC->SelectObject(pFont);
    pDC->DrawText("Ky", rectText, DT_CALCRECT | DT_LEFT);
    UINT uiVClientHeight = rectText.Height();

    pDC->SelectObject(pOld);
    ReleaseDC(pDC);

    //calculate NC area to center text.

    GetClientRect(rectClient);
    GetWindowRect(rectWnd);

    ClientToScreen(rectClient);

    UINT uiCenterOffset = (rectClient.Height() - uiVClientHeight) / 2;
    UINT uiCY = (rectWnd.Height() - rectClient.Height()) / 2;
    UINT uiCX = (rectWnd.Width() - rectClient.Width()) / 2;

    rectWnd.OffsetRect(-rectWnd.left, -rectWnd.top);
    m_rectNCTop = rectWnd;

    m_rectNCTop.DeflateRect(uiCX, uiCY, uiCX, uiCenterOffset + uiVClientHeight + uiCY);

    m_rectNCBottom = rectWnd;

    m_rectNCBottom.DeflateRect(uiCX, uiCenterOffset + uiVClientHeight + uiCY, uiCX, uiCY);

    lpncsp->rgrc[0].top +=uiCenterOffset;
    lpncsp->rgrc[0].bottom -= uiCenterOffset;

    lpncsp->rgrc[0].left +=uiCX;
    lpncsp->rgrc[0].right -= uiCY;

}

void CEditVC::OnNcPaint() 
{
    Default();

    CWindowDC dc(this);
    CBrush Brush(GetSysColor(COLOR_WINDOW));

    dc.FillRect(m_rectNCBottom, &Brush);
    dc.FillRect(m_rectNCTop, &Brush);
}

UINT CEditVC::OnGetDlgCode() 
{
    if(m_rectNCTop.IsRectEmpty())
    {
        SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
    }

    return CEdit::OnGetDlgCode();
}
7
ответ дан Aidan Ryan 27 August 2018 в 23:56
поделиться

У меня недостаточно репутации, чтобы сделать комментарий, так что, возможно, полезный фрагмент к очень старому вопросу!

Если вы предоставите стиль WS_BORDER, тогда текст будет автоматически центрироваться по центру, как просили. Поскольку OP использует WS_EX_CLIENTEDGE, в любом случае граница нарисована , поэтому добавление этого стиля не должно быть проблемой.

Однако WS_BORDER | WS_EX_CLIENTEDGE достигает только " частичное "вертикальное центрирование.

Использование WS_BORDER | WS_EX_STATICEDGE обеспечивает правильное, вертикальное центрирование, хотя, очевидно, тогда у нас есть немного отличающийся визуальный стиль к клик-обрамленному стилю. Для меня я мог бы жить с этим небольшим компромиссом, вместо того, чтобы писать настраиваемый элемент управления.

1
ответ дан dicksters 27 August 2018 в 23:56
поделиться

это невозможно, насколько я знаю. Но вы можете реализовать свой собственный контроль, чтобы сделать это возможным.

Посмотрите на эту статью .

Надеюсь, что это поможет.

Кстати, это вопрос, который он заслуживает google перед публикацией. Вы можете найти много таких вещей уже в Интернете.

1
ответ дан Javier De Pedro 27 August 2018 в 23:56
поделиться

Я попробовал решение от @Aidan Ryan с небольшой настройкой, чтобы избежать другой проблемы, связанной с пользовательским интерфейсом. Я перемещаю «SetWindowPos» в OnNCPaint () и вызываю функцию только один раз.

1
ответ дан Thành Long Nguyễn 27 August 2018 в 23:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: