首先是一个对话框程序,没有view类ondraw
有onpaint主对话框上一个picture控件,ID名为picture1主对话框上有一个按钮,叫打开图片,ID为IDB_OPEN,单击事件是打开图片到....加载图片,最后InvalidateRect(&ClearRect,TRUE);onpaint事件里面是这么写的 CPaintDC dc(this);
CPaintDC pdc(GetDlgItem(IDC_Picture1));//定义容器
ShowRect.left=0-HS_Value;//水平
ShowRect.top=0-VS_Value;//垂直
ShowRect.right=w-HS_Value;//水平
ShowRect.bottom =h-VS_Value;//垂直一定要全部,否则缩放
image->Draw(pdc,ShowRect,&ClipRect);//Cximage *image;
ReleaseDC(&pdc);主对话框上还有一个按钮,叫手动画线,IDB_handDarw提问:程序要求在open图像后,picture1容器中存在一幅位图时,单击[手动画线]按钮后,
鼠标移动到picture1中的图片上,在位图上单击鼠标用鼠标拖拉一根直线,“不闪烁”?这样的操作我其实会写,在movedown mousemove onpaint 事件分别写代码,记录point,不停paint,但是画线很闪烁
我的思路被放弃我查了网上的资料,有一个技术叫双缓冲,还是改进的三缓冲但是线画到picture1控件下面去了,也就是在对话框上,怎么画到picture1容器中贴代码//.h
CBitmap memBakBMP; //新缓冲区内存DC
CDC memBakDC; //新缓冲区用的位图
BOOL bClicked; //判断是否应当作图
CPoint ptBegin; //记录图象开始的位置
CBitmap memBMP; //新缓冲区用的位图
CDC memDC; //旧缓冲区内存DC//创建时
int CBSYDDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
memDC.CreateCompatibleDC(NULL);
memBMP.CreateCompatibleBitmap(&memDC,1024,768);
memDC.SelectObject(&memBMP);
memDC.FillSolidRect(0,0,1024,768,GetDC()->GetBkColor());
memBakDC.CreateCompatibleDC(NULL);
memBakBMP.CreateCompatibleBitmap(&memBakDC,1024,768);
memBakDC.SelectObject(&memBakBMP);
return 0;
}void CBSYDDlg::handDarw()
{
m_measure=1;//标志为1,代表手动画线
}void CBSYDDlg::OnMouseMove(UINT nFlags, CPoint point)
{if(m_measure==1);//标志为1,代表手动画线{
CRect rect;
GetClientRect(&rect);
memBakDC.BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
memDC.BitBlt(0,0,rect.Width(),rect.Height(),&memBakDC,0,0,SRCCOPY);
memDC.MoveTo(100,100);//假设起点在100,100位置处,现在是测试,不考虑第一个点
memDC.LineTo(point);
Invalidate(false);
}
}
void CBSYDDlg::OnPaint()
{
CPaintDC dc(this);
if(m_measure==1)//;//标志为1,代表手动画线
{
CDC* pdc1 = GetDC();
CRect rect;
GetClientRect(&rect);
pdc1->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
ReleaseDC(pdc1);
} if(m_measure!=1)//不是画线
{
CPaintDC pdc(GetDlgItem(IDC_Picture1));//定义容器
ShowRect.left=0-HS_Value;//水平
ShowRect.top=0-VS_Value;//垂直
ShowRect.right=w-HS_Value;//水平
ShowRect.bottom =h-VS_Value;//垂直一定要全部,否则缩放
image->Draw(pdc,ShowRect,&ClipRect);
ReleaseDC(&pdc);
}
}现在这个代码是一团糟,打开图片后正常,一但点击"手动测量"按钮
开始画线了,原来的图片框不见了,移动鼠标直接在窗体画很多线,原来的线也不擦除,彻底无语:-(我想达到的功能是,点击"手动测量"按钮
在picture1中的图片上实时画一条直线条,不擦除背景,用鼠标移动动态画一条直线
就好比windows画图一样,你在打开的图片上画一条直线奉献所有可用分求解!!不胜感谢
有onpaint主对话框上一个picture控件,ID名为picture1主对话框上有一个按钮,叫打开图片,ID为IDB_OPEN,单击事件是打开图片到....加载图片,最后InvalidateRect(&ClearRect,TRUE);onpaint事件里面是这么写的 CPaintDC dc(this);
CPaintDC pdc(GetDlgItem(IDC_Picture1));//定义容器
ShowRect.left=0-HS_Value;//水平
ShowRect.top=0-VS_Value;//垂直
ShowRect.right=w-HS_Value;//水平
ShowRect.bottom =h-VS_Value;//垂直一定要全部,否则缩放
image->Draw(pdc,ShowRect,&ClipRect);//Cximage *image;
ReleaseDC(&pdc);主对话框上还有一个按钮,叫手动画线,IDB_handDarw提问:程序要求在open图像后,picture1容器中存在一幅位图时,单击[手动画线]按钮后,
鼠标移动到picture1中的图片上,在位图上单击鼠标用鼠标拖拉一根直线,“不闪烁”?这样的操作我其实会写,在movedown mousemove onpaint 事件分别写代码,记录point,不停paint,但是画线很闪烁
我的思路被放弃我查了网上的资料,有一个技术叫双缓冲,还是改进的三缓冲但是线画到picture1控件下面去了,也就是在对话框上,怎么画到picture1容器中贴代码//.h
CBitmap memBakBMP; //新缓冲区内存DC
CDC memBakDC; //新缓冲区用的位图
BOOL bClicked; //判断是否应当作图
CPoint ptBegin; //记录图象开始的位置
CBitmap memBMP; //新缓冲区用的位图
CDC memDC; //旧缓冲区内存DC//创建时
int CBSYDDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
memDC.CreateCompatibleDC(NULL);
memBMP.CreateCompatibleBitmap(&memDC,1024,768);
memDC.SelectObject(&memBMP);
memDC.FillSolidRect(0,0,1024,768,GetDC()->GetBkColor());
memBakDC.CreateCompatibleDC(NULL);
memBakBMP.CreateCompatibleBitmap(&memBakDC,1024,768);
memBakDC.SelectObject(&memBakBMP);
return 0;
}void CBSYDDlg::handDarw()
{
m_measure=1;//标志为1,代表手动画线
}void CBSYDDlg::OnMouseMove(UINT nFlags, CPoint point)
{if(m_measure==1);//标志为1,代表手动画线{
CRect rect;
GetClientRect(&rect);
memBakDC.BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
memDC.BitBlt(0,0,rect.Width(),rect.Height(),&memBakDC,0,0,SRCCOPY);
memDC.MoveTo(100,100);//假设起点在100,100位置处,现在是测试,不考虑第一个点
memDC.LineTo(point);
Invalidate(false);
}
}
void CBSYDDlg::OnPaint()
{
CPaintDC dc(this);
if(m_measure==1)//;//标志为1,代表手动画线
{
CDC* pdc1 = GetDC();
CRect rect;
GetClientRect(&rect);
pdc1->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY);
ReleaseDC(pdc1);
} if(m_measure!=1)//不是画线
{
CPaintDC pdc(GetDlgItem(IDC_Picture1));//定义容器
ShowRect.left=0-HS_Value;//水平
ShowRect.top=0-VS_Value;//垂直
ShowRect.right=w-HS_Value;//水平
ShowRect.bottom =h-VS_Value;//垂直一定要全部,否则缩放
image->Draw(pdc,ShowRect,&ClipRect);
ReleaseDC(&pdc);
}
}现在这个代码是一团糟,打开图片后正常,一但点击"手动测量"按钮
开始画线了,原来的图片框不见了,移动鼠标直接在窗体画很多线,原来的线也不擦除,彻底无语:-(我想达到的功能是,点击"手动测量"按钮
在picture1中的图片上实时画一条直线条,不擦除背景,用鼠标移动动态画一条直线
就好比windows画图一样,你在打开的图片上画一条直线奉献所有可用分求解!!不胜感谢
解决方案 »
- C++怎么修改默认输入法?
- "sizeof和strlen区别"以及"memcpy和strcpy区别"?
- 遍历文件系统搜索文件(非FindFirst....)
- 一个引用的简单问题
- 求解一简单算法儿,解决立马给分
- 一个COM类的接口是通过调用一个类的成员函数实现,但是为什么每次调用接口就重新构造了被调用类?
- 求教error LNK2001
- 请教一个菜鸟问题,如何在控制面板中设置数据引擎?
- 用vc6.0做的动态库,到其他地方使用需要Mfc42d.dll和Msvcrtd.dll,怎么避免
- 急急急!! 请问MSDN里面所说的Video Capture函数和视频采集卡厂商所提供的SDK有什么不同了?在线等候。。
- 小女子初次接触VC++,有点小问题请教各位大侠,不要见笑
- 请教高手:一个显卡上接两个显示器,实现
你得获得picture1控件的DC画线,也就是this要改成this->picture1控件。
图片要画在OnPaint里面,而不是在初始化画一下就完了。擦除原来的线你得用InvalidateRect,并且记录线的轨迹,按着轨迹擦这样不会闪。
BOOL CBSYDDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
//return CDialog::OnEraseBkgnd(pDC);
}
我这没说清楚。原来的CPaintDC dc(this)不要动。另外在Picture控件的OnPaint声明一个DC,比如CPaintDC dcPic(GetDlgItem(IDC_Picture1)),用这个dcPic去绘图画线。没有Picture的继承类就继承一个。
OnEraseBkgnd返回TRUE的时候,一定要给pDC填充东西,不然背景就乱了。你这里的OnEraseBkgnd就返回FALSE,因为你这里又不需要擦除背景。
1.
BOOL CBSYDDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return FALSE;
//return CDialog::OnEraseBkgnd(pDC);
}你如果用双缓冲绘制全界面的画,就不需要return true..这是你闪烁的一个原因.2.
双缓冲是概念上的,就是你看到的闪烁是因为你屏幕的pDC操作很多次造成的.因此好方法就是全部在内存里画好,屏幕画一次就看不到闪烁了.
如果在onpaint()中
CPaintDC dcPic(GetDlgItem(IDC_Picture1)),
然后用这个dcPic去绘图画线那这样好像不算是用内存dc去画线了?那在onpaint中多次画线,那就算线搞出来不还是闪烁吗
汗,你自己搞一个内存DC啊,这个dcPic只是用来最后贴到屏幕上用的
{
CPaintDC dc(this);
if(m_measure==1)
{ CWnd* pPictureWnd = GetDlgItem(IDC_Picture1);
CDC* pdc = pPictureWnd->GetDC();
CDC dcMem; //用于缓冲作图的内存DC
CDC* pMem=&dcMem;
CBitmap bmp; //内存中承载临时图象的位图
CRect myrect;
GetClientRect(&myrect);
dcMem.CreateCompatibleDC(pdc); //依附窗口DC创建兼容内存DC
bmp.CreateCompatibleBitmap(pdc,w,h);//创建兼容位图
dcMem.SelectObject(&bmp); //将位图选择进内存DC
//按原来背景填充客户区,不然会是黑色
dcMem.FillSolidRect(myrect,pdc->GetBkColor());
/////////防闪烁程序段1结束/////////////////////////////////
dcMem.MoveTo(100,100);
dcMem.LineTo(x,y);
CPaintDC pDC1(GetDlgItem(IDC_Picture1));//定义容器
/////////防闪烁程序段2开始/////////////////////////////////
pDC1.BitBlt(0,0,w,h, &dcMem,0,0,SRCCOPY);//将内存DC上的图象拷贝到前台
dcMem.DeleteDC(); //删除DC
bmp.DeleteObject(); //删除位图
}
}
你这个if(m_measure==1)是干什么的,去掉试试
去不去掉是一样的因为onpaint 还有其它调用,为了和其它功能区分开来
继承CStatic也可以,新建一个类,继承CStatic。在新类::OnEraseBkgnd(CDC* pDC)里面用pDC->Bitblt贴图,就是你上面的代码,并返回TRUE