实现可拖动大小,移动位置的PictureBox

定义一个类ZoomPictureBox继承与CWnd

头文件:

#if !defined(AFX_ZOOMPICTUREBOX_H__6E8C1D9D_65A8_42B2_915A_BCA43E728784__INCLUDED_) #define AFX_ZOOMPICTUREBOX_H__6E8C1D9D_65A8_42B2_915A_BCA43E728784__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // ZoomPictureBox.h : header file // ///////////////////////////////////////////////////////////////////////////// // ZoomPictureBox window class ZoomPictureBox : public CWnd { // Construction public: ZoomPictureBox(); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(ZoomPictureBox) public: virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL); //}}AFX_VIRTUAL // Implementation public: void DrawBitmap(CDC* pDC); void LoadBitmap(CString path);//从文件加载位图 virtual ~ZoomPictureBox(); // Generated message map functions protected: //{{AFX_MSG(ZoomPictureBox) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct); afx_msg void OnPaint(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); //}}AFX_MSG DECLARE_MESSAGE_MAP() public: void SetPictureSelected(BOOL isSelected); void DrawMark(CDC *pDC); void SetBorderWidth(int width); void DrawBackGround(CDC* pDC); void SetCursorStyle(CPoint& point); void Create(CWnd* pParentWnd,const RECT& rect); CWnd* pParentWnd;//保存父窗口指针 CRect parentRect;//父窗口客户区域 HBITMAP hBitmap;//位图句柄 CBitmap *pBitmap;//位图指针 BITMAPINFOHEADER bminfo;//图像信息头 CRect clientRect;//客户区域 CRect backRect;//背景区域 CRect picRect;//图片区域 int borderWidth;//边框宽度 CSize markSize;//标记大小 CDC MemDC;//存放位图的内存环境变量 CRect rectLeftTop;//左上区域 CRect rectLeftCenter;//左中区域 CRect rectLeftBottom;//左下区域 CRect rectTopCenter;//上中区域 CRect rectBottomCenter;//下中区域 CRect rectRightTop;//右上区域 CRect rectRightCenter;//右中区域 CRect rectRightBottom;//右下区域 BOOL isPicSelected;//图片是否被选中 CPoint oldPoint;//原始坐标 int width;//宽 int height;//高 }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_ZOOMPICTUREBOX_H__6E8C1D9D_65A8_42B2_915A_BCA43E728784__INCLUDED_)

实现文件:

