I would create a new Layered Window at the mouse position that follows the mouse around. The new window would get it's contents from the desired content (the image or text) which would be rendered with an alpha channel that decreased as it moved away from the mouse.
Render the text or image to a GDI+ bitmap with alpha channel, loop through the pixels and set the alpha channel as a function of the mouse cursor position. Set the bitmap on the layered window and update it's position based on where the mouse is.
Creating a layered window in C# (taken from some other source):
public class SplashScreenForm : Form
{
public SplashScreenForm()
{
this.TopMost = true;
this.Show();
SelectBitmap(Properties.Resources.splashblended);
}
// Sets the current bitmap
public void SelectBitmap(Bitmap bitmap)
{
// Does this bitmap contain an alpha channel?
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
{
throw new ApplicationException("The bitmap must be 32bpp with alpha-channel.");
}
// Get device contexts
IntPtr screenDc = APIHelp.GetDC(IntPtr.Zero);
IntPtr memDc = APIHelp.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr hOldBitmap = IntPtr.Zero;
try
{
// Get handle to the new bitmap and select it into the current device context
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
hOldBitmap = APIHelp.SelectObject(memDc, hBitmap);
// Set parameters for layered window update
APIHelp.Size newSize = new APIHelp.Size(bitmap.Width, bitmap.Height); // Size window to match bitmap
APIHelp.Point sourceLocation = new APIHelp.Point(0, 0);
APIHelp.Point newLocation = new APIHelp.Point(this.Left, this.Top); // Same as this window
APIHelp.BLENDFUNCTION blend = new APIHelp.BLENDFUNCTION();
blend.BlendOp = APIHelp.AC_SRC_OVER; // Only works with a 32bpp bitmap
blend.BlendFlags = 0; // Always 0
blend.SourceConstantAlpha = 255; // Set to 255 for per-pixel alpha values
blend.AlphaFormat = APIHelp.AC_SRC_ALPHA; // Only works when the bitmap contains an alpha channel
// Update the window
APIHelp.UpdateLayeredWindow(Handle, screenDc, ref newLocation, ref newSize,
memDc, ref sourceLocation, 0, ref blend, APIHelp.ULW_ALPHA);
}
finally
{
// Release device context
APIHelp.ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
{
APIHelp.SelectObject(memDc, hOldBitmap);
APIHelp.DeleteObject(hBitmap); // Remove bitmap resources
}
APIHelp.DeleteDC(memDc);
}
}
protected override CreateParams CreateParams
{
get
{
// Add the layered extended style (WS_EX_LAYERED) to this window
CreateParams createParams = base.CreateParams;
createParams.ExStyle |= APIHelp.WS_EX_LAYERED;
return createParams;
}
}
}
// Class to assist with Win32 API calls
internal class APIHelp
{
// Required constants
public const Int32 WS_EX_LAYERED = 0x80000;
public const Int32 HTCAPTION = 0x02;
public const Int32 WM_NCHITTEST = 0x84;
public const Int32 ULW_ALPHA = 0x02;
public const byte AC_SRC_OVER = 0x00;
public const byte AC_SRC_ALPHA = 0x01;
public enum Bool
{
False = 0,
True = 1
}
[StructLayout(LayoutKind.Sequential)]
public struct Point
{
public Int32 x;
public Int32 y;
public Point(Int32 x, Int32 y) { this.x = x; this.y = y; }
}
[StructLayout(LayoutKind.Sequential)]
public struct Size
{
public Int32 cx;
public Int32 cy;
public Size(Int32 cx, Int32 cy) { this.cx = cx; this.cy = cy; }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ARGB
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BLENDFUNCTION
{
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
}
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling = true)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll", ExactSpelling = true)]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool DeleteObject(IntPtr hObject);
}