Page 1 of 1

Checking non released GDI objects

PostPosted: Sun Jun 21, 2009 8:11 am
by Antonio Linares
FiveWin provides some functions to check non released GDI objects.

We have have enhanced that code, so you can manage it from PRG level and have full control on it:

rescheck.prg
Code: Select all  Expand view

static aResources := {}

//----------------------------------------------------------------------------//

function PalBmpFree( hBmp, hPal )

   DeleteObject( hBmp )
   DeleteObject( hPal )

return nil

//----------------------------------------------------------------------------//

function AddResource( nHResource, cType )

   AAdd( aResources, { cType, nHResource, ProcName( 3 ), ProcLine( 3 ) } )
   
return nil  

//----------------------------------------------------------------------------//

function DelResource( nHResource )

   local nAt

   if ( nAt := AScan( aResources, { | aRes | aRes[ 2 ] == nHResource } ) ) != 0
      ADel( aResources, nAt )
      ASize( aResources, Len( aResources ) - 1 )
   endif    

return nil

//----------------------------------------------------------------------------//

function CheckRes()

   local cInfo := "", n
   
   for n = 1 to Len( aResources )
      cInfo += aResources[ n, 1 ] + "," + Chr( 9 ) + Str( aResources[ n, 2 ] ) + "," + Chr( 9 ) + ;
               aResources[ n, 3 ] + "," + Chr( 9 ) + Str( aResources[ n, 4 ] ) + CRLF
   next  
   
   MsgInfo( cInfo )
   
return nil  

//----------------------------------------------------------------------------//

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapiitm.h>
#include <hbvm.h>
#include <windows.h>

void RegisterResource( HANDLE hRes, LPSTR szType )
{
   PHB_ITEM pRet = hb_itemNew( hb_param( -1, HB_IT_ANY ) );

   hb_vmPushSymbol( hb_dynsymGetSymbol( "ADDRESOURCE" ) );
   hb_vmPushNil();
   hb_vmPushLong( ( LONG ) hRes );
   hb_vmPushString( szType, strlen( szType ) );
   hb_vmFunction( 2 );

   hb_itemReturnRelease( pRet );
}  

void pascal DelResource( HANDLE hResource )
{
   PHB_ITEM pRet = hb_itemNew( hb_param( -1, HB_IT_ANY ) );

   hb_vmPushSymbol( hb_dynsymGetSymbol( "DELRESOURCE" ) );
   hb_vmPushNil();
   hb_vmPushLong( ( LONG ) hResource );
   hb_vmFunction( 1 );

   hb_itemReturnRelease( pRet );
}    

#pragma ENDDUMP
 

To check consumed GDI objects in your app, add this function call at the beginning:
Code: Select all  Expand view

SetResDebug()
 

and when you want to check the GDI objects, simply call:
Code: Select all  Expand view

CheckRes()
 

Re: Checking non released GDI objects

PostPosted: Sun Jun 21, 2009 8:52 am
by Otto
Hello Antonio,
if I link in rescheck.prg I get following error:
Best regards,
Otto
Application
===========
Path and name: C:\xWinhotel\xRechnung.EXE (32 bits)
Size: 3,083,776 bytes
Time from start: 0 hours 0 mins 2 secs
Error occurred at: 21.06.2009, 10:49:02
Error description: Error BASE/1068 Argument error: array access
Args:
[ 1] = N 0
[ 2] = N 1

Stack Calls
===========
Called from: .\source\classes\BTNBMP.PRG => TBTNBMP:LOADBITMAPS(0)
Called from: .\source\classes\BTNBMP.PRG => TBTNBMP:NEWBAR(0)
Called from: c:\develop8\WH_Fwh\xRg\RECHNUNG.PRG => EXEC_ZIRECHNUNG(1721)
Called from: c:\develop8\WH_Fwh\xRg\RECHNUNG.PRG => ZIRECHNUNG(371)
Called from: c:\develop8\WH_Fwh\xRg\RECHNUNG.PRG => (b)MAIN(356)
Called from: c:\develop8\WH_Fwh\xRg\window.prg => TMDIFRAME:ACTIVATE(876)
Called from: c:\develop8\WH_Fwh\xRg\RECHNUNG.PRG => MAIN(356)

