2016-04-17 4 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; 
} 

(я использую данные точки доступа в другом месте, но я опускаю эту часть, потому что важно здесь получает эту информацию).

Это работает довольно долгое время, но в конце концов я получаю сообщение об ошибке говорящее

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

Coming из

IntPtr hdcBitmap = gfxBmp.GetHdc(); 

Я довольно уверен, что это происходит из-за утечки памяти. Я вызываю этот метод каждый шаг обновления в моем приложении (около 30 шагов в секунду), поэтому я мог поверить, что если он есть, он будет отображаться довольно коротко, как это делается. Где же утечка памяти? Или здесь есть какая-то другая проблема?

ответ

1
public IntPtr hbmMask; 
public IntPtr hbmColor; 

Оба этих полей в конечном итоге, содержащий растровые ручки после вызова GetIconInfo() и они должны быть освобождены с р/ссылаться на вызов DeleteObject().

Не забудьте удалить bmp в вызывающем абоненте.

Смежные вопросы