定义一个类ZoomPictureBox继承与CWnd
头文件:
#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_)
实现文件:
#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中创建该类:
在鼠标左键按下事件OnLButtonDown中添加如下代码:
程序运行结果
程序界面:
图片被选中:
图片移动:
图片放大:
图片缩小: