双缓冲绘图及滚动条问题

时间:2023-01-26 23:01:51
大家好,又要麻烦大家了。我想在picture控件里用双缓冲绘图,由于图形比较大,就采用滚动条。滚动条是picture自身带的,用m_static_wave.ShowScrollBar(SB_BOTH)实现的;m_static_wave是picture的关联静态变量。但问题是:运行的结果显示,图形是在整个对话框内绘制的,并且只要对话框的滚动条起作用,控件的滚动条不能移动。代码如下,麻烦各位了!谢谢!
void CTheLastDlg::OnPaint() 
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else

CPaintDC dc(this);      
 
        int nWidth = 1000; 
        int nHeight = 1000;  
 
        //随后建立与屏幕显示兼容的内存显示设备  
        CDC MemDC; //定义一个显示设备对象 
        CBitmap MemBitmap;//定义一个位图对象 
CRect rect;
GetDlgItem(IDC_STATIC_WAVE)->GetWindowRect(&rect);//IDC_STATIC_WAVE是picture的ID号
     GetClientRect(rect);
        MemDC.CreateCompatibleDC(NULL); 
     
        MemBitmap.CreateCompatibleBitmap(&dc,nWidth,nHeight);  
 
        //将位图选入到内存显示设备中 
  
        MemDC.SelectObject(&MemBitmap); 
        MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(0,0,0));  
 
        //绘图 (这是我做实验随便绘制的图)
        //MemDC.Ellipse(m_nEclipseRect);  
    CPen pen(PS_SOLID, 1, RGB(255,0,0)), *pOldPen;
        pOldPen = MemDC.SelectObject(&pen);
MemDC.MoveTo(rect.left,rect.top+rect.Height()/2);
MemDC.LineTo(rect.right,rect.bottom+rect.Height()/2);
MemDC.MoveTo(50,rect.top+rect.Height()/2);
        MemDC.LineTo(rect.right,rect.Height()/2);
 
        //将内存中的图拷贝到屏幕上进行显示 
        dc.SetViewportOrg(-m_nHScrollPos,-m_nVScrollPos); 
        dc.BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY); 
        //绘图完成后的清理 
        MemBitmap.DeleteObject(); 
        MemDC.DeleteDC(); 

        CDialog::OnPaint();
}
}
//下面是滚动条
void CTheLastDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
// TODO: Add your message handler code here and/or call default
SCROLLINFO scrollinfo;       
GetScrollInfo(SB_HORZ,&scrollinfo,SIF_ALL);   
    switch (nSBCode)   
    {   
        case SB_LEFT:   
            ScrollWindow((scrollinfo.nPos-scrollinfo.nMin)*10,0);   
            scrollinfo.nPos = scrollinfo.nMin;   
            SetScrollInfo(SB_HORZ,&scrollinfo,SIF_ALL);   
            break;   
        case SB_RIGHT:   
            ScrollWindow((scrollinfo.nPos-scrollinfo.nMax)*10,0);   
            scrollinfo.nPos = scrollinfo.nMax;   
            SetScrollInfo(SB_HORZ,&scrollinfo,SIF_ALL);   
            break;   
        case SB_LINELEFT:   
            scrollinfo.nPos -= 1;   
            if (scrollinfo.nPos) 
            {   
                scrollinfo.nPos = scrollinfo.nMin;   
                break;   
            }   
            SetScrollInfo(SB_HORZ,&scrollinfo,SIF_ALL);   
            ScrollWindow(10,0);   
            break;   
        case SB_LINERIGHT:   
            scrollinfo.nPos += 1;   
            if (scrollinfo.nPos>scrollinfo.nMax)   
            {   
                scrollinfo.nPos = scrollinfo.nMax;   
                break;   
            }   
            SetScrollInfo(SB_HORZ,&scrollinfo,SIF_ALL);   
            ScrollWindow(-10,0);   
            break;   
        case SB_PAGELEFT:   
            scrollinfo.nPos -= 5;   
            if (scrollinfo.nPos) 
            {   
                scrollinfo.nPos = scrollinfo.nMin;   
                break;   
            }   
            SetScrollInfo(SB_HORZ,&scrollinfo,SIF_ALL);   
            ScrollWindow(10*5,0);               break;   
        case SB_PAGERIGHT:   
            scrollinfo.nPos += 5;   
            if (scrollinfo.nPos>scrollinfo.nMax)   
            {   
                scrollinfo.nPos = scrollinfo.nMax;   
                break;   
            }   
            SetScrollInfo(SB_HORZ,&scrollinfo,SIF_ALL);   
            ScrollWindow(-10*5,0);   
            break;   
        case SB_THUMBPOSITION:   
            break;   
        case SB_THUMBTRACK:   
            ScrollWindow((scrollinfo.nPos-nPos)*10,0);   
            scrollinfo.nPos = nPos;   
            SetScrollInfo(SB_HORZ,&scrollinfo,SIF_ALL);   
            break;   
        case SB_ENDSCROLL:   
            break;   
    }   
    m_nHScrollPos = scrollinfo.nPos*10; 


CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CTheLastDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
// TODO: Add your message handler code here and/or call default
  SCROLLINFO scrollinfo;   
    GetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
    switch (nSBCode)   
    {   
        case SB_BOTTOM:   
            ScrollWindow(0,(scrollinfo.nPos-scrollinfo.nMax)*10);   
            scrollinfo.nPos = scrollinfo.nMax;   
            SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            break;   
        case SB_TOP:   
            ScrollWindow(0,(scrollinfo.nPos-scrollinfo.nMin)*10);   
            scrollinfo.nPos = scrollinfo.nMin;   
            SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            break;           case SB_LINEUP:   
            scrollinfo.nPos -= 1;   
            if (scrollinfo.nPos) 
            {   
                scrollinfo.nPos = scrollinfo.nMin;   
                break;   
            }   
            SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            ScrollWindow(0,10);   
            break;   
        case SB_LINEDOWN:   
            scrollinfo.nPos += 1;   
            if (scrollinfo.nPos>scrollinfo.nMax)   
            {   
                scrollinfo.nPos = scrollinfo.nMax;   
                break;   
            }   
            SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            ScrollWindow(0,-10);   
            break;   
        case SB_PAGEUP:   
            scrollinfo.nPos -= 5;   
            if (scrollinfo.nPos) 
            {   
                scrollinfo.nPos = scrollinfo.nMin;   
                break;   
            }   
            SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            ScrollWindow(0,10*5);   
            break;   
        case SB_PAGEDOWN:   
            scrollinfo.nPos += 5;   
            if (scrollinfo.nPos>scrollinfo.nMax)   
            {   
                scrollinfo.nPos = scrollinfo.nMax;   
                break;   
            }   
            SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            ScrollWindow(0,-10*5);   
            break;   
        case SB_ENDSCROLL:   
             break;   
        case SB_THUMBPOSITION:               // ScrollWindow(0,(scrollinfo.nPos-nPos)*10);    
            break;   
        case SB_THUMBTRACK:   
            ScrollWindow(0,(scrollinfo.nPos-nPos)*10);   
            scrollinfo.nPos = nPos;   
            SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            break;   
    } 
    m_nVScrollPos = scrollinfo.nPos*10; 
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

13 个解决方案

#1


MARK、

#2



CPaintDC dc(this);      

int nWidth = 1000; 
int nHeight = 1000; 

里面的CPaintDC dc(this); 修改为
CDC *pDC = GetDlgItem(你的picture控件ID)->GetDC();
后面用到dc的地方都改一下

#3


好像不对呀。是不是我下面的代码有问题啊?我用的是picture自身带的滚动条。但好像运行的结果是对整个对话框起作用的滚动结果。图片还是充满整个对话框。辛苦各位了!

#4


各位前辈,麻烦看看我的程序,不知道那里出了问题。麻烦各位帮帮忙了。谢谢!

#5


 CRect rect; 
GetDlgItem(IDC_STATIC_WAVE)->GetWindowRect(&rect);//IDC_STATIC_WAVE是picture的ID号 
    GetClientRect(rect); 
这里错了
改为
CWnd * pWnd=GetDlgItem(IDC_STATIC_WAVE);//取得pic控件窗口指针
    CRect rect;   
  pWnd->GetClientRect(rect);//获得预览框客户区矩形 
    CDC *dc=pWnd->GetDC();//载入设备环境 
后面我没细看,类似的地方都要改

#6


还是不对啊,我将下面的相应要该得地方按照shihaojie1219的修改,但运行结果没什么变化啊。

#7


你的程序是基于什么的?

#8


基于对话框,滚动条是使用picture自身的。

#9


是不是你的图尺寸不对
你那picture尺寸多大呢
这个 int nWidth = 1000; 
     int nHeight = 1000;  1000是什么?

#10


