对话框工程:在wince下WM_ERASEBKGND导致的内存不断增加,以下包括添加的所有代码

逸萌 2009-03-04 08:49:29
我是在ListCtrl中映射WM_ERASEBKGND后不断Invalidate ListCtrl发现的问题,
然后写的对话框工程就加了这些代码,发现确实添加WM_ERASEBKGND消息映射导致,只要注释ON_WM_ERASEBKGND()
就不存在问题!请问如何在添加WM_ERASEBKGND消息处理不导致内存不断增加。
BEGIN_MESSAGE_MAP(CListctrltestDlg, CDialog)
//{{AFX_MSG_MAP(CListctrltestDlg)
ON_WM_ERASEBKGND()
ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_RefreshUIDataStream, OnRefreshUIDataStream)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CListctrltestDlg message handlers
BOOL CListctrltestDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

CenterWindow(GetDesktopWindow()); // center to the hpc screen

// TODO: Add extra initialization here

//PostMessage(WM_RefreshUIDataStream);
SetTimer(111,10,NULL);

return TRUE; // return TRUE unless you set the focus to a control
}




BOOL CListctrltestDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
//return TRUE;也内存不断增加

return CDialog::OnEraseBkgnd(pDC);
}

void CListctrltestDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default

if(nIDEvent == 111)
{
Invalidate();
UpdateWindow();
}

CDialog::OnTimer(nIDEvent);
}

...全文
323 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
wohuazhen 2010-06-17
  • 打赏
  • 举报
回复
因为没有释放CPen实例。deleteobject
逸萌 2009-03-07
  • 打赏
  • 举报
回复
代码逐步断块注释产生分析,最后发现
{
CPen *pOldPen = NULL;
CPen gridline(PS_SOLID, 1, m_gridColor);
pOldPen = pDC->SelectObject(&gridline);
if (nSubItem>0)
{
pDC->MoveTo(boxRect.left, boxRect.top);
pDC->LineTo(boxRect.left, boxRect.bottom);
}
if (nNumLines==1 || nItem==GetItemCount()-1 || (int)GetItemData(nItem+1)>=1)
{
pDC->MoveTo(boxRect.left, boxRect.bottom-1);
pDC->LineTo(boxRect.right, boxRect.bottom-1);
}
pDC->SelectObject(&pOldPen);
}
居然会有问题,不知道为什么,然后
//if (nSubItem>0)
//{
// pDC->MoveTo(boxRect.left, boxRect.top);
// pDC->LineTo(boxRect.left, boxRect.bottom);
//}
//if (nNumLines==1 || nItem==GetItemCount()-1 || (int)GetItemData(nItem+1)>=1)
//{
// pDC->MoveTo(boxRect.left, boxRect.bottom-1);
// pDC->LineTo(boxRect.right, boxRect.bottom-1);
//}
却还有问题,真想不通,
最后在CPen前加static 即OK了!
static CPen gridline(PS_SOLID, 1, m_gridColor);即不会出现一段时间后内存逐步增加
逸萌 2009-03-06
  • 打赏
  • 举报
回复
o, thanks
cnzdgs 2009-03-06
  • 打赏
  • 举报
回复
我对CE不太了解,Windows可以用任务管理器来查看GDI资源数量。
逸萌 2009-03-06
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 cnzdgs 的回复:]
出问题时内存增大到多少?GDI资源数量正常吗?
[/Quote]
32M Program Memory 还剩下15M
怎么确定GDI资源数量是否正常?
逸萌 2009-03-05
  • 打赏
  • 举报
回复
大家可以在wince实际测试下这个工程:
10ms会明显的看到内存不断增加
100ms会大约间隔10秒中看到内存不断增加
1000ms大约间隔3分钟中看到内存不断增加

而我的应用是50ms就要刷新
逸萌 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cnzdgs 的回复:]
当你添加了WM_ERASEBKGND消息映射之后,MFC在调用你的响应函数之前,要构造一个CDC类的临时对象,将指针作为参数传给你的函数,函数返回后,对象不会立即销毁(可能是等到消息队列清空之后,具体我也不清楚),因此当你频繁刷新窗口时,会导致内存不断增加。
[/Quote]
OnEraseBkgnd的pDC不知是否是OnPaint中的dc传递进来的?我个人那样以为
逸萌 2009-03-05
  • 打赏
  • 举报
