Я использую код в первом ответе на этот вопрос: How can we vertically align text in edit box?, чтобы центрировать текст в элементе управления CEdit вертикально.Унаследованное управление CEdit (для текста с вертикальным центром) ведет себя странно
Здесь используется класс CEditVC
/// 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();
}
У меня есть новый CEdit унаследовал контроль, созданный таким образом:
// Header File
CEditVC *mp_inputUser;
// Source File
OnInitDialog()
{
mp_inputUser = new CEditVC();
mp_inputUser->Create(WS_VISIBLE | WS_CHILD, CRect(10,10,100,100), this, 1);
}
Но контроль не показывает курсор, и если я печатаю характер она отрываясь на 2 части и действует очень странно.
Что может быть причиной этого? Есть ли более поздняя (лучшая) версия этого?
'top' -' bottom' = '106'. Какие еще операции вы выполняете на 'rectClient' между вызовом' GetClientRect' и 'ClientToScreen'? Вы уверены, что эти вызовы сделаны в правильном/одном окне? –
Я не хотел публиковать код еще раз. Я связал ответ с кодом. Там вы можете увидеть, что происходит с clientRect. – Vinzenz
Это просто делает его менее полезным для людей, которые ищут решение этой или подобных проблем. Это также требует, чтобы каждый, кто смотрит на ваш вопрос, следил за ссылкой, чтобы проверить код. Включите в свой вопрос _relevant_ части кода, и вы уменьшите количество усилий для каждого другого. –