2016-04-17 8 views
1

は、ここで私がこれまで持っているものです。マウスカーソルのテクスチャをC#でどのようにレンダリングできますか?

[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; 
} 

は(私は他の場所でホットスポット情報を使用しますが、私はその情報を取得しているものを、ここで重要なので、その一部を省略しています)。

これはかなりしばらくの間、動作しますが、最終的に私は、メモリリークのため、私はこれはかなり確信している

IntPtr hdcBitmap = gfxBmp.GetHdc(); 

から来る

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

というエラーを取得します。私はこのメソッドをアプリケーション(毎秒約30ステップ)のすべての更新ステップと呼んでいます。したがって、もしあれば、このメソッドがかなり短期間に表示されると私は信じることができました。どこでメモリリークですか?それとも別の問題がありますか?これらのフィールドの

答えて

1
public IntPtr hbmMask; 
public IntPtr hbmColor; 

の両方がビットマップがGetIconInfo()を呼び出した後処理し、これらはDeleteObject()にコールを呼び出す/ Pでリリースされている必要があり含む終わります。

bmpを発信者に配置することを忘れないでください。

関連する問題