アイコンエディタを自作して16色ではなくフルカラーで保存するプログラムを作成しました。
アイコンヘッダーとディレクトリのデータを少し変えればカーソルファイルの保存もできそうです。ところがCursorクラスでこれを使おうとすると白黒のカーソルになってしまいます。Cursorクラスはカラーカーソルには対応していないのです。
しかし
この方法を使えばカラーカーソルを使用することができます。そこでこれをもう少し使いやすくするためにクラスを作成してみました。ライブラリ化すると便利かもしれません。
API関数のGetIconInfo関数とCreateIconIndirect関数を使います。
今回はカーソルのサイズやホットスポットを自由に設定できるカーソルをつくることにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; namespace MyLibrary { public class CursorEx { static public Cursor GetCursorFromImage(Image image, Size size, int HotspotX, int HotspotY, Color transparent) { Bitmap bitmap = new Bitmap(size.Width, size.Height); Graphics g = Graphics.FromImage(bitmap); g.DrawImage(image, new Rectangle(0, 0, size.Width, size.Height)); bitmap.MakeTransparent(transparent); Icon tempCursor = Icon.FromHandle(bitmap.GetHicon()); bitmap.Dispose(); g.Dispose(); IconInfo tmp = new IconInfo(); GetIconInfo(tempCursor.Handle, ref tmp); tmp.fIcon = false; tmp.xHotspot = HotspotX; tmp.yHotspot = HotspotY; IntPtr ptr = CreateIconIndirect(ref tmp); tempCursor.Dispose(); return new Cursor(ptr); } static public Cursor GetCursorFromImage(Bitmap bmp, Size size, int HotspotX, int HotspotY, Color transparent) { return GetCursorFromImage((Image)bmp, size, HotspotX, HotspotY, transparent); } static public Cursor GetCursorFromImage(string filePath, Size size, int HotspotX, int HotspotY, Color transparent) { Image image = Image.FromFile(filePath); Cursor cursor = GetCursorFromImage(image, size, HotspotX, HotspotY, transparent); image.Dispose(); return cursor; } static public Cursor GetCursorFromImage(Icon icon, Size size, int HotspotX, int HotspotY, Color transparent) { Bitmap bitmap = icon.ToBitmap(); Cursor cursor = GetCursorFromImage(bitmap, size, HotspotX, HotspotY, transparent); bitmap.Dispose(); return cursor; } static public Cursor GetCursorFromImage(Type type, string resource, Size size, int HotspotX, int HotspotY, Color transparent) { Icon icon = new Icon(type, resource); Bitmap bitmap = icon.ToBitmap(); Cursor cursor = GetCursorFromImage(bitmap, size, HotspotX, HotspotY, transparent); bitmap.Dispose(); icon.Dispose(); return cursor; } static public Cursor GetCursorFromImage(System.IO.Stream stream, Size size, int HotspotX, int HotspotY, Color transparent) { Image image = Image.FromStream(stream); Cursor cursor = GetCursorFromImage(image, size, HotspotX, HotspotY, transparent); image.Dispose(); return cursor; } [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo); [DllImport("user32.dll")] static extern IntPtr CreateIconIndirect(ref IconInfo icon); struct IconInfo { public bool fIcon; // アイコンの場合 true, カーソルの場合 false public int xHotspot; // カーソルのホットスポットの X 座標 public int yHotspot; // カーソルのホットスポットの Y 座標 public IntPtr hbmMask; // 透過用のビットマップハンドル public IntPtr hbmColor; // 画像用のビットマップハンドル } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public partial class Form1 : Form { private void Form1_MouseDown(object sender, MouseEventArgs e) { // 右クリックでカーソル変更 if(e.Button == MouseButtons.Right) { Image image = Image.FromFile("mycursor.png"); this.Cursor = CursorEx.GetCursorFromImage(image, new Size(100, 100), 0, 0, Color.White); image.Dispose(); return; } // 左クリックでもとに戻す if(e.Button == MouseButtons.Left) this.Cursor = Cursors.Default; } } |
このようにすればカラーカーソルを好きな大きさで表示させることができます。
大きくなったマウスカーソルをうまくキャプチャできない。ぐぬぬぬ・・・。
解決編はこちら