实现一个简单的计算器,类似于Windows自带的计算器。从中学习一下内容:
1、设计一个基于对话框的应用程序的基本步骤:
首先,创建一个给予对话框的工程文件;其次,编辑对话框并添加所需要的控件等资源,实现完成大致的界面出来;再次,对各个部分的功能,如菜单,控件等的相关操作分别进行编程实现预定的要求;然后,在各个程序块之间建立联系,比如互相调用或引用其成员变量或成员函数等;最后,进行整体调试,测试并实现最终功能。
首先,创建一个给予对话框的工程文件;其次,编辑对话框并添加所需要的控件等资源,实现完成大致的界面出来;再次,对各个部分的功能,如菜单,控件等的相关操作分别进行编程实现预定的要求;然后,在各个程序块之间建立联系,比如互相调用或引用其成员变量或成员函数等;最后,进行整体调试,测试并实现最终功能。
2、学会制作高级控件按钮,该按钮具有不规则的形状,可以识别用户鼠标的位置及单击状态,并以此来显示不同的颜色。创建一个高级按钮类CAdvButton,其父类为CButton。大致程序如下:
高级按钮常用的成员变量:
CRect m_ClientRect; //用来保存按钮的客户的矩形区域
CRgn m_ClientRgn; //用来保存按钮的客户区域,非矩形
UINT m_State; //按钮所处状态,识别鼠标的移动及单击
CPoint m_Point; //当前鼠标的位置
CRect m_ClientRect; //用来保存按钮的客户的矩形区域
CRgn m_ClientRgn; //用来保存按钮的客户区域,非矩形
UINT m_State; //按钮所处状态,识别鼠标的移动及单击
CPoint m_Point; //当前鼠标的位置
在CAdvButton类的构造函数中对成员变量进行初始化:
m_ClientRect.left=0;
m_ClientRect.top=0;
m_ClientRect.right=0;
m_ClientRect.bottom=0;
m_ClientRect.left=0;
m_ClientRect.top=0;
m_ClientRect.right=0;
m_ClientRect.bottom=0;
m_ClientRgn.DeleteObject(); //删除区域对象
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect); //创建椭圆区域
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect); //创建椭圆区域
m_State=0;
m_Point.x=m_Point.y=0
m_Point.x=m_Point.y=0
CAdvButtonl类属于用户自绘制按钮,所以要在PreSubclassWindow函数里面将按钮的风格设置为BS_OWNERDRAW(PreSubclassWindow函数是在窗口被创建前被调用的),这样在当前按钮可见部分被重绘时会自动调用DrawItem函数,否则不会调用。
ModifyStyle(0,BS_OWNERDRAW|BS_PUSHBUTTON);
ModifyStyle(0,BS_OWNERDRAW|BS_PUSHBUTTON);
添加OnLButtonDown、OnLButtonUp及OnMouseMove等事件,执行相应的操作.
CRect rect;
GetWindowRect(&rect); //得到按钮客户区域的屏幕坐标位置
GetCursorPos(&m_Point); //得到鼠标的屏幕坐标位置
if(rect.PtInRect(m_Point)); //判断当前鼠标是否在按钮客户区域内
CRect rect;
GetWindowRect(&rect); //得到按钮客户区域的屏幕坐标位置
GetCursorPos(&m_Point); //得到鼠标的屏幕坐标位置
if(rect.PtInRect(m_Point)); //判断当前鼠标是否在按钮客户区域内
为了能够对一些成员变量或参数进行获得其当前值或修改,故启用定时器消息响应函数
OnTimer(UINT nIDEvent);在OnMouseMove事件中,启动定时器SetTimer(1,100,NULL);来触发定时器消息响应。在OnTimer函数处理完之后,关闭定时器KillTimer(nIDEvent)。
OnTimer(UINT nIDEvent);在OnMouseMove事件中,启动定时器SetTimer(1,100,NULL);来触发定时器消息响应。在OnTimer函数处理完之后,关闭定时器KillTimer(nIDEvent)。
按钮客户区的绘制是通过虚函数DrawItem来实现的,首先得到窗口的有效矩形区域,在此区域创建所需的形状,调用SetWindowRgn()函数来设置窗口的有效区域为所需形状。
GetClientRect(&m_ClientRect); //得到窗口的有效矩形区域
m_ClientRgn.DeleteObject();
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect); //在矩形区域创建椭圆
SetWindowRgn(m_ClientRgn,FALSE); //设置窗口的有效区域为椭圆
CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
//得到按钮控件客户区域的设备环境变量指针
CPen* pPen=NULL; //创建画笔
switch(m_State)
{ case 0: pPen=new CPen(PS_SOLID,RGB(225,225,255);break;)
case 1: ....} //根据按钮的不同状态来创建不同的画笔
pDC->SetBkMode(TRANSPARENT); //设置背景模式为透明
pPen=pDC->SelectObject(pPen);
pDC->Ellipse(&m_ClientRect);
pPen=pDC->SelectObject(pPen);
if(pPen) delete pPen;
LPTSTR pCaption=new char[MAXCAPTIONLEN];
int iLen=GetWindowText(pCaption,MAXCAPTIONLEN);
pDC->SetTextColor(RGB(128,128,128)); //指定文本颜色
pDC->DrawText(pCaption,iLen,&m_ClientRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER); //绘制文本,作为按钮标题
GetClientRect(&m_ClientRect); //得到窗口的有效矩形区域
m_ClientRgn.DeleteObject();
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect); //在矩形区域创建椭圆
SetWindowRgn(m_ClientRgn,FALSE); //设置窗口的有效区域为椭圆
CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
//得到按钮控件客户区域的设备环境变量指针
CPen* pPen=NULL; //创建画笔
switch(m_State)
{ case 0: pPen=new CPen(PS_SOLID,RGB(225,225,255);break;)
case 1: ....} //根据按钮的不同状态来创建不同的画笔
pDC->SetBkMode(TRANSPARENT); //设置背景模式为透明
pPen=pDC->SelectObject(pPen);
pDC->Ellipse(&m_ClientRect);
pPen=pDC->SelectObject(pPen);
if(pPen) delete pPen;
LPTSTR pCaption=new char[MAXCAPTIONLEN];
int iLen=GetWindowText(pCaption,MAXCAPTIONLEN);
pDC->SetTextColor(RGB(128,128,128)); //指定文本颜色
pDC->DrawText(pCaption,iLen,&m_ClientRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER); //绘制文本,作为按钮标题
本文转自jazka 51CTO博客,原文链接:http://blog.51cto.com/jazka/162796,如需转载请自行联系原作者