在VC中动态绘制柱状图
这几天我一直在做这个。发现越是实际的问题想要从书上找到可参考的资料越难。所以贴出来嘎家给挑挑毛病期待提高。呵呵
还有不知道卫生么图片传不上去。有人知道的请指点一下。谢谢
先看一下效果:
1输入部分
2显示(1)
显示(2)
显示(3)
具体步骤
1输入部分验证,看是否输入合法字符
2每一个柱状图都是一个矩形框,用结构将它存储在CArray中
3建立绘图函数
4在下拉列表变化时,输入后的登陆按钮点击时,(OnPaint中调用该函数绘图)
约定:工程名RemoteDlg
1在Remote.cpp中定义
typedef struct _tagPlayTimeSize{
int nTimeStart; //开始时间
int nTimeEnd; //结束时间
} SPlayTimeSize; //放如数组的结构
CArray <SPlayTimeSize,SPlayTimeSize&> g_ArrayTime; //数组
int g_nStartTime,g_nEndTime; //用来传值的全局变量
int g_nTimeMode; //状态标志,因为有三种状态所以用int
2在输入对话框中(TimeSet.cpp)
BOOL CTimeSetDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// m_EditStartHour.,m_EditEndHour.两个编辑框的成员变量
m_EditStartHour.ModifyStyle(0,ES_NUMBER);//只能输入数字
m_EditStartHour.LimitText(2); //最多输入两位
m_EditEndHour.ModifyStyle(0,ES_NUMBER);
m_EditEndHour.LimitText(2);
m_nTimeSize = 0;
m_nHourSize = 0;
return TRUE;
}
在一个按钮中验证并提交。可以是“提交”或“登陆”按钮
void CTimeSetDlg::OnLoginButton()
{
CString strStartH,strEndH;
int nStartH,nEndH;
m_EditStartHour.GetWindowText(strStartH);
m_EditEndHour.GetWindowText(strEndH);
if(("") == 0) {
AfxMessageBox("输入为非空");
return;
}else if (("") == 0) {
AfxMessageBox("输入为非空");
return;
}
nStartH = atoi(strStartH);//将输入转为int
nEndH = atoi(strEndH);
if (nStartH>24){
AfxMessageBox("输入不能超过24");
m_EditStartHour.SetWindowText(_T(""));
return;
}
if (nEndH>24){
AfxMessageBox("输入不能超过24");
m_EditEndHour.SetWindowText(_T(""));
return;
}
//bao zheng yi ding da yu
if (nEndH <= nStartH) {
AfxMessageBox("第二个数要大于第一个数");
m_EditStartHour.SetWindowText(_T(""));
m_EditEndHour.SetWindowText(_T(""));
return;
}
g_nStartTime = nStartH;//将合法的输入伏给全局变量
g_nEndTime = nEndH;
//按照不同的模式向CArray中放入相应的元素
SPlayTimeSize stPlaySize;
int i;
switch(g_nTimeMode) {
case 0://1 week
m_nTimeSize = 70;//490/7
m_nHourSize = 3;//70/3
int nTimeStart,nTimeEnd;
nTimeStart = nStartH * m_nHourSize;
nTimeEnd = nEndH * m_nHourSize;
g_ArrayTime.RemoveAll();
for(i=0;i<7;i++){
stPlaySize.nTimeStart = nTimeStart + m_nTimeSize*i;
stPlaySize.nTimeEnd = nTimeEnd + m_nTimeSize*i;
g_ArrayTime.Add(stPlaySize);
}
break;
case 1://24Hours
m_nTimeSize = 61;//490/8
m_nHourSize = 20;//490/24
int dTime24HourStart,dTime24HourEnd;
dTime24HourStart = nStartH * m_nHourSize;
dTime24HourEnd = nEndH * m_nHourSize;
g_ArrayTime.RemoveAll();//删除掉数组中原来残留的元素
stPlaySize.nTimeStart = dTime24HourStart;
stPlaySize.nTimeEnd = dTime24HourEnd;
g_ArrayTime.Add(stPlaySize);
break;
case 2://12hours
m_nTimeSize = 82;//490/6
m_nHourSize = 41;//490/12
int dTime12HourStart,dTime12HourEnd;
if (nEndH > 12) nEndH = 12;
dTime12HourStart = nStartH*m_nHourSize;
dTime12HourEnd = nEndH*m_nHourSize;
g_ArrayTime.RemoveAll();
stPlaySize.nTimeStart = dTime12HourStart;
stPlaySize.nTimeEnd = dTime12HourEnd;
g_ArrayTime.Add(stPlaySize);
break;
}
CDialog::OnOK();
}
3在TimeRecConfigPage.h(显示颜色条的对话框)
int m_nInvalidateCount;
BOOL bIsModeChange;
//三种情况时用来重新设定CArray中值的函数
void ShowWeekMode();
void Show12Mode();
void Show24Mode();
TimeRecConfigPage.cpp
BOOL CTimerRecConfigPage::OnInitDialog()
{
CPropertyPage::OnInitDialog();
//初始变量值
bIsModeChange = FALSE;
m_nInvalidateCount = 0;
return TRUE;
}
//点击一个按钮弹出输入对话框,然后重绘
void CTimerRecConfigPage::OnButtonSet()
{
//取得下拉列表所选的第几项传给全局变量
g_nTimeMode = m_ComboTimeMode.GetCurSel();
if(m_TimeSetDlg.DoModal()==IDOK){
bIsModeChange = TRUE;
m_nInvalidateCount = 0;
//重绘
Invalidate(TRUE);
UpdateWindow();
}
}
//下拉列表变化时进行的操作
void CTimerRecConfigPage::OnSelchangePeriodCombo()
{
int nPos = m_ComboTimeMode.GetCurSel();
switch(nPos) {
case 0:
//一下三个函数是将对话框中的静态元素从新排序,使其位置相对固定。对于我们要实现的功能没有作用
SetSTATIC24Pos(FALSE);
SetSTATIC12Pos(FALSE);
SetSTATICWeekPos(TRUE);
//从新设置数组
ShowWeekMode();
break;
case 2://12
SetSTATICWeekPos(FALSE);
SetSTATIC24Pos(FALSE);
SetSTATIC12Pos(TRUE);
Show12Mode();
break;
case 1://24
SetSTATICWeekPos(FALSE);
SetSTATIC12Pos(FALSE);
SetSTATIC24Pos(TRUE);
Show24Mode();
break;
}
//置标值位
bIsModeChange = TRUE;
m_nInvalidateCount = 0;
}
三个函数的具体内容和提交按钮中其实是一样的
void CTimerRecConfigPage::ShowWeekMode()
{
int nTimeSize = 70;//490/7
int nHourSize = 3; //(490/7)/24
int nTimeStart,nTimeEnd;
nTimeStart = g_nStartTime * nHourSize;
nTimeEnd = g_nEndTime * nHourSize;
g_ArrayTime.RemoveAll();
SPlayTimeSize stPlayTimeSize;
for(int i=0;i<7;i++){
stPlayTimeSize.nTimeStart = nTimeStart+nTimeSize*i;
stPlayTimeSize.nTimeEnd = nTimeEnd+nTimeSize*i;
g_ArrayTime.Add(stPlayTimeSize);
}
//下面这个函数市仿写的一个重绘函数。但不太成功,可以不用
//SetRetangle();
}
void CTimerRecConfigPage::Show12Mode()
{
int nTimeSize = 82;
int nHourSize = 41;
int nEndStr;
int dTime12HourStart,dTime12HourEnd;
if (g_nEndTime>12) {
nEndStr = 12;
}else{
nEndStr = g_nEndTime;
}
dTime12HourStart = g_nStartTime*nHourSize;
dTime12HourEnd = nEndStr*nHourSize;
g_ArrayTime.RemoveAll();
SPlayTimeSize m_12HourSize;
m_12HourSize.nTimeStart = dTime12HourStart;
m_12HourSize.nTimeEnd = dTime12HourEnd;
g_ArrayTime.Add(m_12HourSize);
}
void CTimerRecConfigPage::Show24Mode()
{
int nTimeSize = 61;
int nHourSize = 20;
int dTime24HourStart,dTime24HourEnd;
dTime24HourStart = g_nStartTime*nHourSize;
dTime24HourEnd = g_nEndTime*nHourSize;
g_ArrayTime.RemoveAll();
SPlayTimeSize m_24HourSize;
m_24HourSize.nTimeStart = dTime24HourStart;
m_24HourSize.nTimeEnd = dTime24HourEnd;
g_ArrayTime.Add(m_24HourSize);
}
4重绘函数
void CTimerRecConfigPage::OnPaint()
{
CPaintDC dc(this);
int nLeftAdd,nTopAdd,nToprt,nHeight;
int x1,x2;
CBrush brushGreen;
brushGreen.CreateSolidBrush(RGB(20,200,0));
CBrush *pOldbrushGreen = dc.SelectObject(&brushGreen);
x1=x2=0;
nLeftAdd = 96;
nToprt = 100;
nTopAdd = 30;
nHeight = 15;
if (bIsModeChange && m_nInvalidateCount == 0) {
Invalidate();
m_nInvalidateCount = 1;
}
for(int i=0; i<g_ArrayTime.GetSize(); i++ ) {
m_stPlayTimeSize = g_ArrayTime.GetAt(i);
x1 = m_stPlayTimeSize.nTimeStart;
x2 = m_stPlayTimeSize.nTimeEnd;
for (int j=0;j<4;j++) {
dc.Rectangle(nLeftAdd+x1,nToprt+nTopAdd*j,nLeftAdd+x2,nHeight+nToprt+nTopAdd*j);//
}
}
dc.SelectObject(pOldbrushGreen);
brushGreen.DeleteObject();
}