GDI效率有关问题:DrawText调用1万次,慢的要命

GDI效率问题:DrawText调用1万次,慢的要命
需要调用 DrawText一万次,每次输出的数字不一样。 
好慢。。。。

大伙可有好的效率优化办法?

------解决方案--------------------
可以事先判断一下,然后只绘制可见区域的文本
可以把需要缩放的图形绘制在一个DC不需要缩放的图形绘制在另一个DC,最后混合到窗口DC
------解决方案--------------------
可以把事先需要绘制的数据放在一个位图上,先在位图上重画数据已经改变的数据,然后一次性刷新图片到屏幕
------解决方案--------------------
在OnDraw的时候,最好只执行一次Bitblt

------解决方案--------------------
不是这么处理的,你要只绘制需要更新的区域。
// 我假设是MM_TEXT映射模式,其他模式自己处理。

void CMyView::OnDraw(CDC* pDC)
{
CRect rectUpdate;
switch (pDC->GetClipBox(&rectUpdate))
{
default:
break;
case ERROR:
case NULLREGION:
return;
}

CSize size = rectUpdate.Size();
CDC dcMem;
dcMem.CreateCompatableDC(pDC);
CBitmap bmp;
bmp.CreateCompatableBitmap(pDC, size.cx, size.cy);
dcMem.SaveDC();
dcMem.SelectObject(bmp);
dcMem.OffsetViewPort(-rectUpdate.left, -rectUpdate.top);
// draw....
// 最好根据坐标和行高等信息直接计算出第一个需要更新的行和最后一个需要更新的行。
CRect r;
if (r.IntersetRect(&TheRectToPaint, &rectUpdate))
{
// draw the string.....
}
dcMem.SetMapMode(MM_TEXT);
dcMem.SetViewPortOrg(0, 0);
pDC->BitBlt(...., &dcMem, 0, 0, SRCCOPY);
dcMem.RestoreDC(-1);
}
以上代码是我随手写的,没有检验过,但只是告诉你思路。

------解决方案--------------------
探讨
图形生成后不会一成不变,变化的代码在哪里处理合适呢
比如我要在上面发的那张图上做画线的操作,在哪里处理比较合适。

上面那张图变化的频率比较小(主要耗费的时间就在画数字表格上),但是画线操作就比较多(画线操作耗费的时间很少), 现在的实现是每次Ondraw的时候都有重画一次数字表格;
有什么办法把表格当背景图,然后每次ondraw只画线,这样时间就少多了???

------解决方案--------------------
探讨
引用:
按jennyvenus的意思,做起来有点“图层”的感觉,层与层之间保持逻辑上的格局一致。

你的问题在论坛上很难解决,是一个基础问题,找本书看吧
与图层无关,windows gdi绘图机制相关

其实你所谓的draw10000次和draw1次,对gdi来说没有任何不同,都是先在内存中画,再显卡1次
你要做的是先在内存中draw10……

------解决方案--------------------
只画界面显示的,你判断超过区域的就别画,这样的话就画非常少,不会有你说的画10000次
------解决方案--------------------
C/C++ code
// OnPaint的时候,只执行了bitblt。

void CMathCalc::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    
    // TODO: Add your message handler code here
     ::BitBlt( g____mathfun_canvasdc, g____mathfun_canvas_l, g____mathfun_canvas_t, g____mathfun_canvas_w, g____mathfun_canvas_h, g____mathfun_memdc, 0, 0, SRCCOPY );
    
    // Do not call CDialog::OnPaint() for painting messages
}

// 按下右键,拖动图形
void CMathCalc::OnMouseMove(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    
    if( MK_RBUTTON == nFlags )
    {
        if( m_bmove )
        {
            int dx, dy;

            dx = m_x - point.x;
            dy = m_y - point.y;

            g____mathfun_cx -= dx;
            g____mathfun_cy -= dy;


            g____mathfun_draw();

            m_x = point.x;
            m_y = point.y;
        }
    }

    CDialog::OnMouseMove(nFlags, point);
}

void
g____mathfun_draw( void )
{
    int i;
    i = 0;

    myclear();
    
    // 画图像的具体代码在这里,要优化的地方主要也在这里
    
    ShowPic();
}

// 清除背景为白色,本质就是一个bitblt
void
myclear( void )
{
    ::BitBlt( g____mathfun_memdc, 0, 0, g____mathfun_canvas_w, g____mathfun_canvas_h, g____mathfun_backdc, 0, 0, SRCCOPY );
}

// 直接显示到屏幕上,可在任意地方直接调用,本例中在MouseMove中调用
void
ShowPic( void )
{
    ::BitBlt( g____mathfun_canvasdc, g____mathfun_canvas_l, g____mathfun_canvas_t, g____mathfun_canvas_w, g____mathfun_canvas_h, g____mathfun_memdc, 0, 0, SRCCOPY );
}

------解决方案--------------------