2009-02-15 21 views
8

Estoy creando un cursor en tiempo de ejecución a partir de un recurso de imagen. El HotSpot del nuevo Cursor siempre se establece en 16x16 (imagen 32x32). ¿Es posible cambiar el HotSpot en tiempo de ejecución o tendré que crear archivos .cur?Cambiar Cursor HotSpot en WinForms/.NET

Respuesta

22

Usted puede. Aquí están mis funciones de utilidad, edición como mejor le parezca :)

public struct IconInfo 
    { 
     public bool fIcon; 
     public int xHotspot; 
     public int yHotspot; 
     public IntPtr hbmMask; 
     public IntPtr hbmColor; 
    } 
    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo); 
    [DllImport("user32.dll")] 
    public static extern IntPtr CreateIconIndirect(ref IconInfo icon); 

    /// <summary> 
    /// Create a cursor from a bitmap without resizing and with the specified 
    /// hot spot 
    /// </summary> 
    public static Cursor CreateCursorNoResize(Bitmap bmp, int xHotSpot, int yHotSpot) 
    { 
     IntPtr ptr = bmp.GetHicon(); 
     IconInfo tmp = new IconInfo(); 
     GetIconInfo(ptr, ref tmp); 
     tmp.xHotspot = xHotSpot; 
     tmp.yHotspot = yHotSpot; 
     tmp.fIcon = false; 
     ptr = CreateIconIndirect(ref tmp); 
     return new Cursor(ptr); 
    } 


    /// <summary> 
    /// Create a 32x32 cursor from a bitmap, with the hot spot in the middle 
    /// </summary> 
    public static Cursor CreateCursor(Bitmap bmp) 
    { 
     int xHotSpot = 16; 
     int yHotSpot = 16; 

     IntPtr ptr = ((Bitmap)ResizeImage(bmp, 32, 32)).GetHicon(); 
     IconInfo tmp = new IconInfo(); 
     GetIconInfo(ptr, ref tmp); 
     tmp.xHotspot = xHotSpot; 
     tmp.yHotspot = yHotSpot; 
     tmp.fIcon = false; 
     ptr = CreateIconIndirect(ref tmp); 
     return new Cursor(ptr); 
    } 
+1

Funcionó muy bien. – smack0007

+0

Oh, amigo, he pasado unas horas infructuosas cambiando bits en un archivo .ico tratando de hacer un colorido .cur con un punto de acceso adecuado - ahora puedo usar los png iniciales. Qué alivio. – Usurer

0

Tome un vistazo a this post on MSDN. Parece haber un par de soluciones posibles (usando P/Invoke) que usted debería poder copiar y pegar y usar.

0

Dado que esta es una pregunta de .NET y no específicamente una pregunta de C#, aquí hay una conversión de VB.NET de parte del código de Nick (para salvar a otros el problema).

Module IconUtility 
Structure IconInfo 
    Public fIcon As Boolean 
    Public xHotspot As Integer 
    Public yHotspot As Integer 
    Public hbmMask As IntPtr 
    Public hbmColor As IntPtr 
End Structure 

Private Declare Function GetIconInfo Lib "user32.dll" (hIcon As IntPtr, ByRef pIconInfo As IconInfo) As Boolean 
Private Declare Function CreateIconIndirect Lib "user32.dll" (ByRef icon As IconInfo) As IntPtr 

' Create a cursor from a bitmap without resizing and with the specified hot spot 
Public Function CreateCursorNoResize(bmp As System.Drawing.Bitmap, xHotSpot As Integer, yHotSpot As Integer) As Cursor 
    Dim ptr As IntPtr = bmp.GetHicon 
    Dim tmp As IconInfo = New IconInfo() 
    GetIconInfo(ptr, tmp) 
    tmp.xHotspot = xHotSpot 
    tmp.yHotspot = yHotSpot 
    tmp.fIcon = False 
    ptr = CreateIconIndirect(tmp) 
    Return New Cursor(ptr) 
End Function 
End Module 
Cuestiones relacionadas