我是在一个对话框里加了一个picture控件,希望实现,能够点击按钮实现图像的放大和缩小,并且当图像大于picture控件时,可以用滚动条拖动,我自己添加了两个滚动条,我可以实现不放大情况下的拖动,但是不知道如何去实现图像放大后的滚动,请高手给些提示。下面是关键代码:
void CMainDialog::OnPaint() 
{
CPaintDC dc(this); // device context for painting
RECT   rc = {0,0,img->Width(),img->Height()} ;
this->Actual_to_Scaled (rc) ;   //用于放大或缩小图像,将原图像的矩形改变为放大或缩小后的矩形 CDC* pDC =m_pic1.GetWindowDC(); //picture控件的cdc
        img->DrawToHDC (pDC->m_hDC, &rc) ;//将自己定义的图像对象img画到pdc上面,
ReleaseDC(pDC);
}void CMainDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
switch (nSBCode)
{
case SB_TOP:
m_ImgVScrollPos = 0;   //滚动条的位置保存在m_ImgVScrollPos 中
break;
case SB_BOTTOM:
m_ImgVScrollPos = INT_MAX;
break;
case SB_THUMBTRACK:
m_ImgVScrollPos = nPos;
break;
}
        //在这里我就不知道如何去实现放大后的滚动了
         .....................................
        Invalidate()
this->SetScrollPos(SB_VERT,m_ImgVScrollPos);
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}void CMainDialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
// TODO: Add your message handler code here and/or call default
switch (nSBCode)
{
case SB_TOP:
m_ImgHScrollPos = 0;
break;
case SB_BOTTOM:
m_ImgHScrollPos = INT_MAX;
break;
case SB_THUMBTRACK:
m_ImgHScrollPos= nPos;
break;
}
//................................................
        this->SetScrollPos(SB_HORZ,m_ImgHScrollPos);
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

解决方案 »

  1.   

    用文档试图结构
    CScrollView::SetScrollSizes()
    直接搞定。
      

  2.   

    如果是对话框,你试试在onpaint时
    dc.SetWindowOrg(0,m_ImgVScrollPos );
    不过最好是在文档视图机构中,系统替你做了。
      

  3.   

    抄襲了別人的   看看這個網站會不會對你有所幫助啊
    http://www.codeproject.com/KB/docview/McCZoomView.aspx
      

  4.   

    建议使用内存DC绘图。
    建一个“足够大”的内存DC,每次只把picture控件大小的内存DC中对应的部分copy出来。
    拖动滚动条实际上就成了改变copy的起始坐标了。缩放都是在内存DC里完成的。所以不会受影响。
      

  5.   

    哈哈,我也在做这个
    刚刚响应OnMouseWheel实现了图像的放大缩小,之前实现了没放大的拖动,现在也要整合起来,还在琢磨加油,兄弟
      

  6.   

    1.先确定m_pic1的大小 这个应该是固定的。
    2.明确要显示放大图片的大小。
    3.通过1 2 计算滚动条的范围。
    4.用Strecthblt()把原图放大贴到m_pic1上。
    5.当滚动条滚动获得滚动块位置,刷新,在ONPAINT()里改Strecthblt()里面源DC开始位置把图贴上来
      

  7.   

    貌似比较麻烦,但应该不是很难。MFC很久没用了,只能说上一个大概的思路来,不过这个思路应该是可行的,因为以前做过和LZ要求类似的东西。一个就是图像的缩放,没用过LZ所说的picture控件。换了我就自己实现一个图像缩放的算法,稍微看一下图像处理的书籍就可以实现。再一个就是滚动条的拖动。这个貌似比较麻烦些。首先楼主要确定当前图像显示范围的“大小”,然后确定你的窗口的“大小”。图像超出窗口的部分,就必须通过滚动条滚动来实现。
    其实,说白了,滚动条滚动跟显示内容一点关系都没有。滚动条只是根据总的显示“大小”、窗口大小、和当前显示位置,以及目前滚动过的Delta值,来确定下一次显示的位置。在鼠标拖动滚动条的过程中,其实,窗口区域中在不停的发生擦除、重画的操作。具体点说,楼主需要创建一个memory DC,这个DC要根据你的图像的大小来创建。然后再每次OnDraw或者OnPaint的时候,把这个memory DC贴到显示DC上去。“贴”上去的时候,起始位置要注意,这个起始位置其实就是滚动条当前的“滚动”位置。   每次图像放大或者缩小了,memory DC都要重新生成,以符合目前的实际情况。大概就这样,根据每个人不同的理解,有不同的实现方法。仅供参考:-)
      

  8.   

    今天终于完成了,暂时没发现什么问题,不过代码我不能给,因为是在公司做的。pDC->StretchBlt(paintRect.left, paintRect.top, paintRect.Width(), paintRect.Height(), 
        &dcMem, imgRect.left, imgRect.top, imgRect.Width(), imgRect.Height(), SRCCOPY);
    CRect paintRect; //在CStatic上的哪个区域贴图
    CRect imgRect;   //贴出图像的哪部分缩放、移动都要重新得到正确的paintRect,imgRect,然后重画。
    具体怎么得到,确实挺麻烦的,主要思路要清晰,不过感觉自己也写得很乱,呵呵。
      

  9.   

    楼主,我现在也遇到了你这个问题,方便把源代码发给我吗,参考下  谢谢!邮箱[email protected]