// ZoomPictureBox.cpp : implementation file // #include "stdafx.h" #include "ZoomPicture.h" #include "ZoomPictureBox.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // ZoomPictureBox ZoomPictureBox::ZoomPictureBox() { hBitmap = NULL;//初始化位图句柄为NULL borderWidth = 1;//默认边框宽度为1 isPicSelected = FALSE;//初始化图片选中状态 //初始化标记大小 markSize.cx = 8; markSize.cy = 8; } ZoomPictureBox::~ZoomPictureBox() { } BEGIN_MESSAGE_MAP(ZoomPictureBox, CWnd) //{{AFX_MSG_MAP(ZoomPictureBox) ON_WM_CREATE() ON_WM_LBUTTONDOWN() ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_DRAWITEM() ON_WM_PAINT() ON_WM_ERASEBKGND() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // ZoomPictureBox message handlers int ZoomPictureBox::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; GetClientRect(&clientRect);//获得客户区域 width = clientRect.right; height = clientRect.bottom; return 0; } BOOL ZoomPictureBox::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) { return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext); } //从文件加载位图 void ZoomPictureBox::LoadBitmap(CString path) { hBitmap= (HBITMAP)::LoadImage(AfxGetInstanceHandle(),path,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE); pBitmap = CBitmap::FromHandle(hBitmap);//从句柄加载位图 pBitmap->GetObject(sizeof(bminfo),&bminfo);//获得位图信息头 } //画位图 void ZoomPictureBox::DrawBitmap(CDC *pDC) { //设置图片区域 picRect.left = clientRect.left + borderWidth+markSize.cx/2; picRect.top = clientRect.top + borderWidth+markSize.cy/2; picRect.right = clientRect.right - 2*borderWidth-markSize.cx; picRect.bottom = clientRect.bottom - 2*borderWidth-markSize.cy; MemDC.CreateCompatibleDC(pDC);//创建一个兼容的内存环境 CBitmap* pOldBitmap = MemDC.SelectObject(pBitmap);//将位图选入内存中 pDC->SetStretchBltMode(COLORONCOLOR);//设置拉伸模式,COLORONCOLOR:删除像素。该模式删除所有消除的像素行,不保留其信息。 pDC->StretchBlt(picRect.left,picRect.top,picRect.right,picRect.bottom,&MemDC,0,0,bminfo.biWidth,bminfo.biHeight,SRCCOPY);//绘制位图 MemDC.SelectObject(pOldBitmap); MemDC.DeleteDC(); } //创建图片框 void ZoomPictureBox::Create(CWnd *pParentWnd, const RECT &rect) { this->pParentWnd = pParentWnd; parentRect = rect; this->Create(NULL,NULL,WS_CHILD|WS_VISIBLE,rect,pParentWnd,NULL); } //鼠标按下 void ZoomPictureBox::OnLButtonDown(UINT nFlags, CPoint point) { ::SendMessage(pParentWnd->GetSafeHwnd(),WM_LBUTTONDOWN,0,0); // TODO: Add your message handler code here and/or call default if(clientRect.PtInRect(point))//在图片区域选中 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));//改变光标样式 isPicSelected = TRUE; Invalidate(); } if(isPicSelected) { SetCursorStyle(point);//设置鼠标样式 ClientToScreen(&point);//转换为屏幕坐标 oldPoint = point; } CString msg; msg.Format("x=%d,y=%d",point.x,point.y); pParentWnd->SetWindowText(msg); CWnd::OnLButtonDown(nFlags,point); } /* nFlags    指示各种虚拟按键是否按下 ,此参数可以是任何下列值的组合:   MK_CONTROL 当CTRL键按下时。    MK_LBUTTON 当鼠标左键按下时。 MK_MBUTTON 当鼠标中键按下时。 MK_RBUTTON 当鼠标右键按下时。    MK_SHIFT 当SHIFT按下时。 */ //鼠标移动 void ZoomPictureBox::OnMouseMove(UINT nFlags, CPoint point) { if(isPicSelected) { SetCursorStyle(point);//设置鼠标样式 if(nFlags==MK_LBUTTON) { if(rectLeftTop.PtInRect(point))//左上角 { ClientToScreen(&point);//转换为屏幕坐标 long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; parentRect.left+=dx; parentRect.top+=dy; width-=dx; height-=dy; clientRect.right-=dx; clientRect.bottom-=dy; this->MoveWindow(parentRect.left,parentRect.top,width,height); oldPoint = point; return; } if(rectRightTop.PtInRect(point))//右上角 { ClientToScreen(&point);//转换为屏幕坐标 long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; parentRect.top+=dy; width+=dx; height-=dy; clientRect.right+=dx; clientRect.bottom-=dy; this->MoveWindow(parentRect.left,parentRect.top,width,height); oldPoint = point; return; } if(rectLeftBottom.PtInRect(point))//左下角 { ClientToScreen(&point);//转换为屏幕坐标 long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; parentRect.left+=dx; width-=dx; height+=dy; clientRect.right-=dx; clientRect.bottom+=dy; this->MoveWindow(parentRect.left,parentRect.top,width,height); oldPoint = point; return; } if(rectRightBottom.PtInRect(point))//右下角 { ClientToScreen(&point);//转换为屏幕坐标 long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; width+=dx; height+=dy; clientRect.right+=dx; clientRect.bottom+=dy; this->MoveWindow(parentRect.left,parentRect.top,width,height); oldPoint = point; return; } if(rectLeftCenter.PtInRect(point))//左边框 { ClientToScreen(&point);//转换为屏幕坐标 long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; parentRect.left+=dx; width-=dx; clientRect.right-=dx; this->MoveWindow(parentRect.left,parentRect.top,width,height); oldPoint = point; return; } if(rectRightCenter.PtInRect(point))//右边框 { ClientToScreen(&point);//转换为屏幕坐标 long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; width+=dx; clientRect.right+=dx; this->MoveWindow(parentRect.left,parentRect.top,width,height); oldPoint = point; return; } if(rectTopCenter.PtInRect(point))//上边框 { ClientToScreen(&point);//转换为屏幕坐标 long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; parentRect.top+=dy; height-=dy; clientRect.bottom-=dy; this->MoveWindow(parentRect.left,parentRect.top,width,height); oldPoint = point; return; } if(rectBottomCenter.PtInRect(point))//下边框 { ClientToScreen(&point);//转换为屏幕坐标 long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; height+=dy; clientRect.bottom+=dy; this->MoveWindow(parentRect.left,parentRect.top,width,height); oldPoint = point; return; } CRect rect; rect.left = clientRect.left+markSize.cx; rect.top = clientRect.top+markSize.cy; rect.right = clientRect.right-2*markSize.cx; rect.bottom = clientRect.bottom-2*markSize.cy; if(rect.PtInRect(point)) { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEALL));//改变光标样式 ClientToScreen(&point);//转换为屏幕坐标 CString msg; msg.Format("x=%d,y=%d",point.x,point.y); pParentWnd->SetWindowText(msg); long dx = point.x - oldPoint.x; long dy = point.y - oldPoint.y; parentRect.left+=dx; parentRect.top+=dy; parentRect.right = clientRect.right; parentRect.bottom = clientRect.bottom; this->MoveWindow(parentRect.left,parentRect.top,parentRect.right,parentRect.bottom); oldPoint = point; } } } CWnd::OnMouseMove(nFlags, point); } //鼠标弹起 void ZoomPictureBox::OnLButtonUp(UINT nFlags, CPoint point) { if(isPicSelected) { SetCursorStyle(point);//设置鼠标样式 } CWnd::OnLButtonUp(nFlags, point); } //鼠标双击 void ZoomPictureBox::OnLButtonDblClk(UINT nFlags, CPoint point) { OnLButtonDown(nFlags,point);//双击当做单击事件处理 CWnd::OnLButtonDblClk(nFlags, point); } //设置鼠标样式 void ZoomPictureBox::SetCursorStyle(CPoint &point) { if(rectLeftTop.PtInRect(point))//左上角 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENWSE)); return; } if(rectRightTop.PtInRect(point))//右上角 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENESW)); return; } if(rectLeftBottom.PtInRect(point))//左下角 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENESW)); return; } if(rectRightBottom.PtInRect(point))//右下角 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENWSE)); return; } if(rectLeftCenter.PtInRect(point))//左边框 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE)); return; } if(rectRightCenter.PtInRect(point))//右边框 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZEWE)); return; } if(rectTopCenter.PtInRect(point))//上边框 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS)); return; } if(rectBottomCenter.PtInRect(point))//下边框 { SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS)); return; } } void ZoomPictureBox::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) { CWnd::OnDrawItem(nIDCtl, lpDrawItemStruct); } //重绘方法 void ZoomPictureBox::OnPaint() { CPaintDC dc(this); //dc.SetBkMode(TRANSPARENT); DrawBackGround(&dc);//绘制背景 if(hBitmap!=NULL)//位图句柄不为空,则绘制位图 { DrawBitmap(&dc); if(isPicSelected) { DrawMark(&dc); } } } BOOL ZoomPictureBox::OnEraseBkgnd(CDC* pDC) { return TRUE; //return CWnd::OnEraseBkgnd(pDC); } //画背景 void ZoomPictureBox::DrawBackGround(CDC *pDC) { CBrush br(RGB(0,0,0));//创建画刷 CRect rect; rect.left=clientRect.left+markSize.cx/2; rect.top=clientRect.top+markSize.cy/2; rect.right=clientRect.right-markSize.cx/2; rect.bottom=clientRect.bottom-markSize.cy/2; backRect = rect; pDC->FillRect(&backRect,&br);//填充客户区域 } //设置边框宽度 void ZoomPictureBox::SetBorderWidth(int width) { borderWidth = width;//边框宽度 } //画标记 void ZoomPictureBox::DrawMark(CDC *pDC) { CBrush br(RGB(0,0,0)); pDC->SelectObject(&br); rectLeftTop=CRect(clientRect.left,clientRect.top,clientRect.left+markSize.cx,clientRect.top+markSize.cy); rectLeftCenter=CRect(clientRect.left,clientRect.bottom/2-markSize.cy/2,clientRect.left+markSize.cx,clientRect.bottom/2+markSize.cy/2); rectLeftBottom=CRect(clientRect.left,clientRect.bottom-markSize.cy,clientRect.left+markSize.cx,clientRect.bottom); rectTopCenter=CRect(clientRect.right/2-markSize.cx/2,clientRect.top,clientRect.right/2+markSize.cx/2,clientRect.top+markSize.cy); rectBottomCenter=CRect(clientRect.right/2-markSize.cx/2,clientRect.bottom-markSize.cy,clientRect.right/2+markSize.cx/2,clientRect.bottom+markSize.cy); rectRightTop=CRect(clientRect.right-markSize.cx,clientRect.top,clientRect.right,clientRect.top+markSize.cy); rectRightCenter=CRect(clientRect.right-markSize.cx,clientRect.bottom/2-markSize.cy/2,clientRect.right,clientRect.bottom/2+markSize.cy/2); rectRightBottom=CRect(clientRect.right-markSize.cx,clientRect.bottom-markSize.cy,clientRect.right,clientRect.bottom); pDC->Rectangle(rectLeftTop);//左上 pDC->Rectangle(rectLeftCenter);//左中 pDC->Rectangle(rectLeftBottom);//左下 pDC->Rectangle(rectTopCenter);//上中 pDC->Rectangle(rectBottomCenter);//下中 pDC->Rectangle(rectRightTop);//右上 pDC->Rectangle(rectRightCenter);//右中 pDC->Rectangle(rectRightBottom);//右下 } //设置图片是否被选中 void ZoomPictureBox::SetPictureSelected(BOOL isSelected) { isPicSelected = isSelected; }

在对话框中使用

在对话框初始化方法OnInitDialog中创建该类:

zoomPictureBox.Create(this,CRect(0,0,300,400)); zoomPictureBox.LoadBitmap("E://VC6WorkSpace//ZoomPicture//1.bmp");

在鼠标左键按下事件OnLButtonDown中添加如下代码:

zoomPictureBox.SetPictureSelected(FALSE); Invalidate();

程序运行结果

 

程序界面:

实现可拖动大小,移动位置的PictureBox_第1张图片

图片被选中:

实现可拖动大小,移动位置的PictureBox_第2张图片

图片移动:

图片放大:

图片缩小:

实现可拖动大小,移动位置的PictureBox_第3张图片

你可能感兴趣的:(实现可拖动大小,移动位置的PictureBox)