静态控件也是比较常用的控件,在VS开发环境中用的应该挺频繁的吧。
其实mfc中实现对窗口美化,主要依赖于重绘。static控件也是个窗口,windows为其留有自绘的权利,可以设置其样式为SS_OWNERDRAW,Windows就会把其绘制权利交给我们的代码,怎么绘制就看我们的代码了。mfc中更好的一种方式就是消息反射,省的自己来做这一步操作了,我们重载CStatic中的DrawItem方法,进行自绘,基本就可以了。其实如果自己在OnPaint里画也是可以的(对于任何控件窗口都可以的,只是麻烦或者有其他的问题)。
我们可以给CStatic中加入背景图片,画成按钮样式,等等,可以模拟出其他的控件(像CButton),如果CStatic要响应事件我们可以加上SS_NOTIFY样式,这样父窗口就会把消息传递到CStatic里面来,要怎么处理就看我们了。
下面看下具体怎么做:
第一要设置继承CStatic类,我们自己写一个Static类,我给他起了CSkinStatic的名字。
第二,设置其样式为SS_OWNERDRAW,设置样式可以在Static控件创建前后都可以,但要在其显示前,我这里在CSkinStatic::PreSubclassWindow()中进行设置
void CSkinStatic::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类
DWORD dwStyle = GetStyle();
SetWindowLong(GetSafeHwnd(),GWL_STYLE,dwStyle | SS_OWNERDRAW );
CStatic::PreSubclassWindow();
}
第三,就是重载DrawItem,然后在里面想怎么画就怎么画了。
void CSkinStatic::DrawItem(LPDRAWITEMSTRUCT /* lpDrawItemStruct */ )
{
CRect rcWnd;
GetWindowRect( & rcWnd);
ScreenToClient( & rcWnd);
CString strText;
GetWindowText(strText);
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
BITMAP bmpInfo;
bmp.GetBitmap( & bmpInfo);
CDC * pdc = GetWindowDC();
CDC dcMem;
dcMem.CreateCompatibleDC(pdc);
CBitmap bmpBg;
bmpBg.CreateCompatibleBitmap(pdc,rcWnd.Width(),rcWnd.Height());
dcMem.SelectObject( & bmpBg);
CDC dcDraw;
dcDraw.CreateCompatibleDC(pdc);
dcDraw.SelectObject( & bmp);
dcMem.StretchBlt( 0 , 0 ,rcWnd.Width(),rcWnd.Height(), & dcDraw, 0 , 0 ,bmpInfo.bmWidth,bmpInfo.bmHeight,SRCCOPY);
CFont font;
VERIFY(font.CreateFont(
12 , // nHeight
0 , // nWidth
0 , // nEscapement
0 , // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0 , // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
" 宋体 " )); // lpszFacename
dcMem.SelectObject( & font);
dcMem.SetBkMode(TRANSPARENT);
dcMem.SetTextColor(RGB( 255 , 0 , 0 ));
dcMem.DrawText(strText, & rcWnd,DT_CENTER);
pdc -> BitBlt( 0 , 0 ,rcWnd.Width(),rcWnd.Height(), & dcMem, 0 , 0 ,SRCCOPY);
bmp.DeleteObject();
ReleaseDC(pdc);
}
这个绘图稍有点麻烦,大致是这样的 先创建内存两个内存DC一个作为画布,另一个负责引入图片,再拉伸拷贝到画布DC上,最后画布DC全部拷贝到窗口DC上。这主要是防止贴图和写文字不同步,造成有图无字,也避免了一个内存DC造成的字体拉伸。运用了网上盛传的双缓冲。
经过我们自己的代码处理后,可以看看Static成什么样了
当然可以自己画个渐变色出来。不过个人觉得还是贴图方便。
Static控件的美化比较简单,没有什么多的消息要进行处理。不过要想设置个性的,也得需要几个状态变量,多个图片吧。
基本的东西都很好做,如果想做好点细腻点,总会有点麻烦的。