基于VS2010的MFC对话框编程之图片浏览器(附源代码)
2016-04-11 20:24
591 查看
–>本文先给出了基于VS2010的MFC对话框编程之图片浏览器所能实现的功能以及采用的技术,然后展示效果图,做出总结,最后附上源代码。
–>效果图 1:在最大化状态下的效果图
–>效果图 2:正常状态下的效果图,这时图片铺满窗口
–>效果图 3:对于长宽比不是4:3的图片,将自适应显示
–>效果图 4:可随意对图片进行拖拽和放缩,且窗口不会产生闪烁
本文源代码下载地址:http://download.csdn.net/detail/destiny0321/9490494
–>所实现的功能:
1.采用双缓冲技术解决屏幕闪烁问题;
2.浏览过程中实现图片的拖拽;
3.浏览过程中实现图片的放缩;
4.对当前文件下所支持图片格式(BMP、JPG、PNG)进行显示;
5.实现“上一张图片”和“下一张图片”功能;
6.随时进行窗口的最小化、正常、最大化显示的切换;
–>所用到的工具:CImage类
–>图片的放缩和拖拽主要用到了投影矩形的技术,即:投影矩形所在位置和大小就是图像在屏幕上位置和大小,随着投影矩形的移动和放缩,图像也在屏幕上移动和放缩,当然这里的屏幕指的是与窗口等尺寸的内存屏幕(解决闪烁问题)。我们只需要对投影矩形操作,就能实现一些列诸如放缩、拖拽等的功能。
–>不足之处:
1.由于能力有限,目前不能实现“双击图像文件,打开该图像”的功能,只好点击鼠标右键打开图像;
2.放缩功能有待改进;
3.更多功能将在今后逐渐添加进来!
–>现附上源代码:
以下是需要改动的地方,其他文件无需改动
–>效果图 1:在最大化状态下的效果图
–>效果图 2:正常状态下的效果图,这时图片铺满窗口
–>效果图 3:对于长宽比不是4:3的图片,将自适应显示
–>效果图 4:可随意对图片进行拖拽和放缩,且窗口不会产生闪烁
本文源代码下载地址:http://download.csdn.net/detail/destiny0321/9490494
–>所实现的功能:
1.采用双缓冲技术解决屏幕闪烁问题;
2.浏览过程中实现图片的拖拽;
3.浏览过程中实现图片的放缩;
4.对当前文件下所支持图片格式(BMP、JPG、PNG)进行显示;
5.实现“上一张图片”和“下一张图片”功能;
6.随时进行窗口的最小化、正常、最大化显示的切换;
–>所用到的工具:CImage类
–>图片的放缩和拖拽主要用到了投影矩形的技术,即:投影矩形所在位置和大小就是图像在屏幕上位置和大小,随着投影矩形的移动和放缩,图像也在屏幕上移动和放缩,当然这里的屏幕指的是与窗口等尺寸的内存屏幕(解决闪烁问题)。我们只需要对投影矩形操作,就能实现一些列诸如放缩、拖拽等的功能。
–>不足之处:
1.由于能力有限,目前不能实现“双击图像文件,打开该图像”的功能,只好点击鼠标右键打开图像;
2.放缩功能有待改进;
3.更多功能将在今后逐渐添加进来!
–>现附上源代码:
以下是需要改动的地方,其他文件无需改动
// stdafx.h : 标准系统包含文件的包含文件, // 或是经常使用但不常更改的 // 特定于项目的包含文件 #pragma once #ifndef _SECURE_ATL #define _SECURE_ATL 1 #endif #ifndef VC_EXTRALEAN #define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料 #endif #include "targetver.h" #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的 // 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏 #define _AFX_ALL_WARNINGS #include <afxwin.h> // MFC 核心组件和标准组件 #include <afxext.h> // MFC 扩展 #ifndef _AFX_NO_OLE_SUPPORT #include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持 #endif #ifndef _AFX_NO_AFXCMN_SUPPORT #include <afxcmn.h> // MFC 对 Windows 公共控件的支持 #endif // _AFX_NO_AFXCMN_SUPPORT #include <afxcontrolbars.h> // 功能区和控件条的 MFC 支持 #include <math.h> #include <afxtempl.h> //对 CStringList 的支持 //窗口状态条尺寸 #define RECT_WINDOWBAR (CRect(0,0,70,16)) //窗口状态条尺寸 #define RECT_MINIMIZE (CRect(0,0,20,16)) //最小化图标尺寸 #define RECT_MAXIMIZE (CRect(20,0,40,16)) //最大化图标尺寸 #define RECT_CLOSE (CRect(40,0,70,16)) //关闭窗口图标尺寸 //左右箭头图标尺寸 #define RECT_ARROW_LEFT (CRect(0,0,47,47)) //左箭头图标尺寸 #define RECT_ARROW_RIGHT (CRect(0,0,47,47)) //右箭头图标尺寸 //客户区背景颜色 #define BKCOLOR (RGB(40,40,40)) //正常窗口的宽和高 #define NORMAL_WINDOW_WIDTH 800 #define NORMAL_WINDOW_HEIGHT 600 //窗口状态 enum{ WINDOW_STATE_MINIMIZED, //最小化 WINDOW_STATE_NORMAL, //正常 WINDOW_STATE_MAXIMIZED //最大化 }; //虚拟按钮类型 enum{ BUTTON_TYPE_WINDOWBAR, //窗口状态条 BUTTON_TYPE_CLOSE, //关闭 BUTTON_TYPE_MAXIMAIZE, //最大化 BUTTON_TYPE_MINIMIZE, //最小化 BUTTON_TYPE_NEXT, //下一张图片 BUTTON_TYPE_PREVIOUS //上一张图片 }; //图像尺寸类型 enum { IMG_SIZE_NORMAL, //图像宽高均在绘图范围内 IMG_SIZE_WIDTH_BEYOND, //仅图像宽度超出绘图范围 IMG_SIZE_HEIGHT_BEYOND, //仅图像高度超出绘图范围 IMG_SIZE_BOTH_BEYOND //图像宽高均超出绘图范围 }; #ifdef _UNICODE #if defined _M_IX86 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_X64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") #else #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif #endif
// PicSeeDlg.h : 头文件 // #pragma once // CPicSeeDlg 对话框 class CPicSeeDlg : public CDialogEx { // 构造 public: CPicSeeDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据 enum { IDD = IDD_PICSEE_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: HICON m_hIcon; // 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); afx_msg void OnRButtonUp(UINT nFlags, CPoint point); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnOpen(); DECLARE_MESSAGE_MAP() private: CImage m_Image; //当前图像 CImage m_ImgWindowBar; //窗口状态条图像 CImage m_ImgLeftArrow; //左箭头图像 CImage m_ImgRightArrow; //右箭头图像 CRect m_RectMem; //内存绘图区矩形区域 CRect m_RectScn; //屏幕绘图区区域 CRect m_RectImg; //图像矩形区域 CRect m_RectProj; //投影到内存屏幕的矩形区域 CRect m_RectWindowBar; //当前窗口状态条所在矩形区域 CRect m_RectClose; //当前关闭按钮所在矩形区域 CRect m_RectMaximize; //当前最大化按钮所在矩形区域 CRect m_RectMinimize; //当前最小化按钮所在矩形区域 CRect m_RectLeftArrow; //当前左箭头图标所在区域 CRect m_RectRightArrow; //当前右箭头图标所在区域 BOOL m_bLButttonDown; //鼠标左键状态 BOOL m_bPtInLeft; //鼠标指针是否在左侧 BOOL m_bPtInRight; //鼠标指针是否在右侧 int m_WindowState; //窗口状态 int m_ImgPos; //当前图像所在文件夹中的图像中的位置 int m_ImgSizeType; //图像尺寸类型 CStringList m_ImgPathList; //当前目录下的所支持的图像全路径链表 CPoint m_ptOriginal; //原点 CPoint m_ptTotalOffSet; //到原点的总偏移量 float m_ZoomScale; //缩放尺度 public: //加载图像资源 static BOOL LoadImageFromResource(IN CImage* pImage, IN UINT nResID, IN LPCSTR lpType); //更新按钮所在内存屏幕区域 void UpdateButtonRect(int nButtonType); //更新投影区域 void UpDateProjRect(void); //拖拽图像 void DragImage(CPoint point); //关闭窗口,退出程序 void Close(void); //最大化窗口 void Maximize(void); //最小化窗口 void Minimize(void); //前一张图像 void Previous(void); //后一张图像 void Next(void); //获取除任务栏以外的桌面区域矩形 void GetDesktopRect(LPRECT lpRect) const; };
// PicSeeDlg.cpp : 实现文件 // #include "stdafx.h" #include "PicSee.h" #include "PicSeeDlg.h" #include "afxdialogex.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CPicSeeDlg 对话框 CPicSeeDlg::CPicSeeDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CPicSeeDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); //初始状态 m_bLButttonDown = FALSE; m_bPtInLeft = FALSE; m_bPtInRight = FALSE; m_ImgPathList.RemoveAll(); m_Image.Destroy(); m_ptTotalOffSet = 0; m_ImgPos = -1; m_ZoomScale = 1.0; //加载资源 m_ImgWindowBar.Destroy(); m_ImgLeftArrow.Destroy(); m_ImgRightArrow.Destroy(); LoadImageFromResource(&m_ImgWindowBar, IDB_WINDOWBAR, "BMP"); LoadImageFromResource(&m_ImgLeftArrow, IDB_LEFTARROW, "PNG"); LoadImageFromResource(&m_ImgRightArrow, IDB_RIGHTARROW, "PNG"); } void CPicSeeDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CPicSeeDlg, CDialogEx) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_COMMAND(IDM_OPEN, &CPicSeeDlg::OnOpen) ON_WM_RBUTTONUP() ON_WM_ERASEBKGND() ON_WM_MOUSEMOVE() ON_WM_MOUSEWHEEL() END_MESSAGE_MAP() // CPicSeeDlg 消息处理程序 BOOL CPicSeeDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 //初始化 GetDesktopRect(&m_RectMem); m_RectScn = m_RectMem; //显示窗口 MoveWindow(&m_RectScn); //更改窗口状态 m_WindowState = WINDOW_STATE_MAXIMIZED; //更新虚拟按钮所在矩形区域 UpdateButtonRect(BUTTON_TYPE_WINDOWBAR); UpdateButtonRect(BUTTON_TYPE_CLOSE); UpdateButtonRect(BUTTON_TYPE_MAXIMAIZE); UpdateButtonRect(BUTTON_TYPE_MINIMIZE); UpdateButtonRect(BUTTON_TYPE_PREVIOUS); UpdateButtonRect(BUTTON_TYPE_NEXT); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CPicSeeDlg::OnPaint() { CClientDC dc(this); CDC MemDC; CBitmap MemBitmap; MemDC.CreateCompatibleDC(&dc); MemBitmap.CreateCompatibleBitmap(&dc, m_RectMem.Width(), m_RectMem.Height()); MemDC.SelectObject(&MemBitmap); MemDC.SetStretchBltMode(COLORONCOLOR); //填充背景颜色 MemDC.FillSolidRect(&m_RectMem, BKCOLOR); //画图像 if(!m_Image.IsNull()) { m_Image.Draw(MemDC.GetSafeHdc(), m_RectProj, m_RectImg); } //画窗口工具条 m_ImgWindowBar.Draw(MemDC.GetSafeHdc(), m_RectWindowBar, RECT_WINDOWBAR); //画左箭头 if(m_bPtInLeft) { m_ImgLeftArrow.Draw(MemDC.GetSafeHdc(), m_RectLeftArrow, RECT_ARROW_LEFT); } //画右箭头 if(m_bPtInRight) { m_ImgRightArrow.Draw(MemDC.GetSafeHdc(), m_RectRightArrow, RECT_ARROW_RIGHT); } //贴图 dc.BitBlt(0, 0, m_RectScn.Width(), m_RectScn.Height(), &MemDC, 0, 0, SRCCOPY); //释放资源 MemDC.DeleteDC(); MemBitmap.DeleteObject(); } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CPicSeeDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } BOOL CPicSeeDlg::LoadImageFromResource(IN CImage* pImage, IN UINT nResID, IN LPCSTR lpType) { ////////////////////////////////////////////////////////////////////////// /// 从资源文件中加载图片 /// @param [in] pImage 图片指针 /// @param [in] nResID 资源号 /// @param [in] lpTyp 资源类型 ////////////////////////////////////////////////////////////////////////// if ( pImage == NULL) return false; pImage->Destroy(); // 查找资源 HRSRC hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(nResID), lpType); if (hRsrc == NULL) return false; // 加载资源 HGLOBAL hImgData = ::LoadResource(AfxGetResourceHandle(), hRsrc); if (hImgData == NULL) { ::FreeResource(hImgData); return false; } // 锁定内存中的指定资源 LPVOID lpVoid = ::LockResource(hImgData); LPSTREAM pStream = NULL; DWORD dwSize = ::SizeofResource(AfxGetResourceHandle(), hRsrc); HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize); LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew); ::memcpy(lpByte, lpVoid, dwSize); // 解除内存中的指定资源 ::GlobalUnlock(hNew); // 从指定内存创建流对象 HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream); if ( ht != S_OK ) { GlobalFree(hNew); } else { // 加载图片 pImage->Load(pStream); GlobalFree(hNew); } // 释放资源 ::FreeResource(hImgData); return 0; } void CPicSeeDlg::OnLButtonDown(UINT nFlags, CPoint point) { m_bLButttonDown = TRUE; m_ptOriginal = point; //前一张图片 if(m_RectLeftArrow.PtInRect(point)) { Previous(); }//后一张图片 else if(m_RectRightArrow.PtInRect(point)) { Next(); } CDialogEx::OnLButtonDown(nFlags, point); } void CPicSeeDlg::OnLButtonUp(UINT nFlags, CPoint point) { //左键按下 if(m_bLButttonDown) { //关闭窗口,结束程序 if(m_RectClose.PtInRect(point)) { Close(); } //最大化窗口 if(m_RectMaximize.PtInRect(point)) { Maximize(); } //最小化窗口 if(m_RectMinimize.PtInRect(point)) { Minimize(); } } m_bLButttonDown = FALSE; CDialogEx::OnLButtonUp(nFlags, point); } void CPicSeeDlg::UpdateButtonRect(int nButtonType) { //选择虚拟按钮类型 switch(nButtonType) { case BUTTON_TYPE_WINDOWBAR: m_RectWindowBar = CRect( m_RectMem.right - RECT_WINDOWBAR.Width(), 0, m_RectMem.right, RECT_WINDOWBAR.Height()); break; case BUTTON_TYPE_CLOSE: m_RectClose = CRect( m_RectMem.right - RECT_CLOSE.Width(), 0, m_RectMem.right, RECT_CLOSE.Height()); break; case BUTTON_TYPE_MAXIMAIZE: m_RectMaximize = CRect( m_RectMem.right - RECT_CLOSE.Width() - RECT_MAXIMIZE.Width(), 0, m_RectMem.right - RECT_CLOSE.Width(), RECT_MAXIMIZE.Height()); break; case BUTTON_TYPE_MINIMIZE: m_RectMinimize = CRect( m_RectMem.right - RECT_WINDOWBAR.Width(), 0, m_RectMem.right - RECT_CLOSE.Width() - RECT_MAXIMIZE.Width(), RECT_MINIMIZE.Height()); break; case BUTTON_TYPE_NEXT: m_RectLeftArrow = CRect( 10, (m_RectMem.bottom - m_ImgLeftArrow.GetHeight())/2, 10 + m_ImgLeftArrow.GetWidth(), (m_RectMem.bottom + m_ImgLeftArrow.GetHeight())/2); break; case BUTTON_TYPE_PREVIOUS: m_RectRightArrow = CRect(-10 + m_RectMem.right - m_ImgRightArrow.GetWidth(), (m_RectMem.bottom - m_ImgRightArrow.GetHeight())/2, -10 + m_RectMem.right, (m_RectMem.bottom + m_ImgRightArrow.GetHeight())/2); break; } } void CPicSeeDlg::Close(void) { AfxGetMainWnd()->PostMessage(WM_QUIT); } void CPicSeeDlg::Maximize(void) { m_ptTotalOffSet = 0; m_ZoomScale = 1.0; CRect rectMax; //除任务栏外的桌面矩形区域 CRect rectWnd; //当前窗口矩形区域 GetDesktopRect(&rectMax); GetWindowRect(&rectWnd); if(rectWnd.EqualRect(&rectMax)) { //若果窗口处于最大化状态 CRect rect( (rectWnd.right-NORMAL_WINDOW_WIDTH)/2, (rectWnd.bottom-NORMAL_WINDOW_HEIGHT)/2, (rectWnd.right+NORMAL_WINDOW_WIDTH)/2, (rectWnd.bottom+NORMAL_WINDOW_HEIGHT)/2); MoveWindow(&rect); //屏幕坐标转客户区坐标 ScreenToClient(&rect); m_RectMem = rect; m_RectScn = m_RectMem; //更新窗口状态 m_WindowState = WINDOW_STATE_NORMAL; //更新投影区区域 UpDateProjRect(); } else { //如果窗口没有处于最大化,则最大化窗口 m_RectMem = rectMax; m_RectScn = m_RectMem; MoveWindow(&m_RectScn); m_WindowState = WINDOW_STATE_MAXIMIZED; UpDateProjRect(); } //更新虚拟按钮矩形区域 UpdateButtonRect(BUTTON_TYPE_WINDOWBAR); UpdateButtonRect(BUTTON_TYPE_CLOSE); UpdateButtonRect(BUTTON_TYPE_MAXIMAIZE); UpdateButtonRect(BUTTON_TYPE_MINIMIZE); UpdateButtonRect(BUTTON_TYPE_PREVIOUS); UpdateButtonRect(BUTTON_TYPE_NEXT); } void CPicSeeDlg::Minimize(void) { //最小化窗口 ShowWindow(SW_MINIMIZE); m_WindowState = WINDOW_STATE_MINIMIZED; } void CPicSeeDlg::OnOpen() { m_ptTotalOffSet = 0; //初始化图像总偏移量 m_ZoomScale = 1.0; CString szFilter = "所有支持的文件|*.jpg;*.bmp;*.png;| \ JPG文件|*.jpg| \ BMP文件|*.bmp| \ PNG文件|*.png||"; CFileDialog dlg(TRUE, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter); if(IDCANCEL == dlg.DoModal()) return; //文件完整路径 CString szWholePath = dlg.GetPathName(); //文件名 CString szFileName = dlg.GetFileName(); //文件纯路径 CString szFilePath = szWholePath.Left(szWholePath.GetLength()-szFileName.GetLength()); //清空图像 if(!m_Image.IsNull()) { m_Image.Destroy(); } //加载图像 m_Image.Load(szWholePath); //更新投影区 UpDateProjRect(); //在当前路径下查找所有支持的图像文件 CFileFind finder; BOOL bWorking = finder.FindFile(szFilePath + "*.*"); while(bWorking) { bWorking = finder.FindNextFile(); CString szName = finder.GetFileName(); if(!finder.IsDirectory()) { //如果找到的不是路径 //获取图像类型 CString szType = szName.Right(3); if( (!szType.CompareNoCase("jpg")) || (!szType.CompareNoCase("bmp")) || (!szType.CompareNoCase("png"))) { //如果是支持的图像格式,添加至链表 m_ImgPathList.AddTail(szFilePath+szName); } if(!szName.CompareNoCase(szFileName)) { //如果文件名与当前所显示图像名一致,则记录下该图像的位置 m_ImgPos = m_ImgPathList.GetCount(); } } } } void CPicSeeDlg::UpDateProjRect(void) { //如果当前图像为空,则返回 if(m_Image.IsNull()) return; //获取图像矩形区域 m_RectImg = CRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight()); int MemWidth = m_RectMem.Width(); int MemHeight = m_RectMem.Height(); int ImgWidth = m_RectImg.Width(); int ImgHeight = m_RectImg.Height(); //默认不收缩投影区域 int nGap = 0; //如果窗口处于最大化状态,则投影区域四周各收缩10个像素 if(m_WindowState == WINDOW_STATE_MAXIMIZED) { nGap = 10; } //获取当前图像尺寸类型 if( (ImgWidth <= MemWidth-nGap) && (ImgHeight <= MemHeight-nGap) ) m_ImgSizeType = IMG_SIZE_NORMAL; else if( (ImgWidth>MemWidth-nGap) && (ImgHeight<=MemHeight-nGap) ) m_ImgSizeType = IMG_SIZE_WIDTH_BEYOND; else if( (ImgWidth<=MemWidth-nGap) && (ImgHeight>MemHeight-nGap) ) m_ImgSizeType = IMG_SIZE_HEIGHT_BEYOND; else m_ImgSizeType = IMG_SIZE_BOTH_BEYOND; //对不同的图像尺寸,计算投影区域矩形 switch(m_ImgSizeType) { float fScaleW,fScaleH; //X、Y方向的缩小率 int nW,nH; //长、宽均在显示范围内 case IMG_SIZE_NORMAL: m_RectProj = CRect( (MemWidth-ImgWidth)/2, (MemHeight-ImgHeight)/2, (MemWidth+ImgWidth)/2, (MemHeight+ImgHeight)/2); break; //只有宽超出显示范围 case IMG_SIZE_WIDTH_BEYOND: fScaleW = ((double)MemWidth)/ImgWidth; nW = MemWidth; nH = fScaleW*ImgHeight; m_RectProj = CRect( (MemWidth-nW)/2 + nGap, (MemHeight-nH)/2, (MemWidth+nW)/2 - nGap, (MemHeight+nH)/2); break; //只有高超出显示范围 case IMG_SIZE_HEIGHT_BEYOND: fScaleH = ((double)MemHeight)/ImgHeight; nW = fScaleH*ImgWidth; nH = MemHeight; m_RectProj = CRect( (MemWidth-nW)/2, (MemHeight-nH)/2 + nGap, (MemWidth+nW)/2, (MemHeight+nH)/2 - nGap); break; //宽高都超出显示范围 case IMG_SIZE_BOTH_BEYOND: fScaleW = ((double)MemWidth)/ImgWidth; fScaleH = ((double)MemHeight)/ImgHeight; float fScale = min(fScaleW, fScaleH); nW = fScale*ImgWidth; nH = fScale*ImgHeight; m_RectProj = CRect( (MemWidth-nW)/2 + nGap, (MemHeight-nH)/2 + nGap, (MemWidth+nW)/2 - nGap, (MemHeight+nH)/2 - nGap); break; } } void CPicSeeDlg::OnRButtonUp(UINT nFlags, CPoint point) { CPoint pt = point; ClientToScreen(&pt); //加载右键菜单 CMenu menu; menu.LoadMenu(IDR_MENU); menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, pt.x, pt.y, this); CDialogEx::OnRButtonUp(nFlags, point); } BOOL CPicSeeDlg::OnEraseBkgnd(CDC* pDC) { return TRUE; // return CDialogEx::OnEraseBkgnd(pDC); } void CPicSeeDlg::OnMouseMove(UINT nFlags, CPoint point) { //如果鼠标指针在左侧,则激活左箭头 if(point.x < 100) m_bPtInLeft = TRUE; else m_bPtInLeft = FALSE; //如果鼠标指针在右侧,则激活右箭头 if(point.x > m_RectMem.right - 100) m_bPtInRight = TRUE; else m_bPtInRight = FALSE; //如果鼠标在图像内,更改光标图案 if(m_RectProj.PtInRect(point)) { HCURSOR hCursor = (HCURSOR)AfxGetApp()->LoadStandardCursor(IDC_HAND); ::SetCursor(hCursor); //如果有鼠标左键按下,拖拽图像 if(m_bLButttonDown) { DragImage(point); } } CDialogEx::OnMouseMove(nFlags, point); } void CPicSeeDlg::DragImage(CPoint point) { //当前图像总的偏移量的累积 m_ptTotalOffSet += point-m_ptOriginal; int MemWidth = m_RectMem.Width(); int MemHeight = m_RectMem.Height(); int ProjWidth = m_RectProj.Width(); int ProjHeight = m_RectProj.Height(); //更新投影区域 m_RectProj = CRect( (MemWidth-ProjWidth)/2 + m_ptTotalOffSet.x, (MemHeight-ProjHeight)/2 + m_ptTotalOffSet.y, (MemWidth+ProjWidth)/2 + m_ptTotalOffSet.x, (MemHeight+ProjHeight)/2 + m_ptTotalOffSet.y); //更新原点 m_ptOriginal = point; } void CPicSeeDlg::Previous(void) { //如果链表为空,则没有图像文件传入 if(m_ImgPathList.IsEmpty()) { return; } m_ptTotalOffSet = 0; m_ZoomScale = 1.0; CString szFilePath; if(m_ImgPos == 1) { //如果当前图像是当前路径下的第一张图像,则显示最后一张图像 szFilePath = m_ImgPathList.GetTail(); m_ImgPos = m_ImgPathList.GetCount(); } else { //否则显示前一张图像 m_ImgPos--; szFilePath = m_ImgPathList.GetAt(m_ImgPathList.FindIndex(m_ImgPos-1)); } m_Image.Destroy(); m_Image.Load(szFilePath); UpDateProjRect(); } void CPicSeeDlg::Next(void) { //如果链表为空,则没有图像文件传入 if(m_ImgPathList.IsEmpty()) { return; } m_ptTotalOffSet = 0; m_ZoomScale = 1.0; CString szFilePath; if(m_ImgPos == m_ImgPathList.GetCount()) { //如果当前图像是当前路径下的最后一张图像,则显示第一张图像 szFilePath = m_ImgPathList.GetHead(); m_ImgPos = 1; } else { //否则显示后一张图像 szFilePath = m_ImgPathList.GetAt(m_ImgPathList.FindIndex(m_ImgPos)); m_ImgPos++; } m_Image.Destroy(); m_Image.Load(szFilePath); UpDateProjRect(); } BOOL CPicSeeDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { //如果链表为空,则没有图像文件传入 if(m_ImgPathList.IsEmpty()) { return FALSE; } //如果图像面积小于一定值且zDelta为负 //或者图像面积大于一定值且zDelta,则不放缩图像 if( ((m_RectProj.Width()*m_RectProj.Height() < 3600) && (zDelta < 0)) || ((m_RectProj.Width()*m_RectProj.Height() > 1366*768*100) && (zDelta > 0))) { m_ZoomScale = 1.0; } //否则放缩图像 else { // m_ZoomScale = pow(1.168, zDelta/120.0 + 29.655)/100.0; m_ZoomScale = 1 + 0.2*zDelta/120.0; } int ProjWidth = m_RectProj.Width(); int ProjHeight = m_RectProj.Height(); int ProjTop = m_RectProj.top; int ProjLeft = m_RectProj.left; int ProjBottom = m_RectProj.bottom; int ProjRight = m_RectProj.right; int ProjWidthNew = ProjWidth*m_ZoomScale; int ProjHeightNew = ProjHeight*m_ZoomScale; int nDiffW = (ProjWidthNew - ProjWidth)/2; int nDiffH = (ProjHeightNew - ProjHeight)/2; m_RectProj = CRect(ProjLeft - nDiffW, ProjTop - nDiffH, ProjRight + nDiffW, ProjBottom + nDiffH); return CDialogEx::OnMouseWheel(nFlags, zDelta, pt); } void CPicSeeDlg::GetDesktopRect(LPRECT lpRect) const { //查找任务栏,获取任务栏窗口句柄 HWND hWnd = ::FindWindow("Shell_TrayWnd", NULL); CRect rectTask; ::GetWindowRect(hWnd, &rectTask); *lpRect = CRect(0, 0, rectTask.right, rectTask.top); }
相关文章推荐
- ubuntu下配置java环境
- Java操作elasticsearch
- Qtcreator 修改工程名字的方法
- Problem G: C语言习题 成绩输出
- 【rapid-generator】代码生成器工具使用
- python 模拟登录
- 机器学习/数据挖掘学习资源
- JAVA-转型
- c语言学习笔记 —— 数组
- Spring笔记3
- 一个类搞懂JAVA Class文件
- python命令行自动补全
- c++第三次作业
- 树的子结构
- C++中string分割函数
- PHP练手:比赛报名系统(一)实现简单单入口
- Java并发学习之十七——线程同步工具之CountDownLatch
- VS2013MFC对话框工程学习笔记九 - C++语法的的学习
- Java设计模式系列之策略模式
- asp.net 正确的使用session