Убедитесь, что любой ресурс GDI (например, bmp.GetHIcon) удаляется. В противном случае вы получите утечку памяти. Следующий код (метод расширения для значка) отлично работает для WPF. Создает курсор в виде стрелки с маленьким значком в правом нижнем углу.
Примечание: этот код использует значок для создания курсора. Он не использует текущий элемент управления пользовательского интерфейса.
Matthias
public static Cursor CreateCursor(this Icon icon, bool includeCrossHair, System.Drawing.Color crossHairColor)
{
if (icon == null)
return Cursors.Arrow;
// create an empty image
int width = icon.Width;
int height = icon.Height;
using (var cursor = new Bitmap(width * 2, height * 2))
{
// create a graphics context, so that we can draw our own cursor
using (var gr = System.Drawing.Graphics.FromImage(cursor))
{
// a cursor is usually 32x32 pixel so we need our icon in the lower right part of it
gr.DrawIcon(icon, new Rectangle(width, height, width, height));
if (includeCrossHair)
{
using (var pen = new System.Drawing.Pen(crossHairColor))
{
// draw the cross-hair
gr.DrawLine(pen, width - 3, height, width + 3, height);
gr.DrawLine(pen, width, height - 3, width, height + 3);
}
}
}
try
{
using (var stream = new MemoryStream())
{
// Save to .ico format
var ptr = cursor.GetHicon();
var tempIcon = Icon.FromHandle(ptr);
tempIcon.Save(stream);
int x = cursor.Width/2;
int y = cursor.Height/2;
#region Convert saved stream into .cur format
// set as .cur file format
stream.Seek(2, SeekOrigin.Begin);
stream.WriteByte(2);
// write the hotspot information
stream.Seek(10, SeekOrigin.Begin);
stream.WriteByte((byte)(width));
stream.Seek(12, SeekOrigin.Begin);
stream.WriteByte((byte)(height));
// reset to initial position
stream.Seek(0, SeekOrigin.Begin);
#endregion
DestroyIcon(tempIcon.Handle); // destroy GDI resource
return new Cursor(stream);
}
}
catch (Exception)
{
return Cursors.Arrow;
}
}
}
/// <summary>
/// Destroys the icon.
/// </summary>
/// <param name="handle">The handle.</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public extern static Boolean DestroyIcon(IntPtr handle);