让单行编辑框文本垂直居中,可以有多种方法:
(1)将文本框样式重设为多行文本框,然后通过消息 EM_SETRECT设置,这比较简单和快速;
(2)重绘编辑框的区域,特别是顶部区域,扩大它,让区域的扩展衬托出文本的居中;
(3)直接改变字体和编辑框高度,让他们相适应,也可以显示出文本框垂直居中效果;
(4)完全重绘编辑框,这样的自定制是最好的了,但这个工作繁重;
(5)把编辑框中可输入文本的区域移到编辑框区域的垂直中部,这样也可以达到目的。
每种方法各有优劣,本文介绍的是最后一种方法,虽取巧,但这也算得上是真正意义上
的垂直居中。
重写了类,继承自CEdit,可以使VC编辑框文本垂直居中,另外也实现了颜色和背景色的设置,效果如下:
有了这个类,其他的很多效果就可以自己去扩展了。扩展类响应了两个消息,WM_NCCALCSIZE用来改变编辑框文本区域的位置,=WM_CTLCOLOR用来设置编辑框的显示特性。
该效果的实现主要是在WM_NCCALCSIZE消息的响应函数OnNcCalcSize中,根据所设置的字体计算文本高宽像素值,然后再设置参数lpncsp->rgrc[0].top的值。代码如下:
void CVEdit::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(!m_pFont)
{
CEdit::OnNcCalcSize(bCalcValidRects, lpncsp);
return ;
}
// 用来计算的样本数据
CString csTest = _T("编辑框VCenterAlign");
SIZE sz;
// 创建DC,设置参照计算的字体
CDC* pDC = GetDC();
CFont* pOldFont = pDC->SelectObject(m_pFont);
// 计算 m_Font 字体的字符高宽
GetTextExtentPoint32(pDC->GetSafeHdc(), csTest, csTest.GetLength(), &sz);
pDC->SelectObject(pOldFont);
// 编辑框的上下左右边框,默认各为2像素,下面的高度计算中需要减去上下边框高度
int nFrame = 2*2;
// 编辑框默认可编辑区顶部也有1个像素边框
int nTextTopFrame = 1;
double dTemp = (lpncsp->rgrc[0].bottom-lpncsp->rgrc[0].top-sz.cy-nFrame)/2.0 ;
if(dTemp>(int)dTemp)
dTemp = (double)( (int)dTemp+1 );
int nBorder = (int)dTemp -nTextTopFrame;
if(nBorder<0)
nBorder = 0;
lpncsp->rgrc[0].top += nBorder;
//lpncsp[0].rgrc->bottom = lpncsp[0].rgrc->top + sz.cy + nBorder;
CEdit::OnNcCalcSize(bCalcValidRects, lpncsp);
}
不过当设置了字体后,需要更新窗口才能触发 WM_NCCALCSIZE 消息,在重建字体的函数中(在设置字体函数中被调用),用了MoveWindow来触发它,值得注意的是,此时窗口尺寸必须有变化才行。
void CVEdit::SetFontHelper()
{
// 重新创建字体,为节约篇幅代码已删除
SetFont(m_pFont);
// 通过 MoveWindow 触发 WM_NCCALCSIZE 消息的发送,需注意必须窗口大小有变化时才能触发成功
CRect rcClient;
GetWindowRect(&rcClient);
GetParent()->ScreenToClient(&rcClient);
// 改变窗口大小,触发 WM_NCCALCSIZE
MoveWindow(rcClient.left, rcClient.top, rcClient.Width()+1, rcClient.Height());
// 恢复窗口大小,也触发了 WM_NCCALCSIZE
MoveWindow(rcClient.left, rcClient.top, rcClient.Width()-1, rcClient.Height());
}
通过上面的操作后,便可以让编辑框文本输出的左上角坐标定位到编辑框垂直中部,但此时编辑框的背景已分离成了几块,所以需要重绘背景,DrawBkAndFrame函数作此工作,边框也可以再次绘制,例中未绘。
此类还提供了设置字体样式的接口,包括加粗、倾斜、下划线,这些简单的扩展不再解释,可参考源代码。
代码下载地址:http://download.csdn.net/detail/yaoyuanyylyy/5861345