我是在一个对话框里加了一个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);
}
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);
}
CScrollView::SetScrollSizes()
直接搞定。
dc.SetWindowOrg(0,m_ImgVScrollPos );
不过最好是在文档视图机构中,系统替你做了。
http://www.codeproject.com/KB/docview/McCZoomView.aspx
建一个“足够大”的内存DC,每次只把picture控件大小的内存DC中对应的部分copy出来。
拖动滚动条实际上就成了改变copy的起始坐标了。缩放都是在内存DC里完成的。所以不会受影响。
刚刚响应OnMouseWheel实现了图像的放大缩小,之前实现了没放大的拖动,现在也要整合起来,还在琢磨加油,兄弟
2.明确要显示放大图片的大小。
3.通过1 2 计算滚动条的范围。
4.用Strecthblt()把原图放大贴到m_pic1上。
5.当滚动条滚动获得滚动块位置,刷新,在ONPAINT()里改Strecthblt()里面源DC开始位置把图贴上来
其实,说白了,滚动条滚动跟显示内容一点关系都没有。滚动条只是根据总的显示“大小”、窗口大小、和当前显示位置,以及目前滚动过的Delta值,来确定下一次显示的位置。在鼠标拖动滚动条的过程中,其实,窗口区域中在不停的发生擦除、重画的操作。具体点说,楼主需要创建一个memory DC,这个DC要根据你的图像的大小来创建。然后再每次OnDraw或者OnPaint的时候,把这个memory DC贴到显示DC上去。“贴”上去的时候,起始位置要注意,这个起始位置其实就是滚动条当前的“滚动”位置。 每次图像放大或者缩小了,memory DC都要重新生成,以符合目前的实际情况。大概就这样,根据每个人不同的理解,有不同的实现方法。仅供参考:-)
&dcMem, imgRect.left, imgRect.top, imgRect.Width(), imgRect.Height(), SRCCOPY);
CRect paintRect; //在CStatic上的哪个区域贴图
CRect imgRect; //贴出图像的哪部分缩放、移动都要重新得到正确的paintRect,imgRect,然后重画。
具体怎么得到,确实挺麻烦的,主要思路要清晰,不过感觉自己也写得很乱,呵呵。