本人有个应用:需要再在窗口客户区绘制若干图形,并以一副位图为背景。
我采用双缓冲的方法:在OnDraw()中定义两个memDc,现在其中一个memdc上画好位图,
再贴到另一个上memdc,再在其上画所需的图形。最后,把memdc贴到pDC上。
但是,使用这种方法,速度实在不太令人满意。我另有两个思路,但不知具体实现方法,特拿来望高手解难:
方法一。我先在OnEraseBkgnd()中画好背景位图,然后在OnDraw()中画图形,但,如果
我在OnDraw中把画好图形的memDc贴到pDC上时,就会自动覆盖背景图像,背景部分显示为
黑色,就算我使用memdc.SetBkMode(TRANSPARENT)也一样。  郁闷。
方法二:在OnDraw画图时,只绘制GetClipBox()取得的区域,在这个区域中画图形还好,
可不知怎么画背景图像(只画部分位图?)。  郁闷,TOO。不知那位朋友,能帮我解决此问题,真是万分感谢。  这里先100分,不够再开贴加分。

解决方案 »

  1.   

    希望对你有用。原理应该差不多。-------- 背景图上移动显示一个文本文件的所有内容--------//给你一个函数,很早以前的了,可以在一幅背景图上移动显示一个文本文件的所有内容。使用方法,先调用:ShowText( hdc, rect, szTextFileName ); 进行初始化,然后在定时器中调用ShowScrollText函数就可以了,具体的使用你可以看懂源代码在进行修改,原理差不多。typedef struct
    {
     unsigned long _CTRL_FMT_;
     char  * textBuff;            //文本缓冲区,<32000个字节
     HFONT   TextFont;            //滚动的文本字体句柄
     COLORREF TextColor,TextBkColor;
     int     TextOffX,TextOffY;
     int     TextWidth,TextHigh;
     int     DX,DY; 
     HDC     hBgDC;               //背景DC
     HBITMAP hBgBMP;              //背景BMP
     HDC     hFgDC;               //前景DC
     HBITMAP hFgBMP;              //前景BMP
     int     left,top;            //显示区域的左上角坐标
     int     width,high;          //显示区域的宽,高
     RECT    rect;                //背景的显示区域
     int     dx,dy,dz;            //滚动的三个方向的步进值
    }_Scroll_Text_;_Scroll_Text_ ScrollText;void ShowText(HDC hdc,RECT rect, char *textFile)
    {
     FILE * fp;
     char * textBuff;
     unsigned int fileSize;
     RECT bkRect; fp=fopen(textFile,"rt");
     fileSize=(unsigned int)filelength(fileno(fp))+1;
     if(fileSize>32000) fileSize=32000;
     textBuff=malloc(fileSize);
     memset(textBuff,0,fileSize);
     fread(textBuff,fileSize,1,fp);
     fclose(fp); CreatFont(FALSE);
     if((_CTRL_FMT_&tEF_X_MOVE)||
     (_CTRL_FMT_&tEF_Y_MOVE)||
     (_CTRL_FMT_&tEF_Z_MOVE))
     {
      ScrollText._CTRL_FMT_=_CTRL_FMT_;
      ScrollText.textBuff = textBuff;
      ScrollText.TextColor=_SUB_LeftTop_;
      ScrollText.TextBkColor=_SUB_RightBottom_;
      ScrollText.TextOffX=HIWORD(_SUB_CTRL_FMT_);
      ScrollText.TextOffY=LOWORD(_SUB_CTRL_FMT_);  ScrollText.width = rect.right-rect.left+1;
      ScrollText.high  = rect.bottom-rect.top+1;
      ScrollText.left  = rect.left;
      ScrollText.top   = rect.top;  ScrollText.rect.left   = 0;
      ScrollText.rect.top    = 0;
      ScrollText.rect.right  = ScrollText.width;
      ScrollText.rect.bottom = ScrollText.high;  ScrollText.hBgBMP=CreateCompatibleBitmap(hdc,
     ScrollText.width,
     ScrollText.high);
      ScrollText.hBgDC=CreateCompatibleDC(hdc);
      SelectObject(ScrollText.hBgDC,ScrollText.hBgBMP);  ScrollText.hFgBMP=CreateCompatibleBitmap(hdc,
     ScrollText.width,
     ScrollText.high);
      ScrollText.hFgDC=CreateCompatibleDC(hdc);
      SelectObject(ScrollText.hFgDC,ScrollText.hFgBMP);  SetBkMode(ScrollText.hFgDC,TRANSPARENT);
      SelectObject(ScrollText.hFgDC, ScrollText.TextFont);  BitBlt(ScrollText.hBgDC,0,0,ScrollText.width,ScrollText.high,
    hdc,rect.left,rect.top,SRCCOPY);  _SCROLL_TEXT_=TRUE;
     }
     else
      _SCROLL_TEXT_=FALSE; SetBkMode(hdc,TRANSPARENT);
     SelectObject(hdc, TextFont);
     if(_CTRL_FMT_&tEF_FLOAT)
     {
      bkRect.left   =rect.left   +HIWORD(_SUB_CTRL_FMT_);
      bkRect.top    =rect.top    +LOWORD(_SUB_CTRL_FMT_);
      bkRect.right  =rect.right  +HIWORD(_SUB_CTRL_FMT_);
      bkRect.bottom =rect.bottom +LOWORD(_SUB_CTRL_FMT_);  SetTextColor(hdc,_SUB_RightBottom_);
      DrawText(hdc,textBuff,-1,&bkRect,DT_LEFT|DT_NOPREFIX);
      SetTextColor(hdc,_SUB_LeftTop_);
      DrawText(hdc,textBuff,-1,&rect,DT_LEFT|DT_NOPREFIX);  ScrollText.TextHigh=DrawText(hdc,textBuff,-1,&rect,
     DT_LEFT|DT_NOPREFIX|DT_CALCRECT);
      ScrollText.TextWidth=rect.right;
     }
     else
     {
      SetTextColor(hdc,_SUB_LeftTop_);
      DrawText(hdc,textBuff,-1,&rect,DT_LEFT|DT_NOPREFIX);
      ScrollText.TextHigh=DrawText(hdc,textBuff,-1,&rect,
     DT_LEFT|DT_NOPREFIX|DT_CALCRECT);
      ScrollText.TextWidth=rect.right;
     }
     if(!_SCROLL_TEXT_)
     {
      DeleteObject(TextFont);
      free(textBuff);
     }
    }void ShowScrollText(HWND hWnd)
    {
     HDC hdc;
     RECT bkRect; hdc=GetDC(hWnd);
     BitBlt(ScrollText.hFgDC,0,0,ScrollText.width,ScrollText.high,
      ScrollText.hBgDC,0,0,SRCCOPY); ScrollText.DX+=ScrollText.dx;
     if(abs(ScrollText.DX)<ScrollText.TextWidth)
      ScrollText.rect.left+=ScrollText.dx;
     else
     {
      ScrollText.DX=
      ScrollText.rect.left=0;
     } ScrollText.DY+=ScrollText.dy;
     if(abs(ScrollText.DY)<ScrollText.TextHigh)
      ScrollText.rect.top +=ScrollText.dy;
     else
     {
      ScrollText.DY=
      ScrollText.rect.top=0;
     }// SetBkMode(ScrollText.hFgDC,TRANSPARENT);
    // SelectObject(ScrollText.hFgDC, ScrollText.TextFont); if(ScrollText._CTRL_FMT_&tEF_FLOAT)
     {
      bkRect.left   =ScrollText.rect.left   +ScrollText.TextOffX;
      bkRect.top    =ScrollText.rect.top    +ScrollText.TextOffY;
      bkRect.right  =ScrollText.rect.right  +ScrollText.TextOffX;
      bkRect.bottom =ScrollText.rect.bottom +ScrollText.TextOffY;  SetTextColor(ScrollText.hFgDC,ScrollText.TextBkColor);
      DrawText(ScrollText.hFgDC,ScrollText.textBuff,-1,&bkRect,DT_LEFT|DT_NOPREFIX);
      SetTextColor(ScrollText.hFgDC,ScrollText.TextColor);
      DrawText(ScrollText.hFgDC,ScrollText.textBuff,-1,&ScrollText.rect,DT_LEFT|DT_NOPREFIX);
     }
     else
     {
      SetTextColor(ScrollText.hFgDC,ScrollText.TextColor);
      DrawText(ScrollText.hFgDC,ScrollText.textBuff,-1,&ScrollText.rect,DT_LEFT|DT_NOPREFIX);
     } BitBlt(hdc,ScrollText.left,ScrollText.top,ScrollText.width,ScrollText.high,
      ScrollText.hFgDC,0,0,SRCCOPY);
     ReleaseDC(hWnd,hdc);

      

  2.   

    看不出楼主的第一种改进方法中在OnEraseBkgnd和OnDraw画背景位图有什么区别,性能都是一样的吧。
    如果背景图一直不变,那你的一个memdc可以保存背景位图,只需要初始化一次就够了,不要在OnDraw里读取
      

  3.   

    谢: KcSoft(蓝珍珠精灵),正在学习中。
    回: sunyard() 
    1。用OnEraseBkgnd的话,我在画前景时,就无需重画背景:InvalidateRect(&rc,FALSE).
    2。我是在构造函数中初始化的位图。大家,看看我的代码吧,看看有什么问题。(见下贴)
      

  4.   

    void CLNCCView::OnDraw(CDC* pDC)
    {
    CRect rc;
    GetClientRect(&rc); CRect rc2 = rc;
    pDC->DPtoLP(&rc2);/////////初始化memDC////////////////////////////////////////
             CDC memDc;
    ASSERT( memDc.CreateCompatibleDC(pDC) );

    CBitmap bitmap;
    ASSERT( bitmap.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height()) ); OnPrepareDC(&memDc);  CBitmap * pOldBitmap; 
    pOldBitmap = memDc.SelectObject(&bitmap); memDc.SetBkMode(TRANSPARENT);/////////初始化背景memDc2////////////////////////////////////////
    CDC memDc2;
    ASSERT( memDc2.CreateCompatibleDC(pDC) ); CBitmap * pOldBitmap2;          //bitmap2(CBitmap)、bmp(BITMAP)已在构造函数中初始化
    pOldBitmap2 = memDc2.SelectObject(&bitmap2);  memDc.StretchBlt(rc2.left,rc2.top,
                        rc2.Width(),rc2.Height(),
            &memDc2,
            0,0,
            bmp.bmWidth,bmp.bmHeight,
            SRCCOPY);/////////在memDc上画图//////////////////////////////////////// mychart->DrawChart(&memDc, rc2);   //为了测试,只画了几个简单的线条 pDC ->BitBlt(rc2.left,rc2.top,rc2.Width(),rc2.Height(),
        &memDc,
                          0,0,
                          SRCCOPY);///////////////////////////////////////////////////////////////
    pDC->SetViewportOrg(0, 0);
    pDC->SetWindowOrg(0,0);
    pDC->SetMapMode(MM_TEXT); memDc.SelectObject(pOldBitmap);
    memDc2.SelectObject(pOldBitmap2); memDc.DeleteDC();
    memDc2.DeleteDC(); bitmap.DeleteObject();
    }