Re: Checking non released GDI objects

PostPosted: Sun Jun 21, 2009 2:17 pm
by Antonio Linares
Otto,

We have edited and modified the previous code.

Please copy it and test it again, thanks :-)

Re: Checking non released GDI objects

PostPosted: Sun Jun 21, 2009 3:49 pm
by Otto
Hello Antonio,
it errors out, too.
Best regards,
Otto

Re: Checking non released GDI objects

PostPosted: Sun Jun 21, 2009 5:24 pm
by toninhofwi
Hi Otto,

I use MemProof.

Regards,

Toninho.

Re: Checking non released GDI objects

PostPosted: Sun Jun 21, 2009 5:38 pm
by Antonio Linares
Otto,

> it errors out, too.

What error do you get ? How to reproduce it ? thanks

Re: Checking non released GDI objects

PostPosted: Sun Jun 21, 2009 7:05 pm
by Antonio Linares
Otto,

We have modified the original posted code in the first msg here.

Please try it again with the new code, thanks :-)

Re: Checking non released GDI objects

PostPosted: Mon Jun 22, 2009 7:11 am
by Otto
Hello Antonio,

thank you. Now it is working.
Would you please be so kind to tell me what the values are for.

Thanks in advance
Otto

Image

Re: Checking non released GDI objects

PostPosted: Thu Jun 25, 2009 6:16 am
by Antonio Linares
Otto,

This is the way to use it:

At the beginning of your app you call SetResDebug()

Then you call to CheckRes() before going into an app option (dialog, report, etc) then you exit it, and go into it again calling CheckRes() first. That way you will see if your GDI cosumed objets grow, or remains the same ones.

Re: Checking non released GDI objects

PostPosted: Fri Jun 26, 2009 11:35 pm
by James Bott
Antonio,

>Then you call to CheckRes() before going into an app option (dialog, report, etc) then you exit it, and go into it again calling CheckRes() first.

I'm with Otto, I'm not sure what I am seeing. Is the second column the windows handle? What is the last column?

Do we need to just count the listed items (unreleased items) before entering a routine and then again after? If so, then perhaps it would help if we had another function that would just return the count. This way we could record it before and then after the routine we could check it against the before count. Manually counting the items in the displayed list each time will be tedious and prone to error.

James

Re: Checking non released GDI objects

PostPosted: Sat Jun 27, 2009 12:14 am
by Daniel Garcia-Gil
Hello James.

> Is the second column the windows handle?
yes, is control handle

> What is the last column?
is the numer line from call

Re: Checking non released GDI objects

PostPosted: Sat Jun 27, 2009 12:19 am
by James Bott
Thanks, Daniel, now if we can just the function I described, we will be able to troubleshoot these unreleased resources easily.

Actually, after I thought about it more, it would be valuable to have access to the array containg this data. Then we could store the array before entering a routine, then after the routine, compare the new array and isolate just those new unreleased resources. This is what we would have to do manually anyway. In the best case, we can try to track down why those resources are not being released. In the case where we can't find the problem, we could automatically release the new unreleased resources when exiting the routine. This could be made generic so we could use it with any troublesome routine.

James

Re: Checking non released GDI objects

PostPosted: Sat Jun 27, 2009 2:43 am
by nageswaragunupudi
>
it would be valuable to have access to the array containg this data.
>
That is the static array, aResources. We can use it in our program the way you wanted to. We may add a function CheckResArray() to return the static array,

Also the message displayed by checkres() function can have the number of resources in the first line.

Re: Checking non released GDI objects

PostPosted: Tue Jan 05, 2010 10:46 am
by Otto
Is MemProof a standalone program. How can it be used with FIVEWIN?
Thanks in advance
Otto