我本来是想用picture显示一个曲线图,采用双缓冲绘图技术。int nWidth = 1000; 
    int nHeight = 1000是我在内存开辟的与设备兼容的位图的大小,然后在这个位图上绘图。最后采取BitBlt()将绘制好的图形拷贝到我的picture控件内显示。由于图形尺寸大于picture得大小,所以要采用滚动条。目前,我修改了BitBlt()已经实现图片在picture控件内显示了。但滚动条的问题还没解决。不知道该怎么驱动这个picture。不清楚picture自身带的滚动条与自己手动加上去的滚动条的使用有和区别。

#11


哪位前辈有这方面的例子能否分享一下?我是个VC初学者,对滚动条驱动picture的使用确实很不清楚。谢谢了。

#12


我感觉控件操作与双缓冲显示好像不沾边啊,双缓冲属于设备机制,而控件只要申请内存获取句柄就可以控制了,似乎没有什么问题吧?

#13


在我拖动滚动条的时候,picture控件内的图形及背景会移动,但是背景竟然超出picture区域范围。修改后的代码如下: CWnd * pWnd=GetDlgItem(IDC_STATIC_WAVE);//取得pic控件窗口指针 
       CRect rect;  
       pWnd->GetClientRect(rect);//获得预览框客户区矩形 
       CDC *dc=pWnd->GetDC();//CDC *pDC=GetDlgItem(IDC_STATIC_WAVE)->GetDC();
        nWidth=1000;
nHeight=1000;
        
 
        //随后建立与屏幕显示兼容的内存显示设备  
        CDC MemDC; //首先定义一个显示设备对象 
        CBitmap MemBitmap;//定义一个位图对象 

        MemDC.CreateCompatibleDC(NULL); 
     
        MemBitmap.CreateCompatibleBitmap(dc,nWidth,nHeight);  
 
        MemDC.SelectObject(&MemBitmap); 
     
        MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(0,0,0));  
 
        //绘图 (我随便绘制的一个大于picture区域的两条直线)
     
    CPen pen(PS_SOLID, 1, RGB(255,0,0)), *pOldPen;
        pOldPen = MemDC.SelectObject(&pen);
MemDC.MoveTo(0,0);
MemDC.LineTo(nWidth/2,nHeight/2);
MemDC.MoveTo(1000,nHeight);
        MemDC.LineTo(nWidth,nHeight);
       //将内存中的图拷贝到屏幕上进行显示 
    dc->SetViewportOrg(m_nHScrollPos,m_nVScrollPos); 
    dc->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY); 
        //绘图完成后的清理 
        MemBitmap.DeleteObject(); 
        MemDC.DeleteDC(); 

CDialog::OnPaint();
Invalidate(FALSE);
}
}
//下面是滚动条的控制,可能是下面的代码有误。现在滚动条采用的是自己手动加上的。
// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTheLastDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CTheLastDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
// TODO: Add your message handler code here and/or call default
    SCROLLINFO hscrollinfo;
