MFC对话框绘制坐标轴和动态曲线的问题VS2010

x123y123 2013-05-02 12:03:48
下面的是我的onpaint,现在我已经把坐标轴画出来了,我想用ontimer来动态描点画折线,数据放在全局数组中,请问应该怎样实现?
void CfangzhenDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
CString str;

//强制更新绘图, 不可少, 否则绘图会出错
pWnd->Invalidate(); //使static控件的区域无效
pWnd->UpdateWindow();//更新窗口, 此时才真正向系统发送重绘消息
CDC *pDC = pWnd->GetDC(); //获取控件的CDC指针
pDC->Rectangle(0, 390, 700, 0); //画一个矩形框
CPen *pPenRed = new CPen(); //创建画笔对象
pPenRed ->CreatePen(PS_SOLID, 1, RGB(128, 128, 128)); //黑色画笔
CPen *pPen = NULL;
//选中当前红色画笔,并保存以前的画笔
CGdiObject *pOldPen = pDC ->SelectObject(pPenRed);
pDC ->MoveTo(20, 20); //绘制坐标轴
pDC ->LineTo(20, 360); //竖起轴
pDC ->LineTo(690, 360); //水平轴
//写X轴刻度值
for(int i = 0; i <= 25; i ++)
{
str.Format(_T("%d"), i);
pDC ->TextOut(17 + 25 * i, 365, str);
//绘制X轴刻度
pDC ->MoveTo(i * 25 + 20, 360);
pDC ->LineTo(i * 25 + 20, 355);
}
pDC ->TextOut(680,365,_T("t/s"));
//写Y轴刻度值
for(int i = 1; i <= 10; i ++)
{
str.Format(_T("%d"), i);
pDC ->TextOut(2, 360 - 30 * i - 5, str);
//绘制Y轴刻度
pDC ->MoveTo(25, 360 - 30 * i);
pDC ->LineTo(20, 360 - 30 * i);
}
//绘制X箭头
pDC ->MoveTo(680, 357);
pDC ->LineTo(690, 360);
pDC ->LineTo(680, 363);
//绘制Y箭头
pDC ->MoveTo(17, 30);
pDC ->LineTo(20, 20); //绘制左边箭头
pDC ->LineTo(23, 30); //绘制右边箭头

pDC ->SelectObject(pOldPen);//恢复以前的画笔

delete pPenRed;
if(pPen != NULL)
delete pPen;
ReleaseDC(pDC);

}
...全文
2535 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
shiter 2016-01-14
  • 打赏
  • 举报
回复
您好,请问楼主解决了么,解决了就分享一下吧,谢谢了,后续如果没有疑问的话就结贴了
manongliangzai 2015-07-11
  • 打赏
  • 举报
回复
您好,我也遇到类似的情况,你的问题解决了么请发到我的邮箱zliang13@mails.jlu.edu.cn
  • 打赏
  • 举报
回复
如果你解决了,能给我具体说一下步骤吗?包括数据的读取。794362713@qq.com
hdg3707 2013-05-02
  • 打赏
  • 举报
回复
坐标轴都画出来了,曲线也一样,只不过曲线上的每一点的实际坐标值要根据坐标轴的刻度和实际值进行转换才行,还是用 pDC ->MoveTo(x1, y1); pDC ->LineTo(x2, y2); 来画
schlafenhamster 2013-05-02
  • 打赏
  • 举报
回复
SetPixel();
schlafenhamster 2013-05-02
  • 打赏
  • 举报
回复
cstring.GetLenth()
schlafenhamster 2013-05-02
  • 打赏
  • 举报
回复
用static控件 , 就要派生 CYourStatic ,然后把 paint 代码 放 CYourStatic 的OnPaint中。 可以 先 去掉 static 直接在 对话框上 试试。
x123y123 2013-05-02
  • 打赏
  • 举报
回复
引用 12 楼 schlafenhamster 的回复:
不是在 对话框 中 paint 吗? 怎么又出来个 static ? “使static控件的区域无效”
用static控件定位然后在static控件中画的……自己不太会,参考网上的例子
x123y123 2013-05-02
  • 打赏
  • 举报
