用GDI的DrawText函数。文字字体HFONT,先CreateFont,然后SelectObject文字里面有中文和英文,如果设置字体为宋体,则没问题。如果设置字体为“Times New Roman”,当中文文字很多、且定时重复刷新显示的时候,CPU占用率一下子上去了。我分析,感觉像是绘制每一个中文字体的时候,先尝试Times New Roman,发现这个是英文字体,不支持中文,然后切换为宋体,结果耗费了大量CPU时间……不知道对不对,如何解决呢?我用的已经是双缓冲了,只不过由于某种需要,内存DC中仍然需要定时重复调用DrawText函数。

解决方案 »

  1.   

    初始化:m_dcMemoryDC = CreateCompatibleDC( m_dcWinDC );
    if( m_dcMemoryDC == NULL )
      return false;m_hMemoryBitmap = CreateCompatibleBitmap( m_dcWinDC, m_iDrawWidth, m_iDrawHeight );
    if( m_hMemoryBitmap == NULL )
      return false;SelectObject( m_dcMemoryDC, m_hMemoryBitmap );m_hBrushBackground = CreateSolidBrush( m_clrBackground );
    if( m_hBrushBackground == NULL )
      return FALSE;::ReleaseDC(m_hWindow,m_dcWinDC);m_hFont = CreateFont( m_iFontSize,0,0,0,iFontBold,iFontItalic,iFontUnderline,iFontStrikeout,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH,(LPCTSTR)(m_iFontName) );
    SelectObject( m_dcMemoryDC, m_hFont );然后SetTimer,每15毫秒调用一次TextToScreen:RECT rectangle;
    rectangle.top    = 0;
    rectangle.left   = 0;
    rectangle.right  = m_iDrawWidth;
    rectangle.bottom = m_iDrawHeight;FillRect( m_dcMemoryDC, &rectangle, m_hBrushBackground ); SetBkMode( m_dcMemoryDC, TRANSPARENT );DrawText( m_dcMemoryDC, m_buffer, m_bufferlen, &rectangle, DT_LEFT | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK );Invalidate(FALSE);
    CPaintDC dc(this);
    ::BitBlt( dc.m_hDC, m_iDrawX, m_iDrawY, m_iDrawWidth, m_iDrawHeight, m_dcMemoryDC, 0, 0, SRCCOPY );就是这样。这段代码之前工作得都好好的,今天我无意间将字体换成Times New Roman,才发现这个问题的……
      

  2.   

    Invalidate(FALSE);
    CPaintDC dc(this);
    ::BitBlt( dc.m_hDC, m_iDrawX, m_iDrawY, m_iDrawWidth, m_iDrawHeight, m_dcMemoryDC, 0, 0, SRCCOPY );
    这里的问题```::BitBlt( dc.m_hDC, m_iDrawX, m_iDrawY, m_iDrawWidth, m_iDrawHeight, m_dcMemoryDC, 0, 0, SRCCOPY );
    写在WM_PAINT里,函数中调用invalidate();就行了`
      

  3.   

    放在这里和放在OnPaint函数里,区别是什么???
      

  4.   

    1。仔细检查下有没有存在GDI leaking
    2. 不要在OnPaint中调用Invalidate(FALSE);, 这会造成频繁刷新,不断发消息WM_PAINT,连续调用OnPaint, 导致系统cpu占用率升高。
      

  5.   

    今天发现根源所在了,是DT_WORDBREAK参数搞的鬼,总结起来,只有当如下三个条件都满足时,CPU占用率才会很高:1) 字体是英文字体,例如Arial、Times New Roman等;
    2) 显示的文本中含有较多的汉字,一般含60多个汉字时CPU就到50%了;
    3) 用DT_WORDBREAK来执行多行显示。其中,任意一条不满足(比如说用中文字体,或者单行显示),CPU都是正常的0%。感到很郁闷,找到根源了也不知道该怎么解决……哪位大侠能帮帮忙啊?
      

  6.   

    GDI+ 封装得太厉害了,绘制速度慢,满足不了需要。
      

  7.   

    画的部分放到OnDraw()函数里面,别在OnTimer里面调用试试看
      

  8.   

    建议把只需创建一次的部分不要放到OnTimer里面,可以作为成员变量,需要不断改变的部分才放到OnTimer里面,另外建议50毫秒刷新一次比较好,50毫秒就能达到20帧了,足够了,其实15帧对于人的眼睛来说就足够了。第二种方法,画的部分放到OnPaint里面----窗口需要重画的时候会自动重画,比如resize,窗口被其他窗口盖住了有拿走了等。 如果数据改变调用Invalidate强制窗口重画。所以如果实在没有其他事件去检测数据的改变,那就在OnTimer里面检测,如果改变,调用Invalidate就行了。第二种方法是占用CPU最少的,但是代码上可能需要改动多一些。
      

  9.   

    我其实是做一个带有动画效果的文字显示的程序,例如文本的移动、闪烁之类的。所以OnTimer里面不断改变参数,不断地重绘。至于刷新的时间间隔,在文本移动的时候试过30毫秒一次都觉得不能满足视觉需求,最后改成15毫秒一次,每次只让它移动1个像素值(可能是我个人对视觉要求比较高的缘故吧)。而最关键的是,15毫秒并不是造成负担的原因,我说了,其余的情况仍然是 0% 的CPU占用率。只有当字体是英文字体、含有较多的汉字且用DT_WORDBREAK来多行显示这三者同时满足时,CPU才很高……