swythan

swythan
- Name: [not set]
- Favorite Languages: [not set]
- Website: [not set]
- Location: [not set]
- About Me: [not set]
-
WPF Tutorial - How To Use Custom Cursors
05/12/2009 - 08:29
Fantastic! Just what I needed.
I think your use of SafeHandle is a bit out, though. SafeFileHandle calls CloseHandle(handle) in it's ReleaseHandle implementation, but CloseHandle doesn't deal with icons. For icons you should call DestroyIcon.
Here's my version. I've also reorganised a bit.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Win32.SafeHandles;
namespace Controls.Utilities
{
public class CursorHelper
{
private static class NativeMethods
{
public struct IconInfo
{
public bool fIcon;
public int xHotspot;
public int yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
[DllImport("user32.dll")]
public static extern SafeIconHandle CreateIconIndirect(ref IconInfo icon);
[DllImport("user32.dll")]
public static extern bool DestroyIcon(IntPtr hIcon);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
}
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
private class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeIconHandle()
: base(true)
{
}
override protected bool ReleaseHandle()
{
return NativeMethods.DestroyIcon(handle);
}
}
private static Cursor InternalCreateCursor(System.Drawing.Bitmap bmp, int xHotSpot, int yHotSpot)
{
var iconInfo = new NativeMethods.IconInfo();
NativeMethods.GetIconInfo(bmp.GetHicon(), ref iconInfo);
iconInfo.xHotspot = xHotSpot;
iconInfo.yHotspot = yHotSpot;
iconInfo.fIcon = false;
SafeIconHandle cursorHandle = NativeMethods.CreateIconIndirect(ref iconInfo);
return CursorInteropHelper.Create(cursorHandle);
}
public static Cursor CreateCursor(UIElement element, int xHotSpot, int yHotSpot)
{
element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
element.Arrange(new Rect(new Point(), element.DesiredSize));
RenderTargetBitmap rtb =
new RenderTargetBitmap(
(int)element.DesiredSize.Width,
(int)element.DesiredSize.Height,
96, 96, PixelFormats.Pbgra32);
rtb.Render(element);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
using (var bmp = new System.Drawing.Bitmap(ms))
{
return InternalCreateCursor(bmp, xHotSpot, yHotSpot);
}
}
}
}
}
Recent Comments