我单步执行代码并在任务管理器中查看进程使用的 GDI 和用户对象的数量。跟踪我在评论中写的代码中的对象数量。我注意到在执行以下代码后,仍然有一个未发布的用户对象和一个未发布的 GDI 对象。我忘了在哪里释放它们?
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.
}
}
}