在 WINCE 开发中使用 GDI 绘图时,碰到的内存泄露问题

大白天的见活鬼,十分的无语:

在一个 CDialog 中写了个 Timer ,Timer中有一段用 GDI 绘图的代码如下:

void WaveDlg::OnTimer(UINT_PTR nIDEvent)

{

   CWnd *pWave=GetDlgItem(IDC_WAVE);
   CClientDC pdc(pWave);

}

很好,就这两行代码,其他的啥也没有,运行期间没有任何内存泄露。

可以注意到,我申请了一个 pdc ,并且没有去手写任何代码去释放它,因为我认为 CClientDC pdc(pWave); 这条语句所生成的对象,会在 OnTimer 函数结束时,自动析构。事实也是如此,就这两行代码,没有任何内存泄露,我特意把 Timer 的触发时间调整为 1ms,触发快,内存泄露明显,不用慢慢等。

OK,接着来,修改代码如下:

void WaveDlg::OnTimer(UINT_PTR nIDEvent)

{

   CWnd *pWave=GetDlgItem(IDC_WAVE);
   CClientDC pdc(pWave);

   CBrush brsWhite;

   brsWhite.CreateSolidBrush(RGB(255,255,255));

   pdc.SelectObject(brsWhite);

   ::DeleteObject(brsWhite.m_hObject);

}

运行,内存一“泄”千里。。。。

无奈,再次尝试,修改代码如下:

void WaveDlg::OnTimer(UINT_PTR nIDEvent)

{

   CWnd *pWave=GetDlgItem(IDC_WAVE);
   CClientDC pdc(pWave);

   CBrush brsWhite;

   brsWhite.CreateSolidBrush(RGB(255,255,255));

   pdc.SelectObject(brsWhite);

   ::DeleteObject(brsWhite.m_hObject);

    ::ReleaseDC(pWave->m_hWnd,pdc.m_hDC);

}

运行,不漏了。。。。

总结,在某个函数中,申请了一个局部的 CDC 后,如果,不对它进行修改,比如用它去 selectobject 某些对象,或者,不用它去画图,那么,可以不用手写代码去释放它。但是,一旦引用了这个 CDC 做了某些工作,那么,就需要手写代码去释放它了。。。

最后,为了保险起见,将所有的 CPen,CBrush 都声明为类成员,而不是局部变量,只在类成员初始化的时候,对他们调用一次 Create ,避免在局部函数中反复对他们调用 Create,避免内存泄露

你可能感兴趣的:(在 WINCE 开发中使用 GDI 绘图时,碰到的内存泄露问题)