Debugging a GDI objects leak

Hello,

My application grabs screenshots, transforms them as JPEG strings and sends them over TCP/IP. On the Windows side, when viewing the task manager, the “GDI objects” column (hidden by default) keeps increasing until my app finally gets Nil Object exceptions (the limit of GDI handles is reached).
In my code, there’s no clear pictures leakage: I don’t use arrays to hold a serie of pictures; only local variables that will go out of scope and global ones that only hold a single picture. Also, the runtime.ObjectCount doesn’t increase that much.
I can’t reproduce it with a simple project, so I have to debug mine. I have no idea how to debug that. Looking for advices.

How do you grab the screenshot?

I’m using the MBS plugin’s ScreenshotDisplayMBS function for that.

I have finally found the method where the GDI objects are created widely. However, I don’t know how it’s wrong. It’s a method I wrote to retrieve the mouse cursor shape. Is there something obviously wrong in it?

P.S.: sorry for the indentation: it’s correct when I edit my post, not when I publish it.

  #if TargetWindows then
    dim HWND,i,CursHandle,CursThread,MyThread As Integer
    dim pt As Point
    
    declare function GetCursorPos lib "User32" (ByRef pt as Point) as Boolean
    declare Function WindowFromPoint lib "User32" (pt as Point) as integer
    declare function GetWindowThreadProcessId lib "User32" (Wnd as Integer,ByRef ProcID as Integer) as Integer
    declare function GetCurrentThreadId lib "Kernel32" as Integer
    declare function AttachThreadInput lib "User32" (OwnThread as integer,RemoteThread as Integer,Attach as Boolean) as Boolean
    declare function GetCursor lib "User32" as Integer
    if GetCursorPos(pt) then
      HWND=WindowFromPoint(pt)
      CursThread=GetWindowThreadProcessId(HWND,i)
      MyThread=GetCurrentThreadId
      if CursThread<>MyThread then
        if AttachThreadInput(MyThread,CursThread,True) then
          CursHandle=GetCursor()
          call AttachThreadInput(MyThread,CursThread,False)
        end if
      else
        CursHandle=GetCursor()
      end if
    end if
    
    dim p As Picture=new Picture(32,32,32)
    Declare Function DrawIconEx lib "User32" (HDC as Integer,XLeft as Integer,YTop as Integer,HIcon as Integer,CXWidth as integer,CXHeight as Integer,CursStep as Integer,BrushHandle as integer,Flags as Integer) as Boolean
    Declare Function GetLastError lib "Kernel32" as Integer
    Declare Function DeleteDC lib "Gdi32" (HDC as Integer) as Integer
    
    dim b As Boolean
    b=DrawIconEx(p.Graphics.Handle(1),0,0,CursHandle,0,0,0,0,14)
    b=DrawIconEx(p.Mask.Graphics.Handle(1),0,0,CursHandle,0,0,0,0,13)
    if not b then i=GetLastError
    
    //The next two following lines have been added very recently, hoping to fix my problem, but they don't:
    i=DeleteDC(p.Graphics.Handle(1))
    i=DeleteDC(p.Mask.Graphics.Handle(1))

    dim ci As CursorInfo
    dim pa As Pair
    Declare Function GetIconInfo lib "User32" (HIcon as Integer,ByRef IconInfo as CursorInfo) as Boolean
    if GetIconInfo(CursHandle,ci) then
      pa=new Pair(ci.HotSpotX,ci.HotSpotY)
    end if
    
    Return new pair(p,pa)
  #endif

To post code, please click the code icon <[>] above the editor and paste.

Or select the code and click the icon.