本站首页    管理页面    写新日志    退出


«July 2025»
12345
6789101112
13141516171819
20212223242526
2728293031


公告

谦卑,荣誉,牺牲,英勇,怜悯,诚实,精神,公正。


我的分类(专题)

日志更新

最新评论

留言板

链接

 

 


Blog信息
blog名称:
日志总数:183
评论数量:698
留言数量:7
访问次数:3018601
建立时间:2005年12月29日




[编程学习]Visual C++6.0实现动态曲线4种方法
网上资源

newqiang 发表于 2006/3/9 11:30:31

  在实验和生产中,我们常常需要对被监测的对象进行实时监控,比如对现场的温度等环境因素进行实时数据采集,然后传输到主控制计算机,以动态曲线的方式显示出来,便于人们对现场的了解和控制。 2.用Visual C++实现动态曲线的绘制有4种方法。(1)使用消隐。(2)使用重绘。其中重绘按照原理的不同又分为3种。 2.1消隐。其实消隐的方法很简单,主要使用CDC类的成员函数SetROP2 。该函数原型为int SetROP2( int nDrawMode )。参数nDrawMode为新的绘制方式。该函数用来设置当前绘制方式,绘制方式说明画笔和被填充对象的内部如何与屏幕表面已有的颜色组合。我们选用R2_XORPEN绘制方式——画笔颜色和屏幕颜色的组合,但不同时在两者之中,最终像素=画笔XOR屏幕像素。要实现动态曲线只需在这种绘制方式下在原有曲线的位置上再绘一次,以消隐掉原有曲线,再绘制新的曲线,如此重复,就可形成动态曲线。 2.2重绘。在重绘中都要使用到这样一个函数:CDC类成员函数BitBlt 。原型为BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop )。该函数将一个位图从源设备描述表拷贝到CDC的设备描述表中。 2.2.1原理1:设置一个后台设备环境。所有的绘图工作都在后台完成,然后通过BitBlt 函数拷贝到当前设备环境。这种方法要求后台每次都全部重绘,包括坐标、字符说明、曲线等。 2.2.2应用举例: 在OnTimer 函数中每隔一定时间进行重绘。 void CDrawView::OnTimer(UINT nIDEvent) {        // TODO: Add your message handler code here and/or call default        DrawPicture();      // 画图函数 } void CDrawView::DrawPicture() {     pBackDC->PatBlt(0,0,winx, winy, PATCOPY);        //画坐标轴及刻度        DrawCoordinate(pBackDC ,BLACKPEN, MainWindowLeft,MainWindowBottom - MAINHEIGHT, MainWindowLeft + MAINWIDTH, MainWindowBottom);        //标出x坐标刻度值        WriteCoordinateX(pBackDC, BLACKPEN, MainWindowLeft,MainWindowLeft + MAINWIDTH, MainWindowBottom);        //标出y坐标刻度值        WriteCoordinateY(pBackDC,BLACKPEN,MainWindowLeft,MainWindowBottom );        //输出实际宽度值        WriteMessage(pBackDC,MainWindowLeft,MainWindowBottom,MAINHEIGHT );     if ( pBackDC != NULL )        { //画曲线图        DrawGraph(pBackDC,REDPEN,MainWindowLeft+MAINWIDTH,MainWindowBottom);              CDC *pDC = GetDC();               if (pDC != NULL)               { //调用OnDraw()函数,将曲线图显示在屏幕中                      OnDraw(pDC);                          ReleaseDC(pDC);               }        } } void CDrawView::OnDraw(CDC* pDC) {        CDrawDoc* pDoc = GetDocument();        ASSERT_VALID(pDoc);        // TODO: add draw code for native data here        if (pDC != NULL)               pDC->BitBlt(0,0,winx, winy, pBackDC, 0, 0, SRCCOPY); } 2.2.3原理2:设置一个后台设备环境(如图2),其大小与当前设备环境相同(如图1)。但主要绘图工作都在当前设备环境进行。例如设当前设备环境大小为200×100,曲线点之间的间距offset=5,左上角顶点在屏幕中的坐标为(200,100)。当所绘制的曲线横坐标X﹤400时,就在当前设备环境绘制曲线;当横坐标X﹥400时,就从前设备环境把坐标点(205,100)的右下部分用函数BitBlt拷贝到矩形区范围为(0,0,195,100)的后台设备环境中,然后清除当前设备环境,接着再用函数BitBlt从后台设备环境中把曲线拷贝到矩形区范围为(200,100,195,100)的当前设备环境中,最后再在曲线尾画上当前的数据点,如此循环。   (200,100)                         (0,0)              200×100                              200×100 图1:当前设备环境                   图2:后台设备环境 2.2.4应用举例: void CAnimateLineView::OnTimer(UINT nIDEvent) {        // TODO: Add your message handler code here and/or call default        CClientDC dc(this);        static int x=200;        static int y=200;        CPen pen1(PS_SOLID,0,RGB(255,255,255));        CPen *oldpen1=NULL;        oldpen1=dc.SelectObject(&pen1);        x=x+offsetx;        if(x<=400)        {               dc.MoveTo(x-offsetx,y);               y=200-rand()%90;               dc.LineTo(x,y);        }        else{               CRect rect(200,100,400,200);               CBrush bkbrush(HS_CROSS,RGB(0,128,0));               m_dc.BitBlt(0,0,195,100,&dc,205,100,SRCCOPY);               dc.SetBkColor(RGB(0,0,0));               dc.FillRect(rect,&bkbrush);               dc.BitBlt(200,100,195,100,&m_dc,0,0,SRCCOPY);               dc.MoveTo(395,y);               y=200-rand()%90;               dc.LineTo(400,y);}        dc.SelectObject(oldpen1);        CView::OnTimer(nIDEvent); } 2.2.5原理3:设置一个后台设备环境,其宽度为当前设备环境的两倍,高度相同。绘图工作都在后台设备环境进行。例如设当前设备环境大小为200×100(如图1),则后台设备环境为400×100(如图2),曲线点之间的间距offset=10,左上角顶点在屏幕中的坐标为(200,100)。①当在后台设备环境中所绘制的曲线横坐标0﹤X﹤200时只需将前半部分区域拷贝到当前设备环境就行了;②当横坐标200﹤X﹤400时,将宽度为200的矩形区域依次向后半部分移动10个单位取出拷贝到当前设备环境;③当X﹥400时,将后半部分拷贝到当前设备环境,并清除前半部分。④当第2次0﹤X﹤200时,将后半部分矩形区域依次向后半部分移动10个单位拷贝到当前设备环境,并将实时曲线画在前半部分然后将其拷贝到当前设备环境的末尾;⑤当200﹤X﹤400时,清除后半部分,并将前半部分矩形区域依次向后移动10个单位拷贝到当前设备环境,在后半部分绘制实时曲线然后将其拷贝到当前设备环境的末尾;⑥当再次X﹥400时,回到④,如此循环下去就能形成动态曲线。   (200,100)   200×100 图1:当前设备环境     宽度为200,不停的向右移 (0,0)                   200                      400   (200+200)×100 图2:后台设备环境 2.2.6应用举例: void CLineView::OnTimer(UINT nIDEvent) {        // TODO: Add your message handler code here and/or call default        static int x=0;        static int y=0;        static int control=0;        CClientDC dc(this);        CRect rect(0,0,200,100);        CRect rect1(200,0,400,100);        CBrush bkbrush(HS_CROSS,RGB(0,128,0));        x=x+offset;        CPen pen1(PS_SOLID,0,RGB(255,255,255));        CPen *oldpen1=NULL;        oldpen1=m_dc.SelectObject(&pen1);        if(x<=200)        {               m_dc.MoveTo(x-offset,y);               y=100-rand()%90;               m_dc.LineTo(x,y);               if(control==0)                      dc.BitBlt(200,100,200,100,&m_dc,0,0,SRCCOPY);              else               {                      dc.BitBlt(200,100,200-x,100,&m_dc,x+200,0,SRCCOPY);                      dc.BitBlt(400-x,100,x,100,&m_dc,0,0,SRCCOPY);               }        }        if(x<=400&&x>200)        {               if(control==1)               {                      dc.BitBlt(200,100,200,100,&m_dc,x-200,0,SRCCOPY);                      m_dc.FillRect(rect1,&bkbrush);                      control=0;               }               m_dc.MoveTo(x-offset,y);              y=100-rand()%90;              m_dc.LineTo(x,y);              dc.BitBlt(200,100,200,100,&m_dc,x-200,0,SRCCOPY);       }       if(x>400)       {              x=0;              dc.BitBlt(200,100,200-x,100,&m_dc,x+200,0,SRCCOPY);              m_dc.SetBkColor(RGB(0,0,0));             m_dc.FillRect(rect,&bkbrush);              control=1;       }        dc.SelectObject(oldpen1);            CView::OnTimer(nIDEvent); } 2.3总结 消隐的方法虽然简单,但不适用于实时监控。当图形区域要求参数说明和时间同时移动时,重绘中的第2和第3种方法实现起来比较麻烦。重绘中的第1种方法适用性较强,效果最好。  [原创 2006-02-21 21:25:53 | 发表者: 鸽子情缘]   


阅读全文(30793) | 回复(36) | 编辑 | 精华
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

yg(游客)发表评论于2012/6/22 9:36:32

发份源代码呗。。。739711498@qq.com


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

lilianplayer(游客)发表评论于2011/5/24 14:11:10

麻烦楼主给我发份,谢谢!lilianplayer@163.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

fly(游客)发表评论于2008/5/12 13:11:43

可以发给我一份吗 2003fln@163.com感谢.

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

Ruibi(游客)发表评论于2008/2/5 9:38:44

您好,求源码一份,谢谢了 ruibi@vip.qq.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

Open(游客)发表评论于2008/1/31 18:07:00

支持。  

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

石头(游客)发表评论于2007/10/19 13:34:18

这个我也希望能得到一份源代码,谢谢!能否发到我邮箱。abc123miracle@163.com  

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

DING(游客)发表评论于2007/10/8 15:09:52

楼主,麻烦你给我发一份源码好吗,多谢了!xdingweix@126.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

DING(游客)发表评论于2007/10/8 15:08:47

您好,麻烦我也想要您的源码学习以下,谢谢~~

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

wangxing(游客)发表评论于2007/9/6 11:10:25

visual c++ 6.0 的OnTimer函数在什么情况下被调用?settimer函数在哪个函数中出现?比如在initinstance函数中,或initupdate ,或构造函数中?很迷惑!另外在单文本环境下,系统调用各函数的顺序是怎样的?先initinstance(),后onpaint()吗?

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

wangxing(游客)发表评论于2007/9/6 11:10:13

visual c++ 6.0 的OnTimer函数在什么情况下被调用?settimer函数在哪个函数中出现?比如在initinstance函数中,或initupdate ,或构造函数中?很迷惑!另外在单文本环境下,系统调用各函数的顺序是怎样的?先initinstance(),后onpaint()吗?

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


» 1 2 3 4 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.143 second(s), page refreshed 144758633 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号