2016-04-17 10 views
1

Hier ist, was ich bisher:Wie kann ich die Mauszeiger Textur in C# rendern?

[StructLayout(LayoutKind.Sequential)] 
struct CursorInfo 
{ 
    public Int32 cbSize; 
    public Int32 flags 
    public IntPtr hCursor; 
    public POINT ptScreenPos; 
} 

[DllImport("user32.dll")] 
static extern int GetSystemMetrics(SystemMetric smIndex); 

public enum SystemMetric 
{ 
    SM_CXICON    = 11, // 0x0B 
    SM_CYICON    = 12, // 0x0C 
} 


[DllImport("user32.dll", SetLastError = true)] 
static extern bool DrawIconEx(IntPtr hdc, 
    int xLeft, 
    int yTop, 
    IntPtr hIcon, 
    int cxWidth, 
    int cyHeight, 
    int istepIfAniCur, 
    IntPtr hbrFlickerFreeDraw, 
    int diFlags); 

const int DI_MASK = 0x0001; 
const int DI_IMAGE = 0x0002; 
const int DI_NORMAL = 0x0003; 
const int DI_COMPAT = 0x0004; 
const int DI_DEFAULTSIZE = 0x0008; 
const int DI_NOMIRROR = 0x0010; 

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); 



Bitmap GetCursorBitmap() 
{ 
    CursorInfo ci = new CursorInfo(); 
    ci.cbSize = Marshal.SizeOf (typeof(CursorInfo)); 

    if (!GetCursorInfo (ref ci)) { 
    throw new Exception("Failed to get cursor info"); 
    } 

    IntPtr cursorPointer = ci.hCursor; 

    int iconWidth = GetSystemMetrics (SystemMetric.SM_CXICON); 
    int iconHeight = GetSystemMetrics (SystemMetric.SM_CYICON); 

    Bitmap bmp; 
    bmp = new System.Drawing.Bitmap(iconWidth, iconHeight, PixelFormat.Format32bppRgb); 
    bmp.MakeTransparent(); 

    Graphics gfxBmp = Graphics.FromImage(bmp);  

    IntPtr hdcBitmap = gfxBmp.GetHdc(); 

    DrawIconEx(hdcBitmap, 0, 0, cursorPointer, iconWidth, iconHeight, 0, IntPtr.Zero, DI_NORMAL); 

    // DrawIcon(hdcBitmap, 0, 0, cursorPointer); has the same problem 

    IconInfo hotSpotInfo = new IconInfo(); 
    GetIconInfo(cursorPointer, ref hotSpotInfo); 

    Point hotSpot = new Point(hotSpotInfo.xHotspot, hotSpotInfo.yHotspot) 

    gfxBmp.ReleaseHdc(hdcBitmap);    
    gfxBmp.Dispose(); 

    return bmp; 
} 

(Ich benutze die Hotspot Info an anderer Stelle, aber ich weggelassen, dass ein Teil, denn was hier zählt ist, dass Informationen bekommen).

Dies funktioniert für eine ganze Weile, aber schließlich bekomme ich einen Fehler

A null reference or invalid value was found [GDI+ status: InvalidParameter] 

Aus dem Leck

IntPtr hdcBitmap = gfxBmp.GetHdc(); 

Ich bin ziemlich sicher, dies ist aufgrund eines Speichers sagen. Ich nenne diese Methode jeden Aktualisierungsschritt in meiner Anwendung (ungefähr 30 Schritte pro Sekunde), also könnte ich glauben, dass, wenn es einen gibt, es ziemlich bald auftauchen würde, wie dieser tut. Wo ist der Speicherverlust? Oder gibt es hier ein anderes Problem?

Antwort

1
public IntPtr hbmMask; 
public IntPtr hbmColor; 

Beide Felder am Ende enthält Bitmap Griffe nach dem Aufruf von GetIconInfo() und diese müssen mit einem p/Invoke Aufruf DeleteObject() freigegeben werden.

Vergessen Sie nicht, die bmp im Anrufer zu entsorgen.

Verwandte Themen