WinCE平台下C#引用API(GDI)一个值得警惕的内存泄漏

由于C#精简框架集绘图函数不支持圆角矩形,所以引用了相关的API。

 

  
  
  
  
  1. [DllImport("\\windows\\coredll.dll", EntryPoint = "RoundRect")]  
  2.         private static extern int CeRoundRect(IntPtr hdc, int X1, int Y1, int X2, int Y2, int X3, int Y3);  

 这是有内存泄漏的源码:

 

  
  
  
  
  1. public static int RoundRect(Graphics e, Pen pen, SolidBrush brush, int X1, int Y1, int X2, int Y2, int X3, int Y3)  
  2.         {           
  3.             IntPtr hpen;  
  4.             IntPtr hbrush;  
  5.  
  6.             if(pen!=null)  
  7.             {  
  8.                 hpen = CreatePen((DashStyle.Solid == pen.DashStyle) ? 0 : 1,  
  9.                 (int)pen.Width, SetRGB(pen.Color.R, pen.Color.G, pen.Color.B));      //创建GDI画笔    
  10.             }  
  11.             else  
  12.             {  
  13.                 hpen = GetStockObject(8);      //空画笔  
  14.             }            
  15.  
  16.             if (brush!= null)  
  17.             {  
  18.                 hbrush = CreateSolidBrush(SetRGB(brush.Color.R, brush.Color.G, brush.Color.B)); //brush.Color.ToArgb());  
  19.             }  
  20.             else  
  21.             {  
  22.                 hbrush = GetStockObject(5);  
  23.             }  
  24.  
  25.             //pen.Dispose();  
  26.             //brush.Dispose();  
  27.  
  28.             IntPtr hdc = e.GetHdc();  
  29.             //---------------------     
  30.              SelectObject(hdc, hbrush);  
  31.              SelectObject(hdc, hpen);  
  32.  
  33.             int intRet=RoundRect(hdc, X1, Y1, X2,Y2, X3, Y3);  
  34.  
  35.             DeleteObject(hbrush);  
  36.             DeleteObject(hpen);  
  37.             //---------------------  
  38.             e.ReleaseHdc(hdc);  
  39.             return intRet;  
  40.         }  
  41.  

这是没有问题的源码:

  
  
  
  
  1. public static int RoundRect(Graphics e, Pen pen, SolidBrush brush, int X1, int Y1, int X2, int Y2, int X3, int Y3)  
  2.        {           
  3.            IntPtr hpen,old_pen;  
  4.            IntPtr hbrush, old_brush;  
  5.  
  6.            if(pen!=null)  
  7.            {  
  8.                hpen = CreatePen((DashStyle.Solid == pen.DashStyle) ? 0 : 1,  
  9.                (int)pen.Width, SetRGB(pen.Color.R, pen.Color.G, pen.Color.B));      //创建GDI画笔    
  10.            }  
  11.            else 
  12.            {  
  13.                hpen = GetStockObject(8);      //空画笔  
  14.            }            
  15.  
  16.            if (brush!= null)  
  17.            {  
  18.                hbrush = CreateSolidBrush(SetRGB(brush.Color.R, brush.Color.G, brush.Color.B)); //brush.Color.ToArgb());  
  19.            }  
  20.            else 
  21.            {  
  22.                hbrush = GetStockObject(5);  
  23.            }  
  24.  
  25.            //pen.Dispose();  
  26.            //brush.Dispose();  
  27.  
  28.            IntPtr hdc = e.GetHdc();  
  29.            //---------------------     
  30.            old_brush=SelectObject(hdc, hbrush);  
  31.            old_pen=SelectObject(hdc, hpen);  
  32.              
  33.            int intRet=RoundRect(hdc, X1, Y1, X2,Y2, X3, Y3);  
  34.  
  35.            SelectObject(hdc, old_brush);  
  36.            SelectObject(hdc, old_pen);  
  37.            DeleteObject(hbrush);  
  38.            DeleteObject(hpen);  
  39.            //---------------------  


            e.ReleaseHdc(hdc);
            return intRet;
        }

       看出代码的区别来了没有?泄漏的原因其实很简单,就是没有重新选入旧的画笔画刷。同样的程序(当然PC端的API库是GDI32)在上位机Window XP平台上没有什么问题(测试大约3天以上),而在WinCE平台确非常明显,大约1~3个小时(视圆角矩形绘图的多寡而定),该程序就会内存耗尽而死。

 

 

你可能感兴趣的:(api,内存,平台,WinCE,gdi)