2013-09-24 63 views
0

我单步执行代码,并在任务管理器中查看进程使用的GDI和用户对象的数量。跟踪我在评论中编写的代码中的对象数量。我注意到在执行下面的代码后,仍然有一个未发布的用户对象和一个未发布的GDI对象。我忘了释放他们的地方?如何销毁ICONINFO?

using System; 
using System.Runtime.InteropServices; 

namespace UnmanagedResourcesTest 
{ 
    class Program 
    { 
     static void Main(string[] args)//20 user objects; 27 GDI objects 
     { 
      CURSORINFO ci = new CURSORINFO(); 
      ci.cbSize = Marshal.SizeOf(ci); 
      if (GetCursorInfo(out ci)) 
      { 
       ////21(+1) user objects; 27 GDI objects 
       if (ci.flags == CURSOR_SHOWING) 
       { 
        bool result; 
        IntPtr hicon = CopyIcon(ci.hCursor);//uo1/go1 
        ////22(+1) user objects; 28(+1) GDI objects 
        ICONINFO icInfo; 
        if (GetIconInfo(hicon, out icInfo))//go1 
        { 
         ////22 user objects; 29(+1) GDI objects 
         Console.WriteLine("ICONINFO gotten"); 
        } 
        result = DestroyIcon(hicon); 
        ////21(-1) user objects; 28(-1) GDI objects 
        Console.WriteLine("Is hicon destroyed? - " + result); 
       } 
      } 
      //leaves 21-20=1 not released user object and 28-27=1 not released GDI object 
      Console.ReadKey(); 
     } 

     private const Int32 CURSOR_SHOWING = 0x00000001; 

     [DllImport("user32.dll", EntryPoint = "GetCursorInfo")] 
     private static extern bool GetCursorInfo(out CURSORINFO pci); 

     [DllImport("user32.dll", EntryPoint = "CopyIcon")] 
     private static extern IntPtr CopyIcon(IntPtr hIcon); 

     [DllImport("user32.dll", EntryPoint = "GetIconInfo")] 
     private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo); 

     [DllImport("user32.dll", SetLastError = true)] 
     static extern bool DestroyIcon(IntPtr hIcon); 

     [StructLayout(LayoutKind.Sequential)] 
     private struct ICONINFO 
     { 
      public bool fIcon;   // Specifies whether this structure defines an icon or a cursor. A value of TRUE specifies 
      public Int32 xHotspot;  // Specifies the x-coordinate of a cursor's hot spot. If this structure defines an icon, the hot 
      public Int32 yHotspot;  // Specifies the y-coordinate of the cursor's hot spot. If this structure defines an icon, the hot 
      public IntPtr hbmMask;  // (HBITMAP) Specifies the icon bitmask bitmap. If this structure defines a black and white icon, 
      public IntPtr hbmColor; // (HBITMAP) Handle to the icon color bitmap. This member can be optional if this 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     private struct POINT 
     { 
      public Int32 x; 
      public Int32 y; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     private struct CURSORINFO 
     { 
      public Int32 cbSize;  // Specifies the size, in bytes, of the structure. 
      public Int32 flags;   // Specifies the cursor state. This parameter can be one of the following values: 
      public IntPtr hCursor;   // Handle to the cursor. 
      public POINT ptScreenPos;  // A POINT structure that receives the screen coordinates of the cursor. 
     } 
    } 
} 

回答

1

我发现了内存泄漏的原因。应拨打下一行:

result = DeleteObject(icInfo.hbmMask);