我想每秒钟刷新10次,能有20次更好了,用GDI作图,发现可以实现,但是CPU占用率100%,以至于显示对话框都困难了。有没有好办法加快绘制速度?绘图的代码只是从数据库中取得数据来显示文字,应该耗时比较少,而且是缓存的。
我是这样:利用内存设备句柄成员变量,在OnTimer里调用绘图函数绘制到内存设备句柄,然后调用InValidate(FALSE),在OnPaint里将整个内存设备句柄BitBlt到客户区dc。当然,使用InvalidateRect()会减少一些耗时,可是不能根本解决问题,能不能不用DirectX的情况下,尽可能提高GDI的速度?
请指教。

解决方案 »

  1.   

    图形显示流畅的问题我也一直在思考。
    我积累了两种方法,第一:图形显示用设备环境拷贝是比较快的,也就是说把该处理的图象在内存中处理,然后贴到显示设备上,贴的这一过程很快。同时,图象的刷新是比较关键的,图象在显示设备上绘的速度与图像擦除的速度大概是9:1。所以,要自己写擦除函数,只擦除该刷新的区域,这个区域可通过裁减区域算法进行判断。
    第二,可以通过DirectX双缓冲技术解决。
      

  2.   

    nix3m() 的第一种方法我就曾经用过的
      

  3.   

    各位仔细看我的问题,回答的都是我会的。
    经过跟踪,发现主要费时间的是DrawText()调用,一个DrawText()调用竟然耗时10ms以上,难道是我使用的问题?
    pDC->DrawText(szDesc, lstrlen(szDesc), rcItem, DT_TOP | DT_LEFT | DT_WORDBREAK);
      

  4.   

    DRAWTEXT应该很费时吧。
    因为是矢量字体,
    每个字体好像还要进行插值计算
    所以说游戏开发的不会用矢量字体都是用位图字体。up先我也不懂。
      

  5.   

    差不多吧,可以说是点阵吧,
    可以用看图软件直接看的。(嘿嘿)
    一般是DIB啦,
    DX里面好像是叫什么来着的,一个SURFACE。
      

  6.   

    Windows的TrueTpype字体是一种矢量字体,笔划的曲线采用2次函数来描述,所以,无论如何缩放都能保持形状不变。当然显示的时候是比较费时的。可以用系统中的点阵字体来代替TrueType字体,比如用Fixedsys来代替宋体,也许会提升一点速度(我没试过,仅仅是猜测)。使用DirectX也不能提升文字的显示速度(如果你用Win32函数的话),这个我是试过的。
      

  7.   

    使用DX不能提升速度???
    我先把字体画出来,生成DIB,
    以后就可以直接贴图上去了,
    就不用再BEZIER算法来算了。当然会快一点了。
      

  8.   

    1.尽可能优化绘制剖分
    2、如果对刷新次数要求不是太严格的话,可以试试在OnIdle里绘制,在OnIdle先一个判断
     if ((NowTick - beginTick)>你设定的时间)
         Draw()
         beginTick = NowTick
     else
         return
      

  9.   

    经仔细比较,如上的DrawText()调用,有的时候是0ms,有的时候是16ms,为什么?
      

  10.   

    因为是办公软件,很多电脑没有安装DirectX。
      

  11.   

    这个问题涉及到很多方面,大概讲讲吧:
    1。SetTimer设置的定时器最快只能是每秒18.2次。周期55毫秒。所以20次是不行的。
    况且,Windows系统中,WM_TIMER 和 WM_PAINT消息都是优先级较低的消息,就是说,
    当消息队列中还有其他消息时,系统会优先处理其他消息。这也使定时的精度得不到保证。2。Windows的消息系统本身也很费时,你在OnTimer()中用InvalidateRect(),实际上产生一个WM_PAINT消息,
    然后再在OnPaint()中处理,这是绕了一个弯,如果不考虑消息体系的结构的话,直接在OnTimer中刷新就行了。解决上面两个问题的更好的办法是用多媒体定时器timeSetEvent()设置一个回调函数,
    在这个回调函数中做刷新的工作。这样速度和精确度都能有很大提高。3。DrawText()这个函数确实比较费时。我想你每次显示的应该都是同一个字,
    只是需要不断移动他在屏幕上的位置吧。要是这样,只需要把字写入内存DC一次,
    然后每次用BitBlt()就行了,这个函数相比之下还是比较快的。4。为什么DrawText()有时是0,有时是19?有两个方面:
       1。函数执行过程中的不确定因素:如硬件中断,线程调度,内存缺页错误等。
       2。计时函数本身不准确。我想你大概时用GetTickCount()来计时的吧。
    msdn中说这个函数在95,98下精度是55ms,NT下是10ms;不过我在98下试,精度是5ms。
    其它的函数也类似,并不能反映准确的执行时间的。
    QueryPerformanceCounter高一点,在有硬件支持情况下,可以达到0.8ms.  
      

  12.   

    我觉得用GDI速度也够,现在CPU快
    不过好象不应该加在ONTIMER里
    试一下ONIDLE,或WIN API的PEEKMESSAGE后
      

  13.   

    BlueSky2008() 说清楚了SetTimer的时间问题,MSDN当中也提到使用这个函数,一般不要使用100以下的发生器,因为不准确,
    由于windows是多任务操作系统,55MS是系统的轮训时间,没有办法更快(不同的操作系统的多任务的轮训周期不同),所以使用SetTimer触发高速显示不是好主意。使用GDI,你也可以模仿DX的切换页方式,自己建立一个MEMDC,把图片绘制其中,然后BITBLT到显示DC上。这个速度是比较快的,BITBLT不比DIRECTDRAW的速度慢。后台程序不用时间触发,自己做循环控制,至于显示对话框都困难,是因为你的循环当中没有加入消息处理机制,在网络上搜索一下,有许多关于长期处理计算,程序不响应的解决方式。
      

  14.   

    我发现DrawText没你们说得这样慢吧,一屏能显示多少字?在通常能看得清的字体下,显示一整屏文字也很快呀.用不了几MS.每秒显示20帧以上完全行啊.从内存拷贝至屏幕入不用擦除背景了.
    使用OnTime显示快速不快,不如在OnIdle中计算间隔时间,并绘制.