m_h_scroll.GetScrollInfo(&hscrollinfo,SIF_ALL);
 switch (nSBCode)   
    {   
        case SB_LEFT: 
    m_h_scroll.ScrollWindowEx(hscrollinfo.nPos-hscrollinfo.nMin,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            hscrollinfo.nPos = hscrollinfo.nMin;   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            break;   
        case SB_RIGHT:   
            m_h_scroll.ScrollWindowEx(hscrollinfo.nPos-hscrollinfo.nMax,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            hscrollinfo.nPos = hscrollinfo.nMax;   
             m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            break;   
        case SB_LINELEFT:   
            hscrollinfo.nPos -= 1;   
            if (hscrollinfo.nPos) 
            {   
                hscrollinfo.nPos = hscrollinfo.nMin;   
                break;   
            }   
             m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            m_h_scroll.ScrollWindowEx(10,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_LINERIGHT:   
            hscrollinfo.nPos += 1;   
            if (hscrollinfo.nPos>hscrollinfo.nMax)   
            {   
                hscrollinfo.nPos = hscrollinfo.nMax;   
                break;   
            }   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            m_h_scroll.ScrollWindowEx(-10,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_PAGELEFT:   
            hscrollinfo.nPos -= 5;   
            if (hscrollinfo.nPos) 
            {   
                hscrollinfo.nPos = hscrollinfo.nMin;   
                break;   
            }   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            m_h_scroll.ScrollWindowEx(10*5,0,&rect,NULL,NULL,NULL,SW_ERASE);              
break;   
        case SB_PAGERIGHT:   
            hscrollinfo.nPos += 5;   
            if (hscrollinfo.nPos>hscrollinfo.nMax)   
            {   
                hscrollinfo.nPos = hscrollinfo.nMax;   
                break;   
            }   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            m_h_scroll.ScrollWindowEx(-10*5,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_THUMBPOSITION:   
            break;   
        case SB_THUMBTRACK:   
            m_h_scroll.ScrollWindowEx(hscrollinfo.nPos-nPos,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            hscrollinfo.nPos = nPos;   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            break;   
        case SB_ENDSCROLL:   
            break;   
    }   
    m_nHScrollPos = hscrollinfo.nPos; 
m_h_scroll.UpdateWindow();
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CTheLastDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
// TODO: Add your message handler code here and/or call default
  SCROLLINFO vscrollinfo;   
    m_v_scroll.GetScrollInfo(&vscrollinfo,SIF_ALL);   
//    this->Invalidate(false); 
    //InvalidateRect(NULL,TRUE);    
    switch (nSBCode)   
    {   
        case SB_BOTTOM:   
            m_v_scroll.ScrollWindowEx(0,vscrollinfo.nPos-vscrollinfo.nMax,&rect,NULL,NULL,NULL,SW_ERASE);   
            vscrollinfo.nPos = vscrollinfo.nMax;   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            break;   
        case SB_TOP:   
            m_v_scroll.ScrollWindowEx(0,vscrollinfo.nPos-vscrollinfo.nMin,&rect,NULL,NULL,NULL,SW_ERASE);   
            vscrollinfo.nPos = vscrollinfo.nMin;   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            break;           
case SB_LINEUP:   
            vscrollinfo.nPos -= 1;   
            if (vscrollinfo.nPos) 
            {   
                vscrollinfo.nPos = vscrollinfo.nMin;   
                break;   
            }   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            m_v_scroll.ScrollWindowEx(0,10,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_LINEDOWN:   
            vscrollinfo.nPos += 1;   
            if (vscrollinfo.nPos>vscrollinfo.nMax)   
            {   
                vscrollinfo.nPos = vscrollinfo.nMax;   
                break;   
            }   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            m_v_scroll.ScrollWindowEx(0,-10,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_PAGEUP:   
            vscrollinfo.nPos -= 5;   
            if (vscrollinfo.nPos) 
            {   
                vscrollinfo.nPos = vscrollinfo.nMin;   
                break;   
            }   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            m_v_scroll.ScrollWindowEx(0,10*5,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_PAGEDOWN:   
            vscrollinfo.nPos += 5;   
            if (vscrollinfo.nPos>vscrollinfo.nMax)   
            {   
                vscrollinfo.nPos = vscrollinfo.nMax;   
                break;   
            }   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            m_v_scroll.ScrollWindowEx(0,-10*5,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_ENDSCROLL:   
            // MessageBox("SB_ENDSCROLL");   
            break;   
        case SB_THUMBPOSITION:               // ScrollWindow(0,(scrollinfo.nPos-nPos)*10);   
            // scrollinfo.nPos = nPos;   
            // SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            break;   
        case SB_THUMBTRACK:   
            m_v_scroll.ScrollWindowEx(0,vscrollinfo.nPos-nPos,&rect,NULL,NULL,NULL,SW_ERASE);   
            vscrollinfo.nPos = nPos;   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            break;   
    } 
    m_nVScrollPos = vscrollinfo.nPos; 
m_h_scroll.UpdateWindow();
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
麻烦前辈们抽空帮我看看。谢谢!

#1


MARK、

#2



CPaintDC dc(this);      

int nWidth = 1000; 
int nHeight = 1000; 

里面的CPaintDC dc(this); 修改为
CDC *pDC = GetDlgItem(你的picture控件ID)->GetDC();
后面用到dc的地方都改一下

#3


好像不对呀。是不是我下面的代码有问题啊?我用的是picture自身带的滚动条。但好像运行的结果是对整个对话框起作用的滚动结果。图片还是充满整个对话框。辛苦各位了!

#4


各位前辈,麻烦看看我的程序,不知道那里出了问题。麻烦各位帮帮忙了。谢谢!

#5


 CRect rect; 
GetDlgItem(IDC_STATIC_WAVE)->GetWindowRect(&rect);//IDC_STATIC_WAVE是picture的ID号 
    GetClientRect(rect); 
这里错了
改为
CWnd * pWnd=GetDlgItem(IDC_STATIC_WAVE);//取得pic控件窗口指针
    CRect rect;   
  pWnd->GetClientRect(rect);//获得预览框客户区矩形 
    CDC *dc=pWnd->GetDC();//载入设备环境 
后面我没细看,类似的地方都要改

#6


还是不对啊,我将下面的相应要该得地方按照shihaojie1219的修改,但运行结果没什么变化啊。

#7


你的程序是基于什么的?

#8


基于对话框,滚动条是使用picture自身的。

#9


是不是你的图尺寸不对
你那picture尺寸多大呢
这个 int nWidth = 1000; 
     int nHeight = 1000;  1000是什么?

#10


我本来是想用picture显示一个曲线图,采用双缓冲绘图技术。int nWidth = 1000; 
    int nHeight = 1000是我在内存开辟的与设备兼容的位图的大小,然后在这个位图上绘图。最后采取BitBlt()将绘制好的图形拷贝到我的picture控件内显示。由于图形尺寸大于picture得大小,所以要采用滚动条。目前,我修改了BitBlt()已经实现图片在picture控件内显示了。但滚动条的问题还没解决。不知道该怎么驱动这个picture。不清楚picture自身带的滚动条与自己手动加上去的滚动条的使用有和区别。

#11


哪位前辈有这方面的例子能否分享一下?我是个VC初学者,对滚动条驱动picture的使用确实很不清楚。谢谢了。

#12


我感觉控件操作与双缓冲显示好像不沾边啊,双缓冲属于设备机制,而控件只要申请内存获取句柄就可以控制了,似乎没有什么问题吧?

#13


在我拖动滚动条的时候,picture控件内的图形及背景会移动,但是背景竟然超出picture区域范围。修改后的代码如下: CWnd * pWnd=GetDlgItem(IDC_STATIC_WAVE);//取得pic控件窗口指针 
       CRect rect;  
       pWnd->GetClientRect(rect);//获得预览框客户区矩形 
       CDC *dc=pWnd->GetDC();//CDC *pDC=GetDlgItem(IDC_STATIC_WAVE)->GetDC();
        nWidth=1000;
nHeight=1000;
        
 
        //随后建立与屏幕显示兼容的内存显示设备  
        CDC MemDC; //首先定义一个显示设备对象 
        CBitmap MemBitmap;//定义一个位图对象 

        MemDC.CreateCompatibleDC(NULL); 
     
        MemBitmap.CreateCompatibleBitmap(dc,nWidth,nHeight);  
 
        MemDC.SelectObject(&MemBitmap); 
     
        MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(0,0,0));  
 
        //绘图 (我随便绘制的一个大于picture区域的两条直线)
     
    CPen pen(PS_SOLID, 1, RGB(255,0,0)), *pOldPen;
        pOldPen = MemDC.SelectObject(&pen);
MemDC.MoveTo(0,0);
MemDC.LineTo(nWidth/2,nHeight/2);
MemDC.MoveTo(1000,nHeight);
        MemDC.LineTo(nWidth,nHeight);
       //将内存中的图拷贝到屏幕上进行显示 
    dc->SetViewportOrg(m_nHScrollPos,m_nVScrollPos); 
    dc->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY); 
        //绘图完成后的清理 
        MemBitmap.DeleteObject(); 
        MemDC.DeleteDC(); 

CDialog::OnPaint();
Invalidate(FALSE);
}
}
//下面是滚动条的控制,可能是下面的代码有误。现在滚动条采用的是自己手动加上的。
// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTheLastDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CTheLastDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
// TODO: Add your message handler code here and/or call default
    SCROLLINFO hscrollinfo;
m_h_scroll.GetScrollInfo(&hscrollinfo,SIF_ALL);
 switch (nSBCode)   
    {   
        case SB_LEFT: 
    m_h_scroll.ScrollWindowEx(hscrollinfo.nPos-hscrollinfo.nMin,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            hscrollinfo.nPos = hscrollinfo.nMin;   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            break;   
        case SB_RIGHT:   
            m_h_scroll.ScrollWindowEx(hscrollinfo.nPos-hscrollinfo.nMax,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            hscrollinfo.nPos = hscrollinfo.nMax;   
             m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            break;   
        case SB_LINELEFT:   
            hscrollinfo.nPos -= 1;   
            if (hscrollinfo.nPos) 
            {   
                hscrollinfo.nPos = hscrollinfo.nMin;   
                break;   
            }   
             m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            m_h_scroll.ScrollWindowEx(10,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_LINERIGHT:   
            hscrollinfo.nPos += 1;   
            if (hscrollinfo.nPos>hscrollinfo.nMax)   
            {   
                hscrollinfo.nPos = hscrollinfo.nMax;   
                break;   
            }   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            m_h_scroll.ScrollWindowEx(-10,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_PAGELEFT:   
            hscrollinfo.nPos -= 5;   
            if (hscrollinfo.nPos) 
            {   
                hscrollinfo.nPos = hscrollinfo.nMin;   
                break;   
            }   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            m_h_scroll.ScrollWindowEx(10*5,0,&rect,NULL,NULL,NULL,SW_ERASE);              
break;   
        case SB_PAGERIGHT:   
            hscrollinfo.nPos += 5;   
            if (hscrollinfo.nPos>hscrollinfo.nMax)   
            {   
                hscrollinfo.nPos = hscrollinfo.nMax;   
                break;   
            }   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            m_h_scroll.ScrollWindowEx(-10*5,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_THUMBPOSITION:   
            break;   
        case SB_THUMBTRACK:   
            m_h_scroll.ScrollWindowEx(hscrollinfo.nPos-nPos,0,&rect,NULL,NULL,NULL,SW_ERASE);   
            hscrollinfo.nPos = nPos;   
            m_h_scroll.SetScrollInfo(&hscrollinfo,SIF_ALL);   
            break;   
        case SB_ENDSCROLL:   
            break;   
    }   
    m_nHScrollPos = hscrollinfo.nPos; 
m_h_scroll.UpdateWindow();
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CTheLastDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
// TODO: Add your message handler code here and/or call default
  SCROLLINFO vscrollinfo;   
    m_v_scroll.GetScrollInfo(&vscrollinfo,SIF_ALL);   
//    this->Invalidate(false); 
    //InvalidateRect(NULL,TRUE);    
    switch (nSBCode)   
    {   
        case SB_BOTTOM:   
            m_v_scroll.ScrollWindowEx(0,vscrollinfo.nPos-vscrollinfo.nMax,&rect,NULL,NULL,NULL,SW_ERASE);   
            vscrollinfo.nPos = vscrollinfo.nMax;   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            break;   
        case SB_TOP:   
            m_v_scroll.ScrollWindowEx(0,vscrollinfo.nPos-vscrollinfo.nMin,&rect,NULL,NULL,NULL,SW_ERASE);   
            vscrollinfo.nPos = vscrollinfo.nMin;   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            break;           
case SB_LINEUP:   
            vscrollinfo.nPos -= 1;   
            if (vscrollinfo.nPos) 
            {   
                vscrollinfo.nPos = vscrollinfo.nMin;   
                break;   
            }   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            m_v_scroll.ScrollWindowEx(0,10,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_LINEDOWN:   
            vscrollinfo.nPos += 1;   
            if (vscrollinfo.nPos>vscrollinfo.nMax)   
            {   
                vscrollinfo.nPos = vscrollinfo.nMax;   
                break;   
            }   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            m_v_scroll.ScrollWindowEx(0,-10,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_PAGEUP:   
            vscrollinfo.nPos -= 5;   
            if (vscrollinfo.nPos) 
            {   
                vscrollinfo.nPos = vscrollinfo.nMin;   
                break;   
            }   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            m_v_scroll.ScrollWindowEx(0,10*5,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_PAGEDOWN:   
            vscrollinfo.nPos += 5;   
            if (vscrollinfo.nPos>vscrollinfo.nMax)   
            {   
                vscrollinfo.nPos = vscrollinfo.nMax;   
                break;   
            }   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            m_v_scroll.ScrollWindowEx(0,-10*5,&rect,NULL,NULL,NULL,SW_ERASE);   
            break;   
        case SB_ENDSCROLL:   
            // MessageBox("SB_ENDSCROLL");   
            break;   
        case SB_THUMBPOSITION:               // ScrollWindow(0,(scrollinfo.nPos-nPos)*10);   
            // scrollinfo.nPos = nPos;   
            // SetScrollInfo(SB_VERT,&scrollinfo,SIF_ALL);   
            break;   
        case SB_THUMBTRACK:   
            m_v_scroll.ScrollWindowEx(0,vscrollinfo.nPos-nPos,&rect,NULL,NULL,NULL,SW_ERASE);   
            vscrollinfo.nPos = nPos;   
            m_v_scroll.SetScrollInfo(&vscrollinfo,SIF_ALL);   
            break;   
    } 
    m_nVScrollPos = vscrollinfo.nPos; 
m_h_scroll.UpdateWindow();
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
麻烦前辈们抽空帮我看看。谢谢!