views:

259

answers:

2

I have written an application which is getting the Icon info of current cursor using GetIconInfo function of user32.dll, It works fine for some time, but after some time it starts providing wrong information in ICONINFO.hbmMask (some negative value), and when on the next line I try to get Bitmap object from Bitmap.HBitmap(bitmask), it throws an exception:

A Generic error occured in GDI+.

From there onwords, it continuously gives this exception, as GetIconInfo always return negative value (all this code is working in a loop)..

Can any one tell me what this problem is? and how to avoid the next iteration exception?

Here is the code

        while (true)
        {
 //DLLimport User32.dll
            PlatformInvokeUSER32.ICONINFO temp; 

 //Get the current cursor
 IntPtr curInfo = GetCurrentCursor(); 


            Cursor cur;
            Icon ic;

            if (curInfo != null && curInfo.ToInt32() != 0 && isOSelected)
            {

                cur = CheckForCusrors(curInfo);

                try
                {
  //Dllimport User32.dll 
  //after some time the temp.hbmMask begin to get -ive vlaue from following function call
                    PlatformInvokeUSER32.GetIconInfo(curInfo, out temp);

                    if (temp.hbmMask != IntPtr.Zero)
                    {

   //due to negative value of hbmMask the following function generates an exception
                            Bitmap bitmask = Bitmap.FromHbitmap(temp.hbmMask);

   ic = Icon.FromHandle(curInfo);

                            Bitmap bmpCur = ic.ToBitmap();

                     }
            }
                catch (Exception ee)
                {
                    //Exception message is 
  //A Generic error occured in GDI+
  //and this loop begins to throw exception continuously
                }
            }


        }// while ended
A: 

Check out this PInvoke sample, are you properly deleting the objects you are pulling in through unmanaged code?

Joe Caffeine
A: 

How large is your loop? GDI+ resources are OS resources and are limited in availability.

You can find out if this is your problem by monitoring the HANDLEs allocated by your process. If GDI+ starts to complain when a certain handle count (HBITMAP or HICON) reaches a limit, then you know you have to deal with your resources more intelligently. You can start by using Task Manager to do this but might want to switch to more sophisticated software like Process Explorer.

If this is your problem, then you need to read about IDisposable and make sure you call Dispose on your objects after you're done with them (won't be rendered anymore). Bitmaps and Icons and most GDI+ objects implement IDisposable.

Furthermore, it's unclear to me, but you may need to call DeleteObject on some of the raw GDI objects themselves (all depends upon where you got their handles).

Frank Krueger
I need to capture the Icon continuously, It works fine for some time and then it started to give this exception and never come back..
Ummar
The question then is, where do you free the resource? My initial statement stands, you have limited resources. Even if you load them continuously, the machine does not have an infinite amount of resources.
Frank Krueger
Thanks Frank, but can you please send me some code sample which tell me how to release the resource, can I use DeleteObject from gdi32.dll... I am in C# enviornment..
Ummar
Yes you can and should delete hbmMask and hbmColor
Mattias S