回复
Invalidate只是为了测试,实际应用的ListCtrl是调用的RedrawItem单行刷新的!
而InvalidateRect即使一个小区域,也会导致OnEraseBkgnd的调用,然后导致同样的问题的!
逸萌 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 arong1234 的回复:]
内存增加不等于内存泄漏,这是俩概念

引用 4 楼 allenhiman 的回复:
放慢速度还会有内存泄漏吗,我怀疑是刷新过快,系统来不及释放画图资源,又申请了新的资源。导致内存加大
[/Quote]
内存泄漏一定内存增加!
逸萌 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 allenhiman 的回复:]
yun,泄漏导致的增加 有什么问题吗?
[/Quote]
我的应用要求实时刷新,泄漏导致的增加导致程序运行逐渐变慢, 在时间2个小时后系统基本上就跑不动了(此时看到内存并没有用完呀,比如32M Program Memory 还剩下15M),最后只能重新启动
逸萌 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 arong1234 的回复:]
我觉得你如此平凡的刷新屏幕,本身就应该占用大量内存,
擦除背景只是使得你情况更严重而已
注意:频率高于100ms的刷新毫无意义,你应该把你定时器设置到100
另外:刷新时也不应该Invalidate,而应该局限到你需要刷新的矩形
[/Quote]

100ms也会存在同样的问题,只是时间间隔相对长了10倍才发现内存不断增加的现象

但是像映射WM_PAINT,注释WM_ERASEBKGND后,即使1ms刷新也不存在问题
allenhiman 2009-03-05
  • 打赏
  • 举报
回复
yun,泄漏导致的增加 有什么问题吗?
cnzdgs 2009-03-05
  • 打赏
  • 举报
回复
出问题时内存增大到多少?GDI资源数量正常吗?
逸萌 2009-03-05
  • 打赏
  • 举报
回复
执行是同样的,就是在死循环里面
不停的
Invalidate, 而自绘的内容一直不变(因为测试)
pDC->DrawText( str, rect, DT_SINGLELINE|DT_NOPREFIX|DT_LEFT|DT_VCENTER|DT_NOPREFIX);
cnzdgs 2009-03-05
  • 打赏
  • 举报
回复
15分钟后做了什么?内存增加与字体有何关系?
逸萌 2009-03-05
  • 打赏
  • 举报
回复
OnEraseBkgnd导致的内存不断增加解决了!
我在OnPaint中最后调用CDC::DeleteTempMap();即可, 即使刷新频率1ms也没有问题:

但现在程序在运行后大约前15分钟都没有内存增加,但是之后突然逐步增加,因为我的自绘制是文字,
所以逐步增加几分钟后文字的字体比所选字体突然变大了好些?
刷新频率大致10ms, 请问这可能是什么因素导致?
逸萌 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 cnzdgs 的回复:]
引用 13 楼 mydeardingxiaoli 的回复:
OnEraseBkgnd的pDC不知是否是OnPaint中的dc传递进来的?我个人那样以为

OnEraseBkgnd是发生在OnPaint前面的,怎么可能用OnPaint中的对象。你跟踪以下MFC的代码就可以看到,调用OnEraseBkgnd之前临时构造了一个CDC对象,并且调用之后没有销毁。
[/Quote]
我错了
cnzdgs 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 mydeardingxiaoli 的回复:]
OnEraseBkgnd的pDC不知是否是OnPaint中的dc传递进来的?我个人那样以为
[/Quote]
OnEraseBkgnd是发生在OnPaint前面的,怎么可能用OnPaint中的对象。你跟踪以下MFC的代码就可以看到,调用OnEraseBkgnd之前临时构造了一个CDC对象,并且调用之后没有销毁。
allenhiman 2009-03-05
  • 打赏
  • 举报
回复
也可能是资源泄露把系统gdi资源用光了
  • 打赏
  • 举报
回复
是不是GDI泄露
加载更多回复(6)

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