在做一个内存绘图后拷贝到对话框中的picture控件,再实现局部放大功能(左键增大放大倍数,右键减少放大倍数),打算是按下button2后才可以实现放大功能(有点不可能是吧—_—!!)。内存绘图与放大的过程均要用到虚似DC,为了同时实现绘图和放大,我把原来是两个程序的代码修改后合到了一起,编译没有错误,但是运行后马上出现错误提示窗口,需要终止程序,移动该提示窗口的话更是会导致整个程序错误关闭(可能是和下面所写的MouseMove事件有关),我找了很久都找不出错误的原因,我真的是水平有限,请高手们再指点指点了……不胜感激~~,好人一生平安~~
具体代码如下:
一.头文件MyDialog1.h中的声明:
public:
CMyDialog(CWnd* pParent = NULL);
protected:
//实现内存绘图的变量
CDC *pDC; //屏幕绘图设备
CDC memDC; //内存绘图设备
int m_High;
int m_Low;
int m_High2;
int m_Low2;
//以下是实现放大过程的一些变量
CSize m_sizeDest;
CSize m_sizeSource;
CBitmap *m_pBitmap;
CDC *m_pdcMem;
int oldx,oldy,s,d;//s确定被放大区域,d确定放大显示区域,放陪率=d/s
bool recover;
long mana;二.如下是MyDialog.cpp中的内容:
// MyDialog.cpp : implementation file#include "stdafx.h"
#include "aint.h"
#include "MyDialog.h"
#include <time.h>
#include <math.h>
#include <stdio.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMyDialog dialogCMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
: CDialog(CMyDialog::IDD, pParent)
{
…略
}void CMyDialog:oDataExchange(CDataExchange* pDX)
{
….略
}BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
//{{AFX_MSG_MAP(CMyDialog)
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CMyDialog message handlersvoid CMyDialog::OnButton1()
{
// TODO: Add your control notification handler code here
m_Low = 0;
m_High =120;
m_now =0;
m_High2 =5;
m_Low2 =-5;
CRect rect;
// 获取绘制坐标的文本框
CWnd* pWnd = GetDlgItem(IDC_PICTURE);
pWnd->GetClientRect(&rect);
// 指针
pDC = pWnd->GetDC();
pWnd->Invalidate();
pWnd->UpdateWindow();
//内存绘图
CBitmap memBitmap;
CBitmap* pOldBmp = NULL;
memDC.CreateCompatibleDC(pDC);
memBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
pOldBmp = memDC.SelectObject(&memBitmap);
memDC.BitBlt(rect.left,rect.top,rect.right,rect.bottom,pDC,0,0,SRCCOPY);
//自定义函数
DrawWave(&memDC);
//把内存绘图拷贝到屏幕
pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
memBitmap.DeleteObject();
pWnd->ReleaseDC(pDC);
}void CMyDialog::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CDialog::OnPaint() for painting messages
//判断是否load位图的静态标志
static bool load;
//按原来大小显示
if(!load)
{
BITMAP bm;
load=!load;
m_pBitmap->LoadBitmap(IDC_PICTURE);
m_pdcMem->CreateCompatibleDC(pDC);
m_pdcMem->SelectObject(m_pBitmap);
m_pBitmap->GetObject(sizeof(bm),&bm);
m_sizeSource.cx=bm.bmWidth;
m_sizeSource.cy=bm.bmHeight;
m_sizeDest=m_sizeSource;
pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,m_pdcMem,0,0,
m_sizeSource.cx,m_sizeSource.cy,mana);
}
else
{
pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,m_pdcMem,0,0,
m_sizeSource.cx,m_sizeSource.cy,mana);
}
}
//自定义函数的过程:
void CMyDialog:rawWave(CDC *pDC)
{
...因此自定义函数对程序影响不大,限于篇幅,此处略去
}
void CMyDialog::OnButton2()
{
// TODO: Add your control notification handler code here
//初始化变量,我想在点击BUTTON2之后才可以实现放大功能,这段代码我试了好多次,放到哪都不行,只能放在这里才不会编译错误.....虽然觉得放这里很不正确.....
m_pdcMem = new CDC;
m_pBitmap = new CBitmap;
recover = true;
s=30;d=45;
mana=SRCCOPY;
}void CMyDialog::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//计算要放大的局部矩形的源图像位置和目标位置
CString cord;
int dd;
CRect srect,drect,mrect;
srect.left=point.x-s;
srect.top=point.y-s;
srect.right=point.x+s;
srect.bottom=point.y+s;
drect.left=point.x-d;
drect.top=point.y-d;
drect.right=point.x+d;
drect.bottom=point.y+d;
mrect.left=oldx-d;
mrect.top=oldx-d;
mrect.right=oldx+d;
mrect.bottom=oldx+d;
dd=2*d;
CDC*pDC=GetDC();
//OnPrepareDC(pDC);//这个函数如果不注释掉,系统会提示"未定义",注释掉后可以运行,但不知影响大否
//放大图像
if(recover)
{
pDC->BitBlt(mrect.left,mrect.top,dd,dd,m_pdcMem,mrect.left,mrect.top,mana);
}
pDC->StretchBlt(drect.left,drect.top,drect.Width(),drect.Height(),m_pdcMem,
srect.left,srect.top,srect.Width(),srect.Height(),SRCCOPY);
oldx=point.x;oldy=point.y;
ReleaseDC(pDC);
recover=true;
CDialog::OnMouseMove(nFlags, point);
}void CMyDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//如果鼠标位置不在位图上,则还原位图大小
CRect rc(0,0,m_sizeSource.cx,m_sizeSource.cy);
if(!rc.PtInRect(point))
{
Invalidate();
}
else if(d>5)//如果放大倍数大于5,就继续送减少放大倍数,然后进行放大显示
{
CDC*pDC=GetDC();
pDC->StretchBlt(oldx-d,oldy-d,2*d,2*d,m_pdcMem,oldx-d,oldy-d,2*d,2*d,mana);
d-=10;
ReleaseDC(pDC);
CMyDialog::OnMouseMove(nFlags, point);
}
CDialog::OnLButtonDown(nFlags, point);
}void CMyDialog::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//如果鼠标位置不在位图上,则还原位图大小
CRect rc(0,0,m_sizeSource.cx,m_sizeSource.cy);
if(!rc.PtInRect(point))
{
Invalidate();
}
else if(d<150)//如果放大倍数小于150,就继续增加放大倍数,然后进行放大显示
{
// CDC*pDC=GetDC();
// pDC->StretchBlt(oldx-d,oldy-d,2*d,m_pdcMem,oldx-d,oldy-d,2*d,2*d,mana);
d+=10;
// ReleaseDC(pDC);
CMyDialog::OnMouseMove(nFlags, point);
}
CDialog::OnRButtonDown(nFlags, point);
}
具体代码如下:
一.头文件MyDialog1.h中的声明:
public:
CMyDialog(CWnd* pParent = NULL);
protected:
//实现内存绘图的变量
CDC *pDC; //屏幕绘图设备
CDC memDC; //内存绘图设备
int m_High;
int m_Low;
int m_High2;
int m_Low2;
//以下是实现放大过程的一些变量
CSize m_sizeDest;
CSize m_sizeSource;
CBitmap *m_pBitmap;
CDC *m_pdcMem;
int oldx,oldy,s,d;//s确定被放大区域,d确定放大显示区域,放陪率=d/s
bool recover;
long mana;二.如下是MyDialog.cpp中的内容:
// MyDialog.cpp : implementation file#include "stdafx.h"
#include "aint.h"
#include "MyDialog.h"
#include <time.h>
#include <math.h>
#include <stdio.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMyDialog dialogCMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
: CDialog(CMyDialog::IDD, pParent)
{
…略
}void CMyDialog:oDataExchange(CDataExchange* pDX)
{
….略
}BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
//{{AFX_MSG_MAP(CMyDialog)
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CMyDialog message handlersvoid CMyDialog::OnButton1()
{
// TODO: Add your control notification handler code here
m_Low = 0;
m_High =120;
m_now =0;
m_High2 =5;
m_Low2 =-5;
CRect rect;
// 获取绘制坐标的文本框
CWnd* pWnd = GetDlgItem(IDC_PICTURE);
pWnd->GetClientRect(&rect);
// 指针
pDC = pWnd->GetDC();
pWnd->Invalidate();
pWnd->UpdateWindow();
//内存绘图
CBitmap memBitmap;
CBitmap* pOldBmp = NULL;
memDC.CreateCompatibleDC(pDC);
memBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
pOldBmp = memDC.SelectObject(&memBitmap);
memDC.BitBlt(rect.left,rect.top,rect.right,rect.bottom,pDC,0,0,SRCCOPY);
//自定义函数
DrawWave(&memDC);
//把内存绘图拷贝到屏幕
pDC->BitBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
memBitmap.DeleteObject();
pWnd->ReleaseDC(pDC);
}void CMyDialog::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CDialog::OnPaint() for painting messages
//判断是否load位图的静态标志
static bool load;
//按原来大小显示
if(!load)
{
BITMAP bm;
load=!load;
m_pBitmap->LoadBitmap(IDC_PICTURE);
m_pdcMem->CreateCompatibleDC(pDC);
m_pdcMem->SelectObject(m_pBitmap);
m_pBitmap->GetObject(sizeof(bm),&bm);
m_sizeSource.cx=bm.bmWidth;
m_sizeSource.cy=bm.bmHeight;
m_sizeDest=m_sizeSource;
pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,m_pdcMem,0,0,
m_sizeSource.cx,m_sizeSource.cy,mana);
}
else
{
pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,m_pdcMem,0,0,
m_sizeSource.cx,m_sizeSource.cy,mana);
}
}
//自定义函数的过程:
void CMyDialog:rawWave(CDC *pDC)
{
...因此自定义函数对程序影响不大,限于篇幅,此处略去
}
void CMyDialog::OnButton2()
{
// TODO: Add your control notification handler code here
//初始化变量,我想在点击BUTTON2之后才可以实现放大功能,这段代码我试了好多次,放到哪都不行,只能放在这里才不会编译错误.....虽然觉得放这里很不正确.....
m_pdcMem = new CDC;
m_pBitmap = new CBitmap;
recover = true;
s=30;d=45;
mana=SRCCOPY;
}void CMyDialog::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//计算要放大的局部矩形的源图像位置和目标位置
CString cord;
int dd;
CRect srect,drect,mrect;
srect.left=point.x-s;
srect.top=point.y-s;
srect.right=point.x+s;
srect.bottom=point.y+s;
drect.left=point.x-d;
drect.top=point.y-d;
drect.right=point.x+d;
drect.bottom=point.y+d;
mrect.left=oldx-d;
mrect.top=oldx-d;
mrect.right=oldx+d;
mrect.bottom=oldx+d;
dd=2*d;
CDC*pDC=GetDC();
//OnPrepareDC(pDC);//这个函数如果不注释掉,系统会提示"未定义",注释掉后可以运行,但不知影响大否
//放大图像
if(recover)
{
pDC->BitBlt(mrect.left,mrect.top,dd,dd,m_pdcMem,mrect.left,mrect.top,mana);
}
pDC->StretchBlt(drect.left,drect.top,drect.Width(),drect.Height(),m_pdcMem,
srect.left,srect.top,srect.Width(),srect.Height(),SRCCOPY);
oldx=point.x;oldy=point.y;
ReleaseDC(pDC);
recover=true;
CDialog::OnMouseMove(nFlags, point);
}void CMyDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//如果鼠标位置不在位图上,则还原位图大小
CRect rc(0,0,m_sizeSource.cx,m_sizeSource.cy);
if(!rc.PtInRect(point))
{
Invalidate();
}
else if(d>5)//如果放大倍数大于5,就继续送减少放大倍数,然后进行放大显示
{
CDC*pDC=GetDC();
pDC->StretchBlt(oldx-d,oldy-d,2*d,2*d,m_pdcMem,oldx-d,oldy-d,2*d,2*d,mana);
d-=10;
ReleaseDC(pDC);
CMyDialog::OnMouseMove(nFlags, point);
}
CDialog::OnLButtonDown(nFlags, point);
}void CMyDialog::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//如果鼠标位置不在位图上,则还原位图大小
CRect rc(0,0,m_sizeSource.cx,m_sizeSource.cy);
if(!rc.PtInRect(point))
{
Invalidate();
}
else if(d<150)//如果放大倍数小于150,就继续增加放大倍数,然后进行放大显示
{
// CDC*pDC=GetDC();
// pDC->StretchBlt(oldx-d,oldy-d,2*d,m_pdcMem,oldx-d,oldy-d,2*d,2*d,mana);
d+=10;
// ReleaseDC(pDC);
CMyDialog::OnMouseMove(nFlags, point);
}
CDialog::OnRButtonDown(nFlags, point);
}
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货