126上位机VC MFC两种实现图片的自由缩放效果
126上位机VC MFC两种实现图片的自由缩放效果
功能展示
一般电脑打开一幅图上都可以进行放大与缩小,我们当前例程通过两种方法也来实现图片的放大与缩小,点击打开位图成功打开后,可以拖拽滑块进行图片的放大与缩小操作,编辑框为缩放的比例,效果如图; 要点提示 图片的放大缩小第种方法是通过设备上下文类CDC的函数StretchBlt()来实现的,前面众多例程都使用了此函数,函数的使用可以参考前面例程;第二种方法是通过GDI+实现的,GDI+实现图片缩放非常方法,具体使用可以参考例程;这里要知道的是滑块再没有关联变量时,它的默认滑动范围是0—100,它的当前值可以通过它的ID来获取,如GetDlgItem(IDC_SLIDER1)->GetPos();
实现功能 1.新建基于对话框的应用程序 2.插入一对话框资源关联一对话框类class CDlg : public Cdialog,再拖拽一图片控件修改其ID为IDC_BMP,关联变量 HBITMAPm_hBitmap;用于显示打开的位图; 添加自定义函数LoadBmp()ResizeBmp()用于打开和缩放位图;
添加水平垂直滚动条消息,用于滚动已打开的大图片OnHScroll() OnVScroll(),下面是函数体 - void CDlg::LoadBmp()
- {
- CFileDialog dlg (true,"bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"位图文件(*.bmp)|*.bmp||",this);
- if (dlg.DoModal()==IDOK)
- {
- CString sPath;
- sPath = dlg.GetPathName();
- m_hBitmap=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),sPath,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_DEFAULTCOLOR|LR_DEFAULTSIZE);
- if (m_hBitmap)
- {
- m_Bmp.SetBitmap(m_hBitmap);
- m_Bmp.CenterWindow();
- }
- //><
- BITMAP bmp;
- GetObject(m_hBitmap,sizeof(bmp),&bmp);
- CRect rect;
- GetClientRect(rect);
- int xpos = GetScrollPos(SB_HORZ);
- if (xpos != 0)
- ScrollWindow(xpos,0); //水平滚动条归零
-
复制代码- int ypos = dlg.GetScrollPos(SB_VERT);
- if (ypos != 0)
- ScrollWindow(0,ypos);
- //><设置垂直滚动条信息
- SCROLLINFO vinfo;
- vinfo.cbSize = sizeof(vinfo);
- vinfo.fMask = SIF_ALL;
- vinfo.nPage = bmp.bmHeight/10;
- vinfo.nMax= bmp.bmHeight-rect.Height()+10;
- vinfo.nMin = 0;
- vinfo.nTrackPos = 0;
- vinfo.nPos = 0;
- SetScrollInfo(SB_VERT,&vinfo);
- //><设置水平滚动条信息
- vinfo.fMask = SIF_ALL;
- vinfo.nPage = bmp.bmWidth/10;
- vinfo.nMax= bmp.bmWidth-rect.Width()+10;
- vinfo.nMin = 0;
- vinfo.nPos = 0;
- vinfo.nTrackPos = 0;
- vinfo.cbSize = sizeof(vinfo);
- SetScrollInfo(SB_HORZ,&vinfo);
- }
- }
- void CDlg::ResizeBmp(double fXRate,double fYRate)
- {
- if(!m_hBitmap)return;
- int xpos = GetScrollPos(SB_HORZ);
- if (xpos != 0)
- ScrollWindow(xpos,0); //水平滚动条归零
- int ypos = GetScrollPos(SB_VERT);
- if (ypos != 0)
- ScrollWindow(0,ypos);
- //><
- CRect rect;
- GetClientRect(rect);
- CDC* pDC = m_Bmp.GetDC();
-
复制代码- CDC memdc;
- memdc.CreateCompatibleDC( pDC );
- memdc.SelectObject(m_hBitmap);
- BITMAP bmp;
- GetObject(m_hBitmap,sizeof(bmp),&bmp);
- int nCX= bmp.bmWidth*fXRate;
- int nCY= bmp.bmHeight*fYRate;
- m_Bmp.MoveWindow(rect.left,rect.top,nCX,nCY,true);
- pDC->StretchBlt(rect.left,rect.top,nCX,nCY,&memdc,0,0, bmp.bmWidth,bmp.bmHeight,SRCCOPY);
- memdc.DeleteDC();
- m_Bmp.ReleaseDC(pDC);
-
- //设置垂直滚动条信息
- SCROLLINFO vinfo;
- vinfo.cbSize = sizeof(vinfo);
- vinfo.fMask = SIF_ALL;
- vinfo.nPage = nCY/10;
- vinfo.nMax= nCY-rect.Height()+10;
- vinfo.nMin = 0;
- vinfo.nTrackPos = 0;
- vinfo.nPos = 0;
- SetScrollInfo(SB_VERT,&vinfo);
-
- //设置水平滚动条信息
- vinfo.fMask = SIF_ALL;
- vinfo.nPage = nCX/10;
- vinfo.nMax= nCX-rect.Width()+10;
- vinfo.nMin = 0;
- vinfo.nPos = 0;
- vinfo.nTrackPos = 0;
- vinfo.cbSize = sizeof(vinfo);
- SetScrollInfo(SB_HORZ,&vinfo);
- }
复制代码- void CDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- // TODO: Add your message handler code here and/or call default
- int pos,min,max,thumbwidth;
- SCROLLINFO vinfo;
- GetScrollInfo(SB_HORZ,&vinfo);
-
- pos = vinfo.nPos;
- min = vinfo.nMin;
- max = vinfo.nMax;
- thumbwidth = vinfo.nPage;
- switch (nSBCode)
- {
- case SB_THUMBTRACK: //拖动滚动块
- ScrollWindow(-(nPos-pos),0);
- SetScrollPos(SB_HORZ,nPos);
- break;
- case SB_LINELEFT : //单击左箭头
- if (pos != 0)
- {
- ScrollWindow(1,0);
- SetScrollPos(SB_HORZ,pos-1);
- }
- break;
- case SB_LINERIGHT: //单击右箭头
- if (pos+thumbwidth <= max)
- {
- SetScrollPos(SB_HORZ,pos+1);
- ScrollWindow(-1,0);
- }
- break;
- case SB_PAGELEFT: //在滚动块的左方空白滚动区域单击
- if (pos >= thumbwidth)
- {
- ScrollWindow(thumbwidth,0);
- SetScrollPos(SB_HORZ,pos-thumbwidth);
- }
复制代码- else
- {
- ScrollWindow(pos,0);
- SetScrollPos(SB_HORZ,0);
- }
- break;
- case SB_PAGERIGHT: //在滚动块的右方空白滚动区域单击
- if (pos+thumbwidth <= max-thumbwidth)
- {
- ScrollWindow(-thumbwidth,0);
- SetScrollPos(SB_HORZ,pos+thumbwidth);
- }
- else
- {
- ScrollWindow(-(max-(pos+thumbwidth)),0);
- SetScrollPos(SB_HORZ,max-thumbwidth);
- }
- break;
- }
- CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
- }
复制代码篇幅有限更多的的函数体可从例程复制 4.最后是自定义类的使用,在主对话框中添加变量CDlg m_Dlg;拖拽按钮控件IDC_OPEN,滑块控件IDC_SLIDER1,编辑框控件IDC_EDIT1,图片控件IDC_RECT 初始化变量m_Dlg.Create(IDD_DIALOG1,this); CRect rc;GetDlgItem(IDC_RECT)->GetWindowRect(rc); m_Dlg.MoveWindow(rc);m_Dlg.ShowWindow(SW_SHOW); GetDlgItem(IDC_RECT)->ShowWindow(SW_HIDE);
按钮调用m_Dlg.LoadBmp();实现图片的打开;添加水平滚动条消息OnHScroll()实现图片的缩放;
代码段为 - void CGkbc8Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- CSliderCtrl *pSlider = (CSliderCtrl *)pScrollBar;
- if(pSlider->GetDlgCtrlID() == IDC_SLIDER1)
- {
- double fRate = pSlider->GetPos();//默认值为0--100
- fRate=fRate/10;
- fRate=fRate==0?0.01:fRate;
- m_Dlg.ResizeBmp(fRate,fRate);
- CString s;
- s.Format("%f",fRate);
- SetDlgItemText(IDC_EDIT1,s);
- }
- CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
- }
复制代码我们来演示整个功能实现过程
|