using System;
using System.Runtime.InteropServices;
namespace CustomCursor
{
static class createCursor
{
[DllImport("user32.dll")]
private static extern IntPtr CreateCursor(
IntPtr hInst,
int xHotSpot,
int yHotSpot,
int nWidth,
int nHeight,
byte[] pvANDPlane,
byte[] pvXORPlane
);
static byte[] PointCodes = new byte[] {
127, //10000000
191, //01000000
223, //00100000
239, //00010000
247, //00001000
251, //00000100
253, //00000010
254, //00000001
255};//00000000
//1 -black; 0 -white;
static public IntPtr Ellipse(IntPtr handle, int radiusX, int radiusY, double angle)
{
angle = Math.PI * angle / 180;
int MaxRadius = Math.Max(radiusX, radiusY);
int sideLength = GetSide(MaxRadius*2+4);
int hotspotX = sideLength/2, hotspotY = sideLength/2;
int length = sideLength * sideLength / 8;
byte[] andMaskCursor = new byte[length];
MakeTransparent(ref andMaskCursor);
_Ellipse(ref andMaskCursor, hotspotX, hotspotY, radiusX, radiusY, angle);
byte[] xorMaskCursor = new byte[length];
return CreateCursor(
handle, // app. instance
hotspotX, // hot spot horiz pos
hotspotY, // hot spot vert pos
sideLength, // cursor width
sideLength, // cursor height
andMaskCursor, // AND mask
xorMaskCursor // XOR mask
);
}
static void MakeTransparent(ref byte[] andMaskCursor)
{
for (int i = 0; i < andMaskCursor.Length; i++)
{
andMaskCursor[i] = PointCodes[8]; //make transparent cursor
}
}
static int GetSide(int sideLength)
{
if (sideLength % 16 != 15)
{
return sideLength + 16 - sideLength % 16;
}
else return sideLength;
}
static int rot_x(int x, int y, double theta)
{
return (int)Math.Round(x * Math.Cos(theta) - y * Math.Sin(theta));
}
static int rot_y(int x, int y, double theta)
{
return (int)Math.Round(x * Math.Sin(theta) + y * Math.Cos(theta));
}
static void _Ellipse(ref byte[] andMaskCursor, int x, int y, int a, int b, double alfa)
{
int firstx = x + rot_x(a, 0, alfa);
int firsty = y + rot_y(a, 0, alfa);
double angle = 0;
int itercount = Math.Max(a, b) * 2 + 40;
double delta = 2 * Math.PI / itercount;
int x1 = firstx, y1 = firsty; //moveto
for (int i = 1; i < itercount; i++)
{ angle += delta;
int rx = (int)Math.Round(a * Math.Cos(angle));
int ry = (int)Math.Round(b * Math.Sin(angle));
_Line(ref andMaskCursor, x1, y1, x + rot_x(rx, ry, alfa),
y + rot_y(rx, ry, alfa));
x1 = x + rot_x(rx, ry, alfa);
y1 = y + rot_y(rx, ry, alfa);
}
_Line(ref andMaskCursor, x1, y1, firstx, firsty);
}
static void _Line(ref byte[] andMaskCursor, float x1, float y1, float x2, float y2)
{
float itercount = Math.Max(Math.Abs(x1 - x2), Math.Abs(y1 - y2));
float dx = (x1 - x2) / itercount;
float dy = (y1 - y2) / itercount;
int sideLength = (int)(Math.Sqrt(andMaskCursor.Length * 8));
for (int i = 0; i < itercount; i++)
{
int xy = (int)Math.Truncate(Math.Round(y1) * sideLength / 8 + Math.Round(x1) / 8);
andMaskCursor[xy] &= PointCodes[(int)(Math.Round(x1) % 8)];
x1 -= dx;
y1 -= dy;
}
}
}
}