MFC PICTURE控件 闪屏问题求解决
mfc吧
全部回复
仅看楼主
level 2
king2009637 楼主
一个对话框窗口,三个picture控件,要在三个picture控件画三幅图,并且,三幅图像是定时刷新在变化,利用网上的双缓冲方法并没有能解决闪屏的问题,甚至变得更加糟糕。问题的所在应该是刷新重绘,整个窗口都重绘了,导致窗口所有的控件闪烁。求解决办法。
2014年02月23日 12点02分 1
level 2
king2009637 楼主
代码:
VOID CLXTomDlg::OnDraw()
{
int i;
srand((long)time(NULL));
// CRgn rgn1, rgn2,rgn3;
CPaintDC dc(this); // device context for painting
//两种颜色的画笔
CPen pen_red(PS_SOLID,1,RGB(255,0,0));
CPen pen_black(PS_SOLID,1,RGB(0,0,0));
//获取绘制坐标的控件
CWnd* pWnd = GetDlgItem(IDC_STATIC_INFRAREDMAP);
CDC* pDC = pWnd->GetDC();
CWnd* pWnd_radar = GetDlgItem(IDC_STATIC_RADARMAP);
CDC* pDC_radar = pWnd_radar->GetDC();
CWnd* pWnd_mixture = GetDlgItem(IDC_STATIC_MIXTURE);
CDC* pDC_mixture = pWnd_mixture->GetDC();
CRect picRect_infrared;
GetDlgItem(IDC_STATIC_INFRAREDMAP)->GetWindowRect(&picRect_infrared);
CRect picRect_radar;
GetDlgItem(IDC_STATIC_RADARMAP)->GetWindowRect(&picRect_radar);
CRect picRect_mixture;
GetDlgItem(IDC_STATIC_MIXTURE)->GetWindowRect(&picRect_mixture);
////////////红外/////////////////////////////////////
tagPOINT pt[8]={{95,84},{125,101},{157,124},{173,155},{84,125},{101,125},{104,147},{135,123}};
for(i=0;i<8;i++)
{
pt[i].x=pt[i].x+rand()%50+10;
pt[i].x=pt[i].y+rand()%50+10;
}
CDC dcMem;
CBitmap bm;
GetClientRect(&picRect_infrared);
// rgn1.CreateRectRgnIndirect(picRect_infrared);
// InvalidateRect(&picRect_infrared);
// Step 1:为屏幕DC创建兼容的内存DC :CreateCompatibleDC()
dcMem.CreateCompatibleDC(pDC);
// Step 2:创建位图:CreateCompatibleBitmap()
bm.CreateCompatibleBitmap(pDC,picRect_infrared.Width(),picRect_infrared.Height());
dcMem.SelectObject(&bm);
// Step 3:把位图选入设备环境:SelectObject(),可以理解为选择画布
dcMem.FillSolidRect(picRect_infrared,pDC->GetBkColor());
//更改画笔颜色
dcMem.SelectObject(pen_red);
// 画图
for( i=0;i<8;i++)
{
dcMem.Ellipse(pt[i].x-10,pt[i].y-10,pt[i].x+10,pt[i].y+10);
}
//pDC->BitBlt(picRect_infrared.left,picRect_infrared.top,picRect_infrared.Width(),picRect_infrared.Height(),&dcMem,0,0,SRCCOPY);
//
tagPOINT pt1[8]={{95,84},{125,101},{157,124},{173,155},{84,125},{101,125},{104,147},{135,123}};
for(i=0;i<8;i++)
{
pt1[i].x=pt1[i].x+rand()%50+10;
pt1[i].x=pt1[i].y+rand()%50+10;
}
////////////雷达/////////////////////////////////////
CDC dcMem_radar;
CBitmap bm_radar;
GetClientRect(&picRect_radar);
// rgn2.CreateRectRgnIndirect(picRect_radar);
//InvalidateRect(&picRect_radar);
// Step 1:为屏幕DC创建兼容的内存DC :CreateCompatibleDC()
dcMem_radar.CreateCompatibleDC(pDC_radar);
// Step 2:创建位图:CreateCompatibleBitmap()
bm_radar.CreateCompatibleBitmap(pDC_radar,picRect_radar.Width(),picRect_radar.Height());
dcMem_radar.SelectObject(&bm_radar);
// Step 3:把位图选入设备环境:SelectObject(),可以理解为选择画布
dcMem_radar.FillSolidRect(picRect_radar,pDC_radar->GetBkColor());
//更改画笔颜色
dcMem_radar.SelectObject(pen_black);
// 画图
for( i=0;i<8;i++)
{
dcMem_radar.Ellipse(pt1[i].x-10,pt1[i].y-10,pt1[i].x+10,pt1[i].y+10);
}
////////////红外—雷达/////////////////////////////////////
CDC dcMem_mixture;
CBitmap bm_mixture;
GetClientRect(&picRect_mixture);
// rgn3.CreateRectRgnIndirect(picRect_mixture);
// InvalidateRect(&picRect_mixture);
// Step 1:为屏幕DC创建兼容的内存DC :CreateCompatibleDC()
dcMem_mixture.CreateCompatibleDC(pDC_mixture);
// Step 2:创建位图:CreateCompatibleBitmap()
bm_mixture.CreateCompatibleBitmap(pDC_mixture,picRect_mixture.Width(),picRect_mixture.Height());
dcMem_mixture.SelectObject(&bm_mixture);
// Step 3:把位图选入设备环境:SelectObject(),可以理解为选择画布
dcMem_mixture.FillSolidRect(picRect_mixture,pDC_mixture->GetBkColor());
//更改画笔颜色
dcMem_mixture.SelectObject(pen_black);
// 红笔画图
for( i=0;i<8;i++)
{
dcMem_mixture.Ellipse(pt1[i].x-10,pt1[i].y-10,pt1[i].x+10,pt1[i].y+10);
}
dcMem_mixture.SelectObject(pen_red);
// 黑笔画图
for( i=0;i<8;i++)
{
dcMem_mixture.Ellipse(pt[i].x-10,pt[i].y-10,pt[i].x+10,pt[i].y+10);
}
// Step 4:把绘制好的图形“拷贝”到屏幕上:BitBlt()
pDC->BitBlt(picRect_infrared.left,picRect_infrared.top,picRect_infrared.Width(),picRect_infrared.Height(),&dcMem,0,0,SRCCOPY);
pDC_radar->BitBlt(picRect_radar.left,picRect_radar.top,picRect_radar.Width(),picRect_radar.Height(),&dcMem_radar,0,0,SRCCOPY);
pDC_mixture->BitBlt(picRect_mixture.left,picRect_mixture.top,picRect_mixture.Width(),picRect_mixture.Height(),&dcMem_mixture,0,0,SRCCOPY);
dcMem.DeleteDC();
bm.DeleteObject();
dcMem_radar.DeleteDC();
bm_radar.DeleteObject();
dcMem_mixture.DeleteDC();
bm_mixture.DeleteObject();
//CRect rectClient;
// CRgn rgn1, rgn2,rgn3;
// GetClientRect();
// rgn1.CreateRectRgnIndirect();
// rgn2.CreateRectRgnIndirect();
// rgn1.CombineRgn(&rgn1, &rgn2, RGN_XOR);
// rgn1.CombineRgn(&rgn1, &rgn3, RGN_XOR);
// InvalidateRgn(&rgn1, TRUE);
//UpdateWindow();
}
void CLXTomDlg::OnPaint()
{
// SetRedraw(FALSE);
OnDraw();
//SetRedraw(TRUE);
CDialog::OnPaint();
}
BOOL CLXTomDlg::OnEraseBkgnd(CDC* pDC)
{
// return CDialog::OnEraseBkgnd(pDC);
return true;
}
2014年02月25日 07点02分 4
level 9
亲,你这个是在重绘对话框,不是重绘 PICTURE控件,当然会闪屏。。。你既然都会双缓冲,为何不直接绘在 对话框里面,对话框基本不会闪屏,只是你重绘的地方不对而已!
2014年02月27日 15点02分 8
[咦]重绘这东西做得太多了。。
2014年02月27日 15点02分
回复 le12380 :额,能给点指教么,因为刚学不久。如果说要仅仅更新三个picture控件要怎么做。
2014年02月27日 15点02分
回复 king2009637 :要做这个挺复杂的,而且也没必要,你直接使用GDI+ 画上去就好了,你都会双缓冲了,上网再找找代码就OK了,很简单而已
2014年02月27日 15点02分
level 12
楼主,强烈建议你用d2d做,GDI画出来真心没法看
2014年05月31日 16点05分 9
什么事d2d 啊!
2014年11月13日 10点11分
回复 life361sky :direct2d,百度搜一下就行,绘制效率远高于gdi
2014年11月14日 01点11分
level 6
pDC_mixture->BitBlt(picRect_mixture.left,picRect_mixture.top,picRect_mixture.Width(),picRect_mixture.Height(),&dcMem_mixture,0,0,SRCCOPY);
显示函数
先绘制不显示
需要显示的时候单独调用这句话。关于闪屏是由于窗口刷新的缘故,你刷的是整个工作区,同时绘制,显示,这样慢是正常的,你需要后台绘制,显示放在定时函数里。
2016年03月22日 04点03分 10
是滴,了解了
2017年08月01日 03点08分
level 2
大兄弟你好,我现在也遇到相同的问题了,请问你最后是怎么解决的,能帮我一下吗?
2017年05月24日 08点05分 11
搞不定问题,搞定客户就行了。
2017年05月26日 08点05分
搞定客户
2017年08月01日 03点08分
level 10
你不要全部客户区都重绘,你只需要哪个需要更新你就重绘哪部分,这样就能解决了
2017年05月28日 12点05分 12
yes
2017年08月01日 03点08分
level 1
程序风格太乱,懒得看
2017年08月01日 06点08分 13
1