在对话框上应用带缩放功能的CScrollView
一.定义cscrollview派生类和document派生类
声明:
DlgView.h:
//----------------------------------------------------------------------------------
class CCraftCxPreviewDlg;
class CDlgDocument : public CDocument
{
friend class CCraftCxPreviewDlg;
protected:
CDlgDocument(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CDlgDocument)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgDocument)
public:
virtual void Serialize(CArchive& ar); // overridden for document i/o
protected:
virtual BOOL OnNewDocument();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDlgDocument();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
//{{AFX_MSG(CDlgDocument)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
class CCraftCxPreviewDlg;
/////////////////////////////////////////////////////////////////////////////
// CDlgView view
class CDlgView : public CScrollView
{
friend class CCraftCxPreviewDlg;
protected:
CDlgView(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CDlgView)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgView)
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnInitialUpdate(); // first time after construct
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CDlgView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
//{{AFX_MSG(CDlgView)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
afx_msg void OnDestroy();
void OnZoomIn();
void OnZoomOut();
protected:
virtual void PostNcDestroy();
private:
void InitDC(CDC *pDC);
float m_zoomScale;
CSize m_size;
};
定义:
DlgView.cpp:
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgDocument
IMPLEMENT_DYNCREATE(CDlgDocument, CDocument)
CDlgDocument::CDlgDocument()
{
}
BOOL CDlgDocument::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
return TRUE;
}
CDlgDocument::~CDlgDocument()
{
}
BEGIN_MESSAGE_MAP(CDlgDocument, CDocument)
//{{AFX_MSG_MAP(CDlgDocument)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgDocument diagnostics
#ifdef _DEBUG
void CDlgDocument::AssertValid() const
{
CDocument::AssertValid();
}
void CDlgDocument::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDlgDocument serialization
void CDlgDocument::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CDlgView
IMPLEMENT_DYNCREATE(CDlgView, CScrollView)
CDlgView::CDlgView()
{
m_zoomScale = 1.0;
m_dbHorzScale = 1.0;
m_dbVertScale = 1.0;
}
CDlgView::~CDlgView()
{
}
BEGIN_MESSAGE_MAP(CDlgView, CScrollView)
//{{AFX_MSG_MAP(CDlgView)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_WM_MOUSEACTIVATE()
ON_WM_DESTROY()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgView drawing
void CDlgView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
sizeTotal.cx = sizeTotal.cy = 30;
SetScrollSizes(MM_TEXT, sizeTotal);
m_size =sizeTotal;//成员变量m_size保存视图的原始大小
}
void CDlgView::SetPreBitmap(Bitmap *PreBitmap, double dbVert, double dbHorz)
{
m_Bitmap = PreBitmap;
m_dbHorzScale = (dbVert > dbHorz) ? dbVert / dbHorz: 1;
m_dbVertScale = (dbVert > dbHorz) ? 1 : dbHorz / dbVert;
}
void CDlgView::OnDraw(CDC* pDC)
{
InitDC(pDC);//设置pDC为新的模式
int nHeight = m_Bitmap->GetHeight();
int nWidth = m_Bitmap->GetWidth();
// 放大位图
CDC dc;
dc.CreateCompatibleDC(pDC);
CBitmap bitmap;
CBitmap* pOldBitmap;
bitmap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
pOldBitmap = dc.SelectObject(&bitmap);
Graphics g(dc.m_hDC);
g.DrawImage(m_Bitmap, 0, 0);
nWidth *= m_dbHorzScale;
nHeight *= m_dbVertScale;
pDC->StretchBlt(0, 0, nWidth, nHeight, &dc, 0, 0, nWidth, nHeight, SRCCOPY);
dc.SelectObject(pOldBitmap);
CRect m_Rect;
GetClientRect(&m_Rect);
m_Rect.bottom += 100;
CSize sizeTotal;
sizeTotal.cx = nWidth * m_zoomScale;
sizeTotal.cy = nHeight * m_zoomScale;
SetScrollSizes(MM_TEXT, sizeTotal);
}
int CDlgView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
}
/////////////////////////////////////////////////////////////////////////////
// CDlgView diagnostics
#ifdef _DEBUG
void CDlgView::AssertValid() const
{
CScrollView::AssertValid();
}
void CDlgView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDlgView message handlers
//////////////////////////////////////////////////////////////////////////
void CDlgView::OnDestroy()
{
CWnd::OnDestroy();
}
void CDlgView::PostNcDestroy()
{
CWnd::PostNcDestroy();
}
void CDlgView::OnZoomIn()
{
if (m_zoomScale > 31)
return;
CSize size = m_size;
m_zoomScale++;//成员变量float m_zoom ;放大倍率加1
size.cx *= m_zoomScale;
size.cy *= m_zoomScale;
size.cx += 2;
size.cy += 2;//可能是计算误差的原因总是看不到最后几个象素
this->SetScrollSizes(MM_TEXT, size); //设置放大后视图的大小
this->Invalidate();//重画视图
}//一个菜单事件进行缩放倍率设置
void CDlgView::OnZoomOut()
{
if (m_zoomScale == 1)
return;
CSize size = m_size;
m_zoomScale--;//成员变量float m_zoom ;放大倍率加1
size.cx *= m_zoomScale;
size.cy *= m_zoomScale;
size.cx += 2;
size.cy += 2;//可能是计算误差的原因总是看不到最后几个象素
this->SetScrollSizes(MM_TEXT, size); //设置放大后视图的大小
this->Invalidate();//重画视图
}//一个菜单事件进行缩放倍率设置
void CDlgView::InitDC(CDC *pDC)
{
CSize size(1000,1000);//定义原始图的大小,可以自己随意定
//但不能太小,数字越大放大的精度就越高
//举个例子,若数字为1,放大1.5倍,int(1*1.5)=1 等于没放大
CSize newSize(1000 * m_zoomScale, 1000 * m_zoomScale);//放大后的图大小
OnPrepareDC(pDC);//pDC设置为绑定逻辑视图
CPoint point(0,0);//逻辑视图的0点
pDC->LPtoDP(&point); //转化为设备坐标因为SetViewportOrg的参数需要设备坐标
pDC->SetMapMode(MM_ANISOTROPIC);// 设置为单位可变模式
pDC->SetViewportOrg(point);//视口原点为逻辑视图原点
pDC->SetViewportExt(newSize); //原窗口1000单位 对应到缩放后的单位
pDC->SetWindowOrg(0,0);
pDC->SetWindowExt(size);//
}//对画图dc进行设置
二.调用
BOOL CCraftCxPreviewDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CWnd *pWnd = this->GetDlgItem(IDC_STATIC_PRE_BMP);
CRect RectTargetCtrl;
pWnd->GetWindowRect(RectTargetCtrl);
pWnd->DestroyWindow();
this->ScreenToClient(RectTargetCtrl);
CCreateContext pContext;
CWnd* pFrameWnd = this;
pContext.m_pCurrentDoc = new CDlgDocument;
pContext.m_pNewViewClass = RUNTIME_CLASS(CDlgView);
m_pZoomView =(CDlgView *) ((CFrameWnd*)pFrameWnd)->CreateView(&pContext);
ASSERT(m_pZoomView);
m_pZoomView->m_nMapMode = MM_TEXT;
m_pZoomView->OnInitialUpdate();
m_pZoomView->SetPreBitmap(m_pPreBitmap, m_dbDensityVert, m_dbDensityHorz);
m_pZoomView->ShowWindow(SW_NORMAL);
m_pZoomView->MoveWindow(RectTargetCtrl);
return TRUE;
}
void CCraftCxPreviewDlg::OnBnClickedButtonZoomout()
{
m_pZoomView->OnZoomOut();
}
void CCraftCxPreviewDlg::OnBnClickedButtonZoomin()
{
m_pZoomView->OnZoomIn();
}
声明:
DlgView.h:
//----------------------------------------------------------------------------------
class CCraftCxPreviewDlg;
class CDlgDocument : public CDocument
{
friend class CCraftCxPreviewDlg;
protected:
CDlgDocument(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CDlgDocument)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgDocument)
public:
virtual void Serialize(CArchive& ar); // overridden for document i/o
protected:
virtual BOOL OnNewDocument();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CDlgDocument();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
protected:
//{{AFX_MSG(CDlgDocument)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
class CCraftCxPreviewDlg;
/////////////////////////////////////////////////////////////////////////////
// CDlgView view
class CDlgView : public CScrollView
{
friend class CCraftCxPreviewDlg;
protected:
CDlgView(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CDlgView)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgView)
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual void OnInitialUpdate(); // first time after construct
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CDlgView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
// Generated message map functions
//{{AFX_MSG(CDlgView)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
afx_msg void OnDestroy();
void OnZoomIn();
void OnZoomOut();
protected:
virtual void PostNcDestroy();
private:
void InitDC(CDC *pDC);
float m_zoomScale;
CSize m_size;
};
定义:
DlgView.cpp:
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgDocument
IMPLEMENT_DYNCREATE(CDlgDocument, CDocument)
CDlgDocument::CDlgDocument()
{
}
BOOL CDlgDocument::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
return TRUE;
}
CDlgDocument::~CDlgDocument()
{
}
BEGIN_MESSAGE_MAP(CDlgDocument, CDocument)
//{{AFX_MSG_MAP(CDlgDocument)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgDocument diagnostics
#ifdef _DEBUG
void CDlgDocument::AssertValid() const
{
CDocument::AssertValid();
}
void CDlgDocument::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDlgDocument serialization
void CDlgDocument::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CDlgView
IMPLEMENT_DYNCREATE(CDlgView, CScrollView)
CDlgView::CDlgView()
{
m_zoomScale = 1.0;
m_dbHorzScale = 1.0;
m_dbVertScale = 1.0;
}
CDlgView::~CDlgView()
{
}
BEGIN_MESSAGE_MAP(CDlgView, CScrollView)
//{{AFX_MSG_MAP(CDlgView)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_WM_MOUSEACTIVATE()
ON_WM_DESTROY()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgView drawing
void CDlgView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
sizeTotal.cx = sizeTotal.cy = 30;
SetScrollSizes(MM_TEXT, sizeTotal);
m_size =sizeTotal;//成员变量m_size保存视图的原始大小
}
void CDlgView::SetPreBitmap(Bitmap *PreBitmap, double dbVert, double dbHorz)
{
m_Bitmap = PreBitmap;
m_dbHorzScale = (dbVert > dbHorz) ? dbVert / dbHorz: 1;
m_dbVertScale = (dbVert > dbHorz) ? 1 : dbHorz / dbVert;
}
void CDlgView::OnDraw(CDC* pDC)
{
InitDC(pDC);//设置pDC为新的模式
int nHeight = m_Bitmap->GetHeight();
int nWidth = m_Bitmap->GetWidth();
// 放大位图
CDC dc;
dc.CreateCompatibleDC(pDC);
CBitmap bitmap;
CBitmap* pOldBitmap;
bitmap.CreateCompatibleBitmap(pDC, nWidth, nHeight);
pOldBitmap = dc.SelectObject(&bitmap);
Graphics g(dc.m_hDC);
g.DrawImage(m_Bitmap, 0, 0);
nWidth *= m_dbHorzScale;
nHeight *= m_dbVertScale;
pDC->StretchBlt(0, 0, nWidth, nHeight, &dc, 0, 0, nWidth, nHeight, SRCCOPY);
dc.SelectObject(pOldBitmap);
CRect m_Rect;
GetClientRect(&m_Rect);
m_Rect.bottom += 100;
CSize sizeTotal;
sizeTotal.cx = nWidth * m_zoomScale;
sizeTotal.cy = nHeight * m_zoomScale;
SetScrollSizes(MM_TEXT, sizeTotal);
}
int CDlgView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
}
/////////////////////////////////////////////////////////////////////////////
// CDlgView diagnostics
#ifdef _DEBUG
void CDlgView::AssertValid() const
{
CScrollView::AssertValid();
}
void CDlgView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDlgView message handlers
//////////////////////////////////////////////////////////////////////////
void CDlgView::OnDestroy()
{
CWnd::OnDestroy();
}
void CDlgView::PostNcDestroy()
{
CWnd::PostNcDestroy();
}
void CDlgView::OnZoomIn()
{
if (m_zoomScale > 31)
return;
CSize size = m_size;
m_zoomScale++;//成员变量float m_zoom ;放大倍率加1
size.cx *= m_zoomScale;
size.cy *= m_zoomScale;
size.cx += 2;
size.cy += 2;//可能是计算误差的原因总是看不到最后几个象素
this->SetScrollSizes(MM_TEXT, size); //设置放大后视图的大小
this->Invalidate();//重画视图
}//一个菜单事件进行缩放倍率设置
void CDlgView::OnZoomOut()
{
if (m_zoomScale == 1)
return;
CSize size = m_size;
m_zoomScale--;//成员变量float m_zoom ;放大倍率加1
size.cx *= m_zoomScale;
size.cy *= m_zoomScale;
size.cx += 2;
size.cy += 2;//可能是计算误差的原因总是看不到最后几个象素
this->SetScrollSizes(MM_TEXT, size); //设置放大后视图的大小
this->Invalidate();//重画视图
}//一个菜单事件进行缩放倍率设置
void CDlgView::InitDC(CDC *pDC)
{
CSize size(1000,1000);//定义原始图的大小,可以自己随意定
//但不能太小,数字越大放大的精度就越高
//举个例子,若数字为1,放大1.5倍,int(1*1.5)=1 等于没放大
CSize newSize(1000 * m_zoomScale, 1000 * m_zoomScale);//放大后的图大小
OnPrepareDC(pDC);//pDC设置为绑定逻辑视图
CPoint point(0,0);//逻辑视图的0点
pDC->LPtoDP(&point); //转化为设备坐标因为SetViewportOrg的参数需要设备坐标
pDC->SetMapMode(MM_ANISOTROPIC);// 设置为单位可变模式
pDC->SetViewportOrg(point);//视口原点为逻辑视图原点
pDC->SetViewportExt(newSize); //原窗口1000单位 对应到缩放后的单位
pDC->SetWindowOrg(0,0);
pDC->SetWindowExt(size);//
}//对画图dc进行设置
二.调用
BOOL CCraftCxPreviewDlg::OnInitDialog()
{
CDialog::OnInitDialog();
CWnd *pWnd = this->GetDlgItem(IDC_STATIC_PRE_BMP);
CRect RectTargetCtrl;
pWnd->GetWindowRect(RectTargetCtrl);
pWnd->DestroyWindow();
this->ScreenToClient(RectTargetCtrl);
CCreateContext pContext;
CWnd* pFrameWnd = this;
pContext.m_pCurrentDoc = new CDlgDocument;
pContext.m_pNewViewClass = RUNTIME_CLASS(CDlgView);
m_pZoomView =(CDlgView *) ((CFrameWnd*)pFrameWnd)->CreateView(&pContext);
ASSERT(m_pZoomView);
m_pZoomView->m_nMapMode = MM_TEXT;
m_pZoomView->OnInitialUpdate();
m_pZoomView->SetPreBitmap(m_pPreBitmap, m_dbDensityVert, m_dbDensityHorz);
m_pZoomView->ShowWindow(SW_NORMAL);
m_pZoomView->MoveWindow(RectTargetCtrl);
return TRUE;
}
void CCraftCxPreviewDlg::OnBnClickedButtonZoomout()
{
m_pZoomView->OnZoomOut();
}
void CCraftCxPreviewDlg::OnBnClickedButtonZoomin()
{
m_pZoomView->OnZoomIn();
}