本人比较笨,在Onpaint中利用双缓存绘图,需要添加滚动条。现在我已经添加了滚动条的函数,对话框上的控件可以移动,但是利用双缓存画出来的图形不跟着移动。请问在Onpaint中如何将滚动条关联起来?最好有特定的函数。万分感谢!

解决方案 »

  1.   

    在Bitblt或者StretchBlt的时候根据滚动条的位置贴相应位置的图就可以了。。~
      

  2.   

    类似于这样试下。。CPaintDC dc(this);CRect rect;
    GetClientRect(&rect);CDC dcMem; 
    dcMem.CreateCompatibleDC(&dc); CSize szScroll = GetTotalSize();CBitmap bmpMem;
    bmpMem.CreateCompatibleBitmap(&dc, szScroll.cx, szScroll.cy);CBitmap* pBmpOld = dcMem.SelectObject(&bmpMem);DrawMemImage(dcMem, szScroll);dc.BitBlt(0, 0, rect.Width(), rect.Height(), &dcMem, GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT), SRCCOPY);dcMem.SelectObject(pBmpOld);
    bmpMem.DeleteObject();dcMem.DeleteDC();
      

  3.   

    非常感谢你的回复。我比较笨,再问一下,我将程序改动之后,编译时出现这样的问题:error C2065: 'GetTotalSize' : undeclared identifier
    error C2065: 'DrawMemImage' : undeclared identifier
    问一下是怎么回事啊?谢谢你!
      

  4.   

    GetTotalSize是CScrollView的成员函数。。DrawMemImage得自己实现,具体的绘制放在这个函数中。。
      

  5.   


    楼上,您好!我是在对话框中画图,需要水平滚动条。刚开始学习,我把画图的语句都写在OnPaint函数中了,我摘抄了一部分程序如下,麻烦您帮我看看。另外滚动条的程序在CTSRCureDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)中,这样,对话框中的控件可以随着滚动条移动,但是图形不移动。应该在OnPaint函数中做哪些修改?谢谢!void CTSRCureDlg::OnPaint() 
    {
    CPaintDC dc(this); // device context for painting

    // TODO: Add your message handler code here

    // Do not call CDialog::OnPaint() for painting messages CDC *pDC;
    pDC=GetDC();
    CRect DrawRect;
    CRect sideRect;
    CBitmap MemBT;
    CDC MemDC;
    GetClientRect(&DrawRect);

    int PicWidth,PicHeight;
    int HRect,WRect; //绘图区Rect长宽
    CPoint ZeroPos,NowPos,OldPos;
    int WidEdge,HeiEdge; //边缘
    int ppiHRect,ppiWRect; //绘图区长宽像素点 int dotFlag=0;
    int alertFlag=0;
    HRect=200;
    WRect=1000;
    ppiHRect=225;
    ppiWRect=2060;
    WidEdge=30;
    HeiEdge=25;
    float measureSpeed=0.5;
    float measureDist=0.02;
    CFont numFont;   CPen LinePen(PS_SOLID,1,RGB(85,85,85)); //银灰色
    numFont.CreatePointFont(80,"黑体",NULL);


    int yNum=0,xNum=0,sDot;

    int tmpCurSpeed,tmpCurDist;
    CString yNumStr,xNumStr,strTrainNum,strCurSpeed,strCurPos,strCSDscp;
    CPoint tmpPoint;
    PicWidth=DrawRect.Width(); //客户区宽度
    PicHeight=DrawRect.Height(); //客户区长度
    ZeroPos.x=WidEdge;
    ZeroPos.y=ppiHRect;
    //--------------------------双缓存绘图
    MemDC.CreateCompatibleDC(pDC);
    MemBT.CreateCompatibleBitmap(pDC,PicWidth,PicHeight);
    MemDC.SelectObject(&MemBT);
    DrawRect.SetRect(WidEdge,HeiEdge,ppiWRect,ppiHRect); //黑色画布区域
    /*--------边框----------*/
    sideRect.SetRect(WidEdge-5,HeiEdge-5,ppiWRect+5,ppiHRect+5);
    /*----------------------*/
    MemDC.FillSolidRect(0,0,PicWidth,PicHeight,RGB(255,255,255));
    MemDC.FillSolidRect(sideRect,RGB(85,85,85)); //待修改,填充边框代码
    MemDC.FillSolidRect(DrawRect,RGB(0,0,0));
    MemDC.SetBkMode(TRANSPARENT); //文字背景透明

    for (int i=0;i<8;i++) //横网格线
    {
    MemDC.SelectObject(&LinePen);
    MemDC.MoveTo(WidEdge,ppiHRect-i*HRect/8);
    MemDC.LineTo(ppiWRect,ppiHRect-i*HRect/8);
    MemDC.SelectObject(&numFont);
    yNumStr.Format("%d",yNum+i*50);
    MemDC.SetTextColor(RGB(0,0,0));
    if (i==7)
    {
    MemDC.SetTextColor(RGB(255,0,0));
    }
    MemDC.TextOut(5,ppiHRect-i*HRect/8,yNumStr);
    }
    for (i=0;i<21;i++) //纵网格线
    {
    MemDC.MoveTo(WidEdge+i*(WRect/5*measureSpeed),ppiHRect);
    MemDC.LineTo(WidEdge+i*(WRect/5*measureSpeed),ppiHRect-8);
    if (((i%2)==0))
    {
    MemDC.MoveTo(WidEdge+i*(WRect/5*measureSpeed),ppiHRect);
    MemDC.LineTo(WidEdge+i*(WRect/5*measureSpeed),HeiEdge);
    }
    if (i>0)
    {
    yNumStr.Format("%d",yNum+i*5000);
    MemDC.SetTextColor(RGB(0,0,0));
    MemDC.TextOut(i*WRect/5*measureSpeed+25,ppiHRect+10,yNumStr);
    }
    } pDC->BitBlt(0,0,PicWidth,PicHeight,&MemDC,0,0,SRCCOPY);
    MemBT.DeleteObject();
    MemDC.DeleteDC();
    }
      

  6.   

    在滚动条事件下 Invalidate(); 不过必须有成员变量或全局变量在 onpaint 中
      

  7.   

    依靠修改成员变量或全局变量 在Invalidate(); 
      

  8.   

    稍微修改了下。。virtual BOOL OnInitDialog();
    afx_msg void OnPaint();
    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);int m_nScrollPos;
    BEGIN_MESSAGE_MAP(CTSRCureDlg, CDialog)
    ON_WM_PAINT()
    ON_WM_HSCROLL()
    ON_WM_ERASEBKGND()
    ON_WM_SIZE()
    END_MESSAGE_MAP()
    BOOL CTSRCureDlg::OnInitDialog()
    {
    CDialog::OnInitDialog(); SCROLLINFO si;
    si.cbSize = sizeof(SCROLLINFO);
    si.fMask = SIF_ALL; 
    si.nMin = 0;
    si.nMax = 2060;
    si.nPage = 100;
    si.nPos = 0;
    SetScrollInfo(SB_HORZ, &si, TRUE);  m_nScrollPos = 0; return TRUE;  // return TRUE unless you set the focus to a control
    // 异常: OCX 属性页应返回 FALSE
    }void CTSRCureDlg::OnPaint()
    {
    CPaintDC dc(this); // device context for painting
    // TODO: 在此处添加消息处理程序代码
    // 不为绘图消息调用 CDialog::OnPaint() //CDC *pDC;
    //pDC=GetDC();
    CDC* pDC = &dc; CRect DrawRect;
    CRect sideRect;
    CBitmap MemBT;
    CDC MemDC;
    GetClientRect(&DrawRect); int PicWidth,PicHeight;
    int HRect,WRect; //绘图区Rect长宽
    CPoint ZeroPos,NowPos,OldPos;
    int WidEdge,HeiEdge; //边缘
    int ppiHRect,ppiWRect; //绘图区长宽像素点 int dotFlag = 0; 
    int alertFlag = 0;
    HRect = 200;
    WRect = 1000;
    ppiHRect = 225;
    ppiWRect = 2060; 
    WidEdge = 30;
    HeiEdge = 25;
    float measureSpeed = 0.5f;
    float measureDist = 0.02f;
    CFont numFont; CPen LinePen(PS_SOLID, 1 ,RGB(85, 85, 85)); //银灰色
    numFont.CreatePointFont(80, _T("黑体"), NULL);
    int yNum=0, xNum=0/*,sDot*/; //int tmpCurSpeed,tmpCurDist;
    CString yNumStr,xNumStr,strTrainNum,strCurSpeed,strCurPos,strCSDscp;
    CPoint tmpPoint;
    PicWidth=DrawRect.Width(); //客户区宽度
    PicHeight=DrawRect.Height(); //客户区长度
    ZeroPos.x=WidEdge;
    ZeroPos.y=ppiHRect; //--------------------------双缓存绘图
    MemDC.CreateCompatibleDC(pDC);
    //MemBT.CreateCompatibleBitmap(pDC,PicWidth,PicHeight);
    MemBT.CreateCompatibleBitmap(pDC,ppiWRect, PicHeight);
    MemDC.SelectObject(&MemBT);
    DrawRect.SetRect(WidEdge,HeiEdge,ppiWRect,ppiHRect); //黑色画布区域
    /*--------边框----------*/
    sideRect.SetRect(WidEdge-5,HeiEdge-5,ppiWRect+5,ppiHRect+5);
    /*----------------------*/
    //MemDC.FillSolidRect(0,0,PicWidth,PicHeight,RGB(255,255,255));
    MemDC.FillSolidRect(0,0,ppiWRect,PicHeight,RGB(255,255,255));
    MemDC.FillSolidRect(sideRect,RGB(85,85,85)); //待修改,填充边框代码
    MemDC.FillSolidRect(DrawRect,RGB(0,0,0));
    MemDC.SetBkMode(TRANSPARENT); //文字背景透明 for( int i = 0; i < 8; i++ ) //横网格线
    {
    MemDC.SelectObject(&LinePen);
    MemDC.MoveTo(WidEdge, ppiHRect-i*HRect/8);
    MemDC.LineTo(ppiWRect, ppiHRect-i*HRect/8);
    MemDC.SelectObject(&numFont);
    yNumStr.Format(_T("%d"), yNum+i*50);
    MemDC.SetTextColor(RGB(0,0,0)); if (i == 7)
    {
    MemDC.SetTextColor(RGB(255,0,0));
    } MemDC.TextOut(5, ppiHRect-i*HRect/8, yNumStr);
    } for( int i = 0; i < 21; i++ ) //纵网格线
    {
    MemDC.MoveTo((int)(WidEdge+i*(WRect/5*measureSpeed)), ppiHRect);
    MemDC.LineTo((int)(WidEdge+i*(WRect/5*measureSpeed)), ppiHRect-8); if(( (i%2) == 0 ))
    {
    MemDC.MoveTo((int)(WidEdge+i*(WRect/5*measureSpeed)),ppiHRect);
    MemDC.LineTo((int)(WidEdge+i*(WRect/5*measureSpeed)),HeiEdge);
    }
    if (i > 0)
    {
    yNumStr.Format(_T("%d"), yNum+i*5000);
    MemDC.SetTextColor(RGB(0,0,0));
    MemDC.TextOut((int)(i*WRect/5*measureSpeed+25), ppiHRect+10, yNumStr);
    }
    } //pDC->BitBlt(0,0,PicWidth,PicHeight,&MemDC,0,0,SRCCOPY);
    pDC->BitBlt(0,0,PicWidth,PicHeight,&MemDC,m_nScrollPos,0,SRCCOPY);
    MemBT.DeleteObject();
    MemDC.DeleteDC();
    }void CTSRCureDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    CRect rc;
    GetClientRect(&rc); int nDelta(0);
    int nMaxPos = 2060 - rc.Width() - 30; switch (nSBCode)
    {
    case SB_LINEDOWN:
    if (m_nScrollPos >= nMaxPos)
    return; nDelta = min(max(nMaxPos/20, 5), nMaxPos-m_nScrollPos);
    break; case SB_LINEUP:
    if (m_nScrollPos <= 0)
    return;
    nDelta = -min(max(nMaxPos/20, 5), m_nScrollPos);
    break; case SB_PAGEDOWN:
    if (m_nScrollPos >= nMaxPos)
    return;
    nDelta = min(max(nMaxPos/10, 5), nMaxPos-m_nScrollPos);
    break; case SB_PAGEUP:
    if (m_nScrollPos <= 0)
    return;
    nDelta = -min(max(nMaxPos/10, 5), m_nScrollPos);
    break; case SB_THUMBTRACK:
    case SB_THUMBPOSITION:
    nDelta = (int)nPos - m_nScrollPos;
    break; default:
    return;
    } m_nScrollPos += nDelta; SetScrollPos(SB_HORZ, m_nScrollPos,TRUE); Invalidate(); CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
    }BOOL CTSRCureDlg::OnEraseBkgnd(CDC* pDC)
    {
    //return CDialog::OnEraseBkgnd(pDC);
    return TRUE;
    }
      

  9.   

    对话框添加滚动条需要处理WM_HSCROLL/WM_VSCROLL
      

  10.   

    大侠有没有demo发给我看看呢
    [email protected]