2009-02-15 7 views
8

Tworzę kursor w środowisku wykonawczym z zasobu obrazu. HotSpot nowego kursora jest zawsze ustawiony na 16x16 (obraz 32x32). Czy można zmienić HotSpot w czasie wykonywania lub czy będę musiał utworzyć pliki .cur?Zmień kursor HotSpot w WinForm/.NET

Odpowiedz

22

Na pewno można. Oto moje funkcje narzędziowe, edytuj według własnego uznania :)

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

Pięknie wykonana. – smack0007

+0

Och, stary, spędziłem kilka bezowocnych godzin zmieniając bity w pliku .ico, próbując zrobić kolorowy .cur z właściwym hotspotem - teraz mogę po prostu użyć początkowych pngs. Co za ulga. – Usurer

0

Zobacz this post on MSDN. Wydaje się, że istnieje kilka możliwych rozwiązań (za pomocą P/Invoke), które powinieneś móc kopiować i wklejać.

0

Ponieważ jest to pytanie .NET, a nie konkretnie pytanie C#, tutaj jest konwersja VB.NET części kodu Nicka (aby uratować innym kłopot).

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