回复
这个是一个读数据的代码,在VC6.0下没问题,改了VS2010中的用法不知道行不行,调试无警告无错误。还有我怀疑的是逻辑坐标转换成设备坐标的操作,我的逻辑坐标是double型的强制转成int型
schlafenhamster 2013-05-02
  • 打赏
  • 举报
回复
不是在 对话框 中 paint 吗? 怎么又出来个 static ? “使static控件的区域无效”
x123y123 2013-05-02
  • 打赏
  • 举报
回复
引用 10 楼 schlafenhamster 的回复:
把定时器中绘图部分 移到 onpaint 中 定时器中就2条语句: m ++; Invalidate();
我试了一下,还是不行……是这个有问题吗?
//强制更新绘图, 不可少, 否则绘图会出错
   pWnd->Invalidate(); //使static控件的区域无效
   pWnd->UpdateWindow();//更新窗口, 此时才真正向系统发送重绘消息
还是这个?
	FILE *fp=0;
    fopen_s(&fp,"e:\\input.txt","r");
	for(int i=0;i<625;i++)
	{
		for(int j=0;j<9;j++)
		{
			fscanf_s(fp,"%lf",&(input[i][j]),40);
		}
	}
	fclose(fp);
schlafenhamster 2013-05-02
  • 打赏
  • 举报
回复
把定时器中绘图部分 移到 onpaint 中 定时器中就2条语句: m ++; Invalidate();
  • 打赏
  • 举报
