热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么定时器内的画图函数没有执行?

我想用定时器实现曲线的动态输出,可是我把划线函数ShowData放在定时器中,定时器没有实现划线函数ShowData的功能,请问这是怎么回事呢?我的划线函数没有问题,如果在OnPaint函数中直

 我想用定时器实现曲线的动态输出,可是我把划线函数ShowData放在定时器中,定时器没有实现划线函数ShowData的功能,请问这是怎么回事呢 ?我的划线函数没有问题,如果在OnPaint函数中直接调用划线函数ShowData可以输出一条曲线。
void CDCDlg::OnPaint() 
{
CPaintDC dc(this); // device context for painting
CDC  memDC ;
memDC.CreateCompatibleDC(&dc) ;
CPen Oldpen(PS_SOLID,2,RGB(128,128,128)) ;
CPen  pen(PS_SOLID,2,RGB(0,255,0)) ;
CBrush oldbrush(RGB(0,255,255));
CBrush newbrush(RGB(255,255,0));
dc.SelectObject(&pen) ;

CWnd* pImage=GetDlgItem(IDC_STATIC) ;
pImage->GetDC() ;
pImage->GetWindowRect(&rect) ;

ScreenToClient(&rect) ; //将屏幕坐标转换为客户区坐标

//dc.Ellipse(&rect) ;  //画圆
dc.Rectangle(&rect) ;
CRect newrect ;
newrect.left=rect.left+20 ;
                   newrect.right=rect.right-20 ;
newrect.top=rect.top+20 ;
newrect.bottom=rect.bottom-20 ;

                  //ShowData(&dc) ;
SetTimer(0,3000,NULL) ;
        
UpdateWindow() ;
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CDCDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CDCDlg::OnTimer(UINT nIDEvent) 
{

CPaintDC dc(this); // device context for painting
CDC  memDC ;
memDC.CreateCompatibleDC(&dc) ;
CPen Oldpen(PS_SOLID,2,RGB(128,128,128)) ;
CPen  pen(PS_SOLID,2,RGB(0,255,0)) ;
CBrush oldbrush(RGB(0,255,255));
CBrush newbrush(RGB(255,255,0));
dc.SelectObject(&pen) ;

ShowData(&dc) ;

CDialog::OnTimer(nIDEvent);
}
void CDCDlg::ShowData(CDC *dc)
{
   //static int count=1 ;
   double lx=rect.left ;
   double rx=rect.right ;
   double dy=rect.bottom ;
   double step=(rx-lx)/1000 ;
   for(int i=0;i<1000;i++)
   {
      X[i]=lx+step*i ;
  Y[i]=100+cos(X[i]/20)*50+50+rand()/1000;

   }
   dc->MoveTo(lx,dy) ;
   for(i=0;i<1000;i++)
   {
      dc->LineTo(X[i],Y[i]);

   }
 
}

19 个解决方案

#1


SetTimer(0,3000,NULL) ;  第一个参数得是非零的值

#2


这样是画不上的,在OnPaint里面绘制。在OnTimer里面把要绘制的东西,以model的形式保存下来。。。

#3


在OnTimer中调用Invalidate()就可以了,没有必要在里面再获取dc进行绘制。
一般最好能够把绘制的功能都放在OnPaint里面实现。

#4


OnPaint()函数里还调用了UpdateWindow() ......

#5


引用 3 楼 nintendo_dskay 的回复:
在OnTimer中调用Invalidate()就可以了,没有必要在里面再获取dc进行绘制。
一般最好能够把绘制的功能都放在OnPaint里面实现。


顶,正解!

#6


nintendo_dskay你好, 在OnTimer中调用Invalidate()的作用是什么 ? 绘制功能都在OnPaint中实现是不是就不需要OnTimer函数了 ?

#7


绘制完成后还要更新,否则是显示不出来的
而OnPaint自动更新

#8


healer_kx 你好,
在OnTimer里面把要绘制的东西,以model的形式保存下来,
这句话我不太理解,具体一点说应该在OnTimer中做什么呢 ?

#9


nintendo_dskay 你好,
 按照你的要求我把程序修改如下,但是还是不能实现动态显示啊,是不是我的定时器用的不对啊 ,请指教一下,谢谢。

void CDCDlg::OnPaint() 
{
CPaintDC dc(this); // device context for painting
CDC  memDC ;
memDC.CreateCompatibleDC(&dc) ;
CPen Oldpen(PS_SOLID,2,RGB(128,128,128)) ;
CPen  pen(PS_SOLID,2,RGB(0,255,0)) ;
CBrush oldbrush(RGB(119,136,153));
CBrush newbrush(RGB(255,255,0));
dc.SelectObject(&pen) ;

CWnd* pImage=GetDlgItem(IDC_STATIC) ;
pImage->GetDC() ;
pImage->GetWindowRect(&rect) ;
                ScreenToClient(&rect) ; //将屏幕坐标转换为客户区坐标
dc.Rectangle(&rect) ;
dc.FillRect(&rect,&oldbrush);
}

void CDCDlg::OnTimer(UINT nIDEvent) 
{
Invalidate() ;
CDialog::OnTimer(nIDEvent);
}

void CDCDlg::ShowData(CDC *dc)
{
   //static int count=1 ;
   double lx=rect.left ;
   double rx=rect.right ;
   double dy=rect.bottom ;
   double step=(rx-lx)/1000 ;
   for(int i=0;i<1000;i++)
   {
      X[i]=lx+step*i ;
  Y[i]=100+cos(X[i]/20)*50+50+rand()/1000;

   }
   dc->MoveTo(lx,dy) ;
   for(i=0;i<1000;i++)
   {
      dc->LineTo(X[i],Y[i]);

   }
 
}

#10


引用 8 楼 liu8712289 的回复:
healer_kx 你好,
 在OnTimer里面把要绘制的东西,以model的形式保存下来,
 这句话我不太理解,具体一点说应该在OnTimer中做什么呢 ?


听说过MVC吧?我就是这个意思,按照这种方式写,你的代码就有更好的可维护性和可扩展性。

#11


第一个:在OnPaint中调用SetTimer本身就是错误的,OnPaint会被调用多次,每更新一次就会调用一次,按你的代码,你会设置多个定时器的。
第二个:在OnTimer中画图不是不行,但是在OnTimer中获取CPaintDC 是不合适的,CPaintDC一般只用在OnPaint中,这涉及到无效区的设置,在定时器中不应该用这个,你可以用其它的方式获取DC,比如用CClientDC dc(this);或是用GetDC都可以,在客户画图用CClientDC是很方便的。
第三个:上面不少人说的方法是正确的,在OnTimer中不画图,仅仅是调用Invalidate()更新,将画图部分还是放在OnPaint中,这种方法是常用的方法。

#12


nintendo_dskay 你好, 

用你说的方法可以了,不过闪了很厉害,这个怎么解决呢,用双缓冲法可以吗 ?

#13


引用 10 楼 healer_kx 的回复:
引用 8 楼 liu8712289 的回复:
healer_kx 你好,
在OnTimer里面把要绘制的东西,以model的形式保存下来,
这句话我不太理解,具体一点说应该在OnTimer中做什么呢 ?


听说过MVC吧?我就是这个意思,按照这种方式写,你的代码就有更好的可维护性和可扩展性。


哦 ,大体明白了,谢谢你啊 。

#14


引用 11 楼 wltg2001 的回复:
第一个:在OnPaint中调用SetTimer本身就是错误的,OnPaint会被调用多次,每更新一次就会调用一次,按你的代码,你会设置多个定时器的。
第二个:在OnTimer中画图不是不行,但是在OnTimer中获取CPaintDC 是不合适的,CPaintDC一般只用在OnPaint中,这涉及到无效区的设置,在定时器中不应该用这个,你可以用其它的方式获取DC,比如用CClientDC dc(this);或是用GetDC都可以,在客户画图用CClientDC是很方便的。
第三个:上面不少人说的方法是正确的,在OnTimer中不画图,仅仅是调用Invalidate()更新,将画图部分还是放在OnPaint中,这种方法是常用的方法。


谢谢你的回答,让我明白了挺多知识。
你能不能告诉我OnPaint调用SetTimer后其刷新一次的间隔时间是不是由定时器决定的 ?
我在OnPaint()函数中调用SetTimer和在 下面的OnRunStop()中调用SetTimer效果是一样的。这二者有区别嘛 ?为什么在OnPaint()函数中调用SetTimer会设置多个定时器呢 ? 谢谢
void CDCDlg::OnRunStop() 
{
SetTimer(1,100,NULL);
}

#15


引用 12 楼 liu8712289 的回复:
nintendo_dskay 你好,

用你说的方法可以了,不过闪了很厉害,这个怎么解决呢,用双缓冲法可以吗 ?


可以用双缓冲,或者用InvalidateRect只刷新你要更新的区域!!

#16


你能不能告诉我OnPaint调用SetTimer后其刷新一次的间隔时间是不是由定时器决定的 ? 
我在OnPaint()函数中调用SetTimer和在 下面的OnRunStop()中调用SetTimer效果是一样的。这二者有区别嘛 ?为什么在OnPaint()函数中调用SetTimer会设置多个定时器呢 ? 谢谢 
==========
SetTimer是设置定时器,每调用一次就会设置一个定时器,OnRunStop应该是一个按钮或是菜单的处理函数吧,它一般只有在你点击它时才会被调用,而OnPaint则是出现无效区就会调用,比如你的窗口被别的窗口挡住了,你点一下你的窗口,它又回到了最前面,这时OnPaint就会被调用一次,或是做一次最大化操作,OnPaint又会被调用一次,如果将SetTimer放在OnPaint中,那会设置很多的定时器,因为你用的语句是SetTimer(1,...)也就是说定时器ID是一样的,所以每调用一次,前一个定时器就会被新定时器取代,所以在OnPaint中调用SetTimer的时间间隔根本就说不清。

#17


闪得厉害就重写WM_ERASEBKGND的消息处理,在里面直接返回TRUE,这样就不闪了。

#18


闪烁最好的解决办法还是双缓冲,其实你的OnPaint里面已经基本可以用双缓冲了,就是CDC memDC.
你把OnPaint里面用到的dc全部先换成memDC,也就是先把要画的东西画在内存DC上,然后用dc.BitBlt()将memDC里面的内容复制到dc上,这样就可以了,其中的参数可以参考msdn。

#19


谢谢大家啊 ,非常感谢。

#20


  • 使用定时器执行含有参数的函数
  • 没有被调用的函数其代码为什么会被执行?

推荐阅读
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
author-avatar
手机用户2502897397
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有