Posted on 2009-06-01 22:55
syzfeng 阅读(2944)
评论(0) 编辑 收藏 引用
首先要感谢网络和网友,许多写程序过程中遇到的问题是借助网络解决的,网友对于我遇到的类似问题的解答给我提供了很多思路,当然还有MSDN,我的水平才会不断提高,可能以后也不会再用vc++6.0开发软件了,花点时间将以前的成果总结一下。
工程示例实现的美化内容包括:
- 给工程添加背景图与文字:图的位置、大小,文字的字体、大小均可以通过更改参数来改变;
- 完全手动绘制链接效果的按钮;并带有实时提示功能;
- 解决刷新界面时的闪烁问题;
具体实现过程如下:
- 为方便使用MFC提供的控件,我们建立单文档工程时将视类的基类选为CFormView类
如果是基于对话框的工程,直接“完成”就行了。
2 闪屏的解决。
因为需要图像图形的操作,很多代码可能会放到OnDraw(),或者OnPaint()函数里执行,那样就会导致刷新界面时的闪烁,原因网上介绍的很多,解决方法也很多,本文采用利用兼容DC(也叫内存DC)的方法实现,思路是在内存中建立一块和界面一样大小的位图,将所有在界面上的绘制操作现在内存位图里画好,然后再一并复制到显示设备地址上去,(原理说的不是很严谨,不过就那意思)
代码送上:
void CEODSVer2_1View::OnDraw(CDC* pDC)


{
// TODO: Add your specialized code here and/or call the base class
CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap;//定义一个位图对象
MemDC.CreateCompatibleDC(NULL);
CRect rt;
GetClientRect(&rt);
MemBitmap.CreateCompatibleBitmap(pDC,rt.Width(),rt.Height()); //建立与屏幕显示兼容的位图,
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); //将位图选入到内存设备中
//设置背景色
MemDC.FillSolidRect(0,0,rt.Width(),rt.Height(),COLOR_BKGD);

/**//****************************************************************************/
这里实现绘图的所有操作

/**//**********************************************************************************************/
pDC->BitBlt(0,0,rt.Width(),rt.Height(),&MemDC,0,0,SRCCOPY); //将内存图拷贝到屏幕上进行显示
MemBitmap.DeleteObject(); //绘图完成后的清理
MemDC.DeleteDC();
//InvalidateRect(m_Button_Logon,FALSE);
}
3 添加背景图片与文字。
这个简单,在OnDraw()函数里实现 ^_^ 代码送上:

/**//************************************************************************/

/**//* 贴背景图与写大标题 */

/**//********************begin x**********************************************/
CBitmap bitmap;
BITMAP bmp;
bitmap.LoadBitmap(IDB_BITMAP1);
bitmap.GetBitmap(&bmp);
CDC pCompatableDC1;
pCompatableDC1.CreateCompatibleDC(&MemDC);// MemDC是上文提到的DC,所有绘图操作都在兼容DC里完成
pCompatableDC1.SelectObject(&bitmap);
MemDC.SetStretchBltMode(HALFTONE); // 防止位图缩小时失真
CRect m_Area_Title;
GetClientRect(&m_Area_Title); //获得显示位图的区域,
MemDC.StretchBlt(m_Area_Title.left,//这四个参数表示显示位图到哪个区域
m_Area_Title.top,
m_Area_Title.Width(),
m_Area_Title.Height()-200,
&pCompatableDC1,
0,0,bmp.bmWidth,bmp.bmHeight, //这四个参数表示要显示位图的哪部分,现在显示全部位图
SRCCOPY);
MemDC.SetBkMode(TRANSPARENT);
CFont m_font_title;
m_font_title.CreatePointFont(220,"仿宋_GB2312"); //设置标题的字体与大小
MemDC.SelectObject(&m_font_title);
MemDC.SetTextColor(RGB(255,0,0));
MemDC.DrawText("测试系统",
CRect(0,0,m_Area_Title.Width(),m_Area_Title.Height()), //写文字的矩形区域,可以自己更改

DT_CENTER|/**//*DT_VCENTER|*/DT_SINGLELINE);

/**//**************************end x***************************************/
效果图:

4 带提示功能的链接效果的按钮(不是tip)
效果如图:


需要添加的代码
首先需要添加3个成员变量与一个函数:
1
CRect m_Button_1;
2
CRect m_Button_2;
3
CRect m_Area_3;
4
void DrawButtonText(CDC* pmemdc,CRect rc, CString text,CString describe,CRect area_describe, COLORREF textcolor, BOOL underline=FALSE );
5
OnInitialUpdate()里添加的代码有:
1
void CInterfaceView::OnInitialUpdate()
2

{
3
CFormView::OnInitialUpdate();
4
GetParentFrame()->RecalcLayout();
5
ResizeParentToFit();
6
GetDlgItem(IDC_STATIC1)->GetWindowRect(&m_Button_1);
7
GetDlgItem(IDC_STATIC2)->GetWindowRect(&m_Button_2);
8
GetDlgItem(IDC_STATIC3)->GetWindowRect(&m_Area_3);
9
ScreenToClient(&m_Button_1);
10
ScreenToClient(&m_Button_2);
11
ScreenToClient(&m_Area_3);
12
m_Area_3.InflateRect(-5,-20,-5,-20);
13
}
然后添加鼠标移动消息响应函数:
1
void CInterfaceView::OnMouseMove(UINT nFlags, CPoint point)
2

{
3
// TODO: Add your message handler code here and/or call default
4
CDC *pClientDC= GetDC();
5
static BOOL iswrite_Button_1=FALSE;
6
static BOOL iswrite_Button_2=FALSE;
7
if (m_Button_1.PtInRect(point)) //如果鼠标在登录按钮内
8
{
9
SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR1));
10
if (!iswrite_Button_1) //只写一次
11
{
12
DrawButtonText(pClientDC,m_Button_1,
13
"按钮1",
14
"按钮1",
15
m_Area_3,RGB(42,95,170),TRUE);
16
iswrite_Button_1=TRUE;
17
}
18
}else if(m_Button_2.PtInRect(point)) //鼠标不在上述按钮但在退出内
19
{
20
SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR1)); //设置光标为手型
21
if (!iswrite_Button_2) //只写一次
22
{
23
DrawButtonText(pClientDC,m_Button_2,
24
"第二个按钮",
25
"第二个按钮",
26
m_Area_3,RGB(42,95,170),TRUE);
27
iswrite_Button_2=TRUE;
28
}
29
}else
{ //鼠标不在上述按钮内时
30
InvalidateRect(&m_Area_3,FALSE); //刷新描述区
31
m_Button_1.InflateRect(-1,-1,-1,-1);
32
m_Button_2.InflateRect(-1,-1,-1,-1);
33
InvalidateRect(&m_Button_1,FALSE);
34
InvalidateRect(&m_Button_2,FALSE);
35
m_Button_1.InflateRect(1,1,1,1);
36
m_Button_2.InflateRect(1,1,1,1);
37
iswrite_Button_1=FALSE;
38
iswrite_Button_2=FALSE;
39
}
40
ReleaseDC(pClientDC);
41
CFormView::OnMouseMove(nFlags, point);
42
}
在OnDraw()函数里添加的代码有:
MemDC.FillSolidRect(m_Button_1,RGB(175,202,228));
MemDC.FillSolidRect(m_Button_2,RGB(175,202,228));
DrawButtonText(&MemDC,m_Button_1,"按钮1","",m_Area_3,RGB(0,0,0));
DrawButtonText(&MemDC,m_Button_2,"第二个按钮","",m_Area_3,RGB(0,0,0));
然后是DrawButtonText()的实现:
1
void CInterfaceView::DrawButtonText(CDC* pmemdc,CRect rc, CString text,CString describe,CRect area_describe, COLORREF textcolor, BOOL underline)
2

{
3
pmemdc->SetBkMode(TRANSPARENT);
4
CFont m_font_text;
5
m_font_text.CreatePointFont(120,"仿宋_GB2312");
6
pmemdc->SelectObject(&m_font_text);
7
pmemdc->SetTextColor(textcolor);
8
pmemdc->DrawText(text, rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
9
pmemdc->DrawText(describe, area_describe, DT_LEFT);
10
11
CSize sz=pmemdc->GetTextExtent(text);
12
if (underline) //绘制下划线
13
{
14
CPen UnderLinePen;
15
UnderLinePen.CreatePen(PS_SOLID,1,RGB(0,0,0));
16
pmemdc->SelectObject(&UnderLinePen);
17
18
pmemdc->MoveTo(rc.left+(rc.Width()-sz.cx)/2,rc.bottom-(rc.Height()-sz.cy)/2);
19
pmemdc->LineTo(rc.right-(rc.Width()-sz.cx)/2,rc.bottom-(rc.Height()-sz.cy)/2);
20
}
21
else
22
{
23
CPen UnderLinePen;
24
UnderLinePen.CreatePen(PS_SOLID,1,RGB(175,202,228));
25
pmemdc->SelectObject(&UnderLinePen);
26
pmemdc->MoveTo(rc.left+(rc.Width()-sz.cx)/2,rc.bottom-(rc.Height()-sz.cy)/2);
27
pmemdc->LineTo(rc.right-(rc.Width()-sz.cx)/2,rc.bottom-(rc.Height()-sz.cy)/2);
28
}
29
}
到此实现了简单的按钮功能,如果需要添加按钮响应函数可以在鼠标左击、右击等消息响应函数里实现;效果虽然没有CButtonST好,但是更节省代码与内存资源占用,如果要实现按钮的动态效果,可以在按钮四周画不同颜色的线,把文字侧移一下(实际上微软按钮效果就是那样实现的),第一篇先到此为止。
工程下载:
/Files/syzfeng/interface-blog.rar