回复
一般很少有直接在 OnPaint 中绘图的。 如果有, 那一般是教学示例程序。 我的OnPaint 一般是这样处理 void CGraph::OnPaint() { CPaintDC dc(this); // device context for painting ::BitBlt (dc.m_hDC, 0, 0, m_rcThis.Width(), m_rcThis.Height(), m_hMemDC, 0, 0, SRCCOPY); }
  • 打赏
  • 举报
回复
我知道你要表达的意思, 我是这么处理的。 我通常保存好几个dc, 一个DC装有画好的背景, 一个内存DC, 一个窗口DC。 1, 将背景DC(一般只绘有坐标)BITBLT 到内存DC 2, 在内存DC上绘制图形 3, 将内存DC BITBLT 到窗口DC上 下一次绘制时,重复以上三部。
baichi4141 2013-05-02
  • 打赏
  • 举报
回复
第一,写一个函数X来画图 第二,为了让图像改变,在OnTimer或者某个按钮的响应函数里添加画图函数X 第三,为了让界面自动重绘时画的图不消失,在OnPaint里添加画图函数X 至于Invalidate(),我是非常讨厌的
x123y123 2013-05-02
  • 打赏
  • 举报
回复
引用 5 楼 schlafenhamster 的回复:
"但是怎样两次绘图才能不冲突" 什么问题 ???
就是在Ontimer中的绘图会不会把在Onpaint中的坐标轴覆盖,我看网上有些说要在Ontimer中调用Invalidate()来重绘,我这样做时就没有图了,现在我执行Ontimer后没有曲线只有坐标轴……我是第一次接触MFC……
schlafenhamster 2013-05-02
  • 打赏
  • 举报
回复
"但是怎样两次绘图才能不冲突" 什么问题 ???
x123y123 2013-05-02
  • 打赏
  • 举报
回复
引用 2 楼 hdg3707 的回复:
坐标轴都画出来了,曲线也一样,只不过曲线上的每一点的实际坐标值要根据坐标轴的刻度和实际值进行转换才行,还是用 pDC ->MoveTo(x1, y1); pDC ->LineTo(x2, y2); 来画
我就是这样画的,但是怎样两次绘图才能不冲突?请看下Ontimer,我的肯定有问题
x123y123 2013-05-02
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
SetPixel();
可能我说的不清楚,画曲线用Moveto和lineto就可以实现这个就是我的Ontimer函数
void CfangzhenDlg::OnTimer(UINT_PTR nIDEvent)
{
	 CWnd* pWnd = GetDlgItem(IDC_MYSTATIC);
       CDC* pDC = pWnd->GetDC();
	   //描点
   	HPEN sRedPen,dRedPen,sGreenPen,dGreenPen,sBluePen,dBluePen,hPenOld;
	sRedPen=CreatePen(PS_SOLID,3,RGB(255,0,0));
	dRedPen=CreatePen(PS_DASH,3,RGB(255,0,0));
	sGreenPen=CreatePen(PS_SOLID,3,RGB(0,255,0));
	dGreenPen=CreatePen(PS_DASH,3,RGB(0,255,0));
	sBluePen=CreatePen(PS_SOLID,3,RGB(0,0,255));
	dBluePen=CreatePen(PS_DASH,3,RGB(0,0,255));
	hPenOld = (HPEN)pDC->SelectObject(sRedPen);
	pDC ->MoveTo((T[m]-15)*25+15,360-300*Output[m][0]);
	pDC ->LineTo((T[m+1]-15)*25+15,360-300*Output[m+1][0]);//PNP
	pDC->SelectObject(hPenOld);
	hPenOld = (HPEN)pDC->SelectObject(dRedPen);
    pDC ->MoveTo((T[m]-15)*25+15,360-300*Output[m][1]);
	pDC ->LineTo((T[m+1]-15)*25+15,360-300*Output[m+1][1]);//PNC
	pDC->SelectObject(hPenOld);
	hPenOld = (HPEN)pDC->SelectObject(sGreenPen);
    pDC ->MoveTo((T[m]-15)*25+15,360-300*Output[m][2]);
	pDC ->LineTo((T[m+1]-15)*25+15,360-300*Output[m+1][2]);//HPP
	pDC->SelectObject(hPenOld);
	hPenOld = (HPEN)pDC->SelectObject(dGreenPen);
	pDC ->MoveTo((T[m]-15)*25+15,360-300*Output[m][3]);
	pDC ->LineTo((T[m+1]-15)*25+15,360-300*Output[m+1][3]);//SMC
	pDC->SelectObject(hPenOld);
	hPenOld = (HPEN)pDC->SelectObject(sBluePen);
	pDC ->MoveTo((T[m]-15)*25+15,360-300*Output[m][4]);
	pDC ->LineTo((T[m+1]-15)*25+15,360-300*Output[m+1][4]);//T45
	pDC->SelectObject(hPenOld);
	hPenOld = (HPEN)pDC->SelectObject(dBluePen);
	pDC ->MoveTo((T[m]-15)*25+15,360-300*Output[m][5]);
	pDC ->LineTo((T[m+1]-15)*25+15,360-300*Output[m+1][5]);
	pDC->SelectObject(hPenOld);

		double s0,s1,s2,s3,s4,s5,s6;
		CString S0,S1,S2,S3,S4,S5,S6;
		s0=input[m+1][2];
		S0.Format(_T("%.4f"),s0);
		GetDlgItem(IDC_EDIT1)->SetWindowText(S0);//输出WFB

		s1=Output[m+1][0]*mPNP;
		S1.Format(_T("%.4f"),s1);
		GetDlgItem(IDC_EDIT2)->SetWindowText(S1);//输出PNP

		s2=Output[m+1][1]*mPNC;
		S2.Format(_T("%.4f"),s2);
		GetDlgItem(IDC_EDIT3)->SetWindowText(S2);//输出PNC
	    
		s3=Output[m+1][2]*mHPP;
		S3.Format(_T("%.4f"),s3);
		GetDlgItem(IDC_EDIT4)->SetWindowText(S3);//输出HPP
	    
		s4=Output[m+1][3]*mSMC;
		S4.Format(_T("%.4f"),s4);
		GetDlgItem(IDC_EDIT5)->SetWindowText(S4);//输出SMC
	    
		s5=Output[m+1][4]*mT45;
		S5.Format(_T("%.4f"),s5);
		GetDlgItem(IDC_EDIT6)->SetWindowText(S5);//输出T45
	    
		s6=Output[m+1][5]*mP45;
		S6.Format(_T("%.4f"),s6);
		GetDlgItem(IDC_EDIT7)->SetWindowText(S6);//输出P45
		m+=1;
		if(m>=625)
		{
			KillTimer(1);
		}// TODO: 在此添加消息处理程序代码和/或调用默认值

	CDialogEx::OnTimer(nIDEvent);
}

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