Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[C#] Memory leak in unmanaged code

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

Ik zit met een serieus c#.net probleem nl een memory leak ifv unmanaged code.

Voor een applicatie moet ik custom cursors maken adhv bitmaps. Ik heb een klasse gevonden op codeproject en aangepast naar mijn noden, die gebruik maakt van unmanaged functies. Daar dit de enige manier is om het te doen zonder .cur files aan te maken.

In men applicatie wordt dit gebruikt als tooltip. Daarom moet dit object erg vaak aangemaakt worden en eigenlijk altijd een andere bitmap tonen.

Het probleem zit in het afbreken van het object voordat een nieuw aangemaakt moet worden. Dit gebeurt niet correct, waardoor mijn ram in no time volzit.

Aangezien ik zo goed als geen kennis heb van unmanaged code en hoe erop te debuggen, zit ik redelijk vast.

Ik heb een mini vb project gemaakt die de klasse bevat en het probleem duidelijk aantoont. OnmouseMove worden continue nieuwe objecten aangemaakt waardoor uw ram aan +- 1MB/sec toeslibt.

Alvast bedankt om het even te bekijken

het project vind je hier: *snip*

De klasse:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication1
{

///
/// Creates a Cursor from any bitmap. You can use the alpha-channel
/// for transparency effects.
///
/// you can use the API function CreateIconIndirect to create any cursor from a bitmap.
/// There is not size limit so you can draw the item into a bitmap and convert it into a cursor.
/// The following class can be used for that. An instance of this class must exists as long as the cursor is displayed.
///
public class clsBitmapCursor : IDisposable
{
#region Win-API imports

///
/// API-Structure ICONINFO
///
///
[StructLayout(LayoutKind.Sequential)]
public struct ICONINFO
{
public bool fIcon;
public uint xHotspot;
public uint yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}

///
/// API function CreateIconIndirect
///
[System.Runtime.InteropServices.DllImport("USER32.DLL")]
public static extern IntPtr CreateIconIndirect( ref ICONINFO iconinfo );
///
/// API function DestryIcon
///
[System.Runtime.InteropServices.DllImport("USER32.DLL")]
public static extern bool DestroyIcon( IntPtr hIcon );

#endregion


private ICONINFO iconInfo;
private Cursor cursor = null;
private IntPtr handle = IntPtr.Zero;


#region constructors and destructor
public clsBitmapCursor(System.Drawing.Bitmap bmp)
{
iconInfo = new ICONINFO();
iconInfo.fIcon = false;
iconInfo.xHotspot = 0;
iconInfo.yHotspot = 0;
iconInfo.hbmMask = bmp.GetHbitmap();
iconInfo.hbmColor = bmp.GetHbitmap();
Create();
}
public clsBitmapCursor( System.Drawing.Bitmap bmp, uint HotSpotX, uint HotSpotY )
{
iconInfo = new ICONINFO();
iconInfo.fIcon = false;
iconInfo.xHotspot = HotSpotX;
iconInfo.yHotspot = HotSpotY;
iconInfo.hbmMask = bmp.GetHbitmap();
iconInfo.hbmColor = bmp.GetHbitmap();
Create();
}

///
/// Creates a cursor from a bitmap and combines it with another cursor.
///
public clsBitmapCursor(System.Drawing.Bitmap bmp, Cursor Cursor)
{
iconInfo = new ICONINFO();
iconInfo.fIcon = false;
iconInfo.xHotspot = 0;
iconInfo.yHotspot = 0;
using( System.Drawing.Bitmap bmpdup = bmp.Clone() as System.Drawing.Bitmap )
{
using( Graphics g = Graphics.FromImage( bmpdup ) )
{
Cursor.Draw( g, new Rectangle( new Point( 0, 0 ), Cursor.Size ) );
}
iconInfo.hbmMask = bmpdup.GetHbitmap();
iconInfo.hbmColor = bmpdup.GetHbitmap();
Create();
}
}

///
/// destructor
///
~clsBitmapCursor()
{
Dispose();
}

#endregion


public void moveHotspot(int x, int y)
{
iconInfo.xHotspot = (uint)x;
iconInfo.yHotspot = (uint)y;

Create();
}

private void Create()
{
Dispose();

handle = CreateIconIndirect(ref iconInfo);
cursor = new Cursor(handle);
}

///
/// free the used handles
///
public void Dispose()
{
GC.SuppressFinalize( this );
if(cursor != null) cursor.Dispose();
if (handle != IntPtr.Zero)
DestroyIcon(handle);


}
///
/// The Cursor-Object you can use
///
public Cursor Cursor
{
get
{
return cursor;
}
}
}
}


//de functie die object aanmaakt
private void PrepareCustomCursor()
{
Bitmap bm = new Bitmap(1000, 1000);
Graphics g = Graphics.FromImage(bm);

GraphicsPath gp = new GraphicsPath();
Point lo = new Point(0, 10);
Point lb = new Point(0, 0);
Point rb = new Point(10, 0);
Point ro = new Point(10, 10);

gp.AddLine(lb, rb);
gp.AddLine(rb, ro);
gp.AddLine(ro, lo);
gp.AddLine(lo, lb);


Pen pen = new Pen(Color.Black, 1);

g.DrawPath(pen, gp);

g.Dispose();
gp.Dispose();
pen.Dispose();

if(CursorPixelRectangle != null) CursorPixelRectangle.Dispose();
CursorPixelRectangle = new clsBitmapCursor(bm);
bm.Dispose();

}

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
1) Als je code post, post dan enkel relevante code
2) Gebruik code tags
3) Wat heb je zelf al geprobeerd? Gezocht? Gevonden?
Verwijderd schreef op woensdag 07 mei 2008 @ 18:18:
Alvast bedankt om het even te bekijken

het project vind je hier: snip
4) We zijn geen persoonlijke debug-service of "Fix-it". Zie ook quickfix
5) Als je code 'leent' van derden dan kun je beter terecht bij die derden dan bij ons ;)


Visual Basic .NET:
1
2
3
        private void Create()
        {
            Dispose();

Dat is wel heeeeel ranzig :X

[ Voor 62% gewijzigd door RobIII op 07-05-2008 18:28 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Sorry, maar ik vind de gehele class ranzig. Een bitmap naar een icon omzetten kan heel erg goed in managed code. De basis van onderstaande code komt uit de MSDN.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
        private Icon BitmapToIcon( Image image )
        {
            //transform universal image to bitmap
            Bitmap bmp = new Bitmap( image );
            
            //get windows resource handle for bitmap instance
            IntPtr iconHandle = bmp.GetHicon();

            //Create icon based on icon handle
            Icon icn = Icon.FromHandle( iconHandle );

            return icn;
        }


Verder vond ik in de System.Windows.Forms namespace ook al een Cursor en een CursorConverter class. Lijkt mij niet onmogelijk.

Overigens qualistor, weet je zeker dat je elke keer opnieuw de cursor moet aanmaken? Kun je niet gewoon bij het opstarten van de applicaties de cursors aanmaken. Daarna is het selchts een kwestie van toewijzen. bijvoorbeeld defaultCursor en hoverCursor..

Dit nog allemaal los van het feit dat gebruikers helemaal niet zitten te wachten op custom cursors.

If it isn't broken, fix it until it is..


  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 18-11 23:16

TeeDee

CQB 241

Voor oplossingen tot je probleem: zie Niemand_Anders.

Als ik verder ook nog in je posthistory kijk, zie ik aardig wat zaken/vragen gerelateerd aan de interface c.q. het aanpassen daarvan. Is dat wel zo wenselijk? Ik bedoel, ik zit sowieso niet te wachten op een cursor (hell, misschien zelfs later nog een animatie) in een tooltip.

Heart..pumps blood.Has nothing to do with emotion! Bored