f



Strange behavior

Hi all,

I was still fighting for monthes with unpredicable error in my app
compiled in vo27b.
For example: access violation when leaving the app. This error was
coming after the self:exec() of the start function (and after the
queryclose of the standardshell) or HyperLabel:Axit that is not found.

Today, I have imported the Manifest module. Just to try. I don't have
the errors anymore... but... all my menu and look is changed... due to
the windows xp style...

It's a dilema: update all my menu and button.. or deal with the error !

Any suggestion ?


Jean-Luc

0
Jean
11/25/2005 10:08:56 AM
comp.clipper.visual-objects 12618 articles. 0 followers. Post Follow

32 Replies
1077 Views

Similar Articles

[PageSpeed] 55

There is a big problem for me: caption of pushbutton with an image is
printed over the image... not very beautifull.. And I need the caption,
because it make the short cut: &Save....

Grrr

0
Jean
11/25/2005 10:32:14 AM
Jean-Luc,

The access violation (5333 error I presume) is almost certainly 
indicative of an error somewhere in the app. It'd be far better to spend 
time chasing it down...

Nick

In article <1132914734.295439.310970@f14g2000cwb.googlegroups.com>, 
jls@igsoft.be says...
> 
> There is a big problem for me: caption of pushbutton with an image is
> printed over the image... not very beautifull.. And I need the caption,
> because it make the short cut: &Save....
> 
> Grrr
> 
> 
0
Nick
11/25/2005 12:29:05 PM
Jean-Luc,
Do you need the caption at run-time or design time. For me, I use a
subclassed push-button and i set the caption to "" if the button has a
picture. It is a one line change. I believe Jamal came up with it
shortly after 2.7 was released. I can repost if you are interested.

Regards,

Willie

0
Williem
11/25/2005 1:00:51 PM
Jean-Luc,

Firstly, please read the Readmes and What's New documents. They list in 
some detail the changes relating to Windows themes and the impact on 
various controls. There will be many clues to help you with this. Once 
you have read this and still cannot achieve what you want, come back to 
the ng with specific code and I am sure we can help. We all survived 
<bg>.

Secondly, the shut down sequence is now a little tighter and demands you 
do things 'properly'. For instance, load any sample, create the exe, run 
it, close it and will not give this problem. Hence something you are 
doing in your app causes the problem and you need to isolate your 
closure sequences in your classes to find out where this happens from. 
Again, we've all been through this and come out the end unscathed. You 
will too <g>.

Geoff


"Jean-Luc Stassen" <jls@igsoft.be> wrote in message 
news:1132914734.295439.310970@f14g2000cwb.googlegroups.com:

> There is a big problem for me: caption of pushbutton with an image is
> printed over the image... not very beautifull.. And I need the caption,
> because it make the short cut: &Save....
>
> Grrr

0
Geoff
11/26/2005 1:02:30 AM
Jean-Luc,
I would suggest that you include the ShowGCDump function (you can find it 
somewhere in this NG). From time to time, while using your app, just run 
this dump and take a look on all the objects, arrays, ... that are left in 
memory where they should not.

You can also set :
PROCEDURE StartUp AS VOID PASCAL _INIT3
 _RegisterExit( @ShowGCDump() )
RETURN

to run the dump automatically when you leave the program.

Your problem stays somewhere in your code. It is just being shown up when 
you leave the program.

HTH

Eric


"Jean-Luc Stassen" <jls@igsoft.be> a �crit dans le message de news: 
1132913336.581054.81800@z14g2000cwz.googlegroups.com...
> Hi all,
>
> I was still fighting for monthes with unpredicable error in my app
> compiled in vo27b.
> For example: access violation when leaving the app. This error was
> coming after the self:exec() of the start function (and after the
> queryclose of the standardshell) or HyperLabel:Axit that is not found.
>
> Today, I have imported the Manifest module. Just to try. I don't have
> the errors anymore... but... all my menu and look is changed... due to
> the windows xp style...
>
> It's a dilema: update all my menu and button.. or deal with the error !
>
> Any suggestion ?
>
>
> Jean-Luc
> 


0
Eric
11/26/2005 9:03:43 AM
FUNCTION ShowGCDump() AS VOID PASCAL

	LOCAL pGCEntry AS _GCENTRY
	LOCAL pGCDump AS _GCDUMP
	LOCAL dwItems AS DWORD
	LOCAL dwMax AS DWORD
	LOCAL nItem AS DWORD
	LOCAL cDumpFilename AS STRING
	LOCAL oLog AS GCSLogFile
	LOCAL oTemp AS OBJECT

	DoEvents()
	CollectForced()
	DynLock()	// lock up dynamic mem to obtain accurate result

	dwMax:=100
	pGCDump:=MemAlloc(_SIZEOF(DWORD)+(dwMax*_SIZEOF(_GCENTRY)))
	pGCDump.nEntryCount:=dwMax
	dwItems:=CreateGCDump(pGCDump,6)	// 0=All, 7=Strings, 5=Arrays, 
3=FLOATs, 6=Objects
	IF dwItems > 0
		cDumpFilename := gcDumpFileRoot+"_" + 
Right(DToS(Today()),4)+Left(Time(),2)+SubStr(Time(),4,2)+".log"
		DebugOutputNoTrace("GCDump Found Items",dwItems, "GC Dump log file", 
cDumpFilename)
		oLog := GCSLogFile{cDumpFilename,,,,FALSE} 	// create new file each 
time
		IF !oLog:IsOpen
			DebugOutput("Failed to create log file")
		ENDIF
		oLog:Write("Active references to dynamic memory: "+NTrim(dwItems))
		oLog:Write("---------------------------------------------------------")
		oLog:Write()
		IF dwItems = dwMax
			oLog:Write(" Maximum Entries inserted - Possibly more existed")
			oLog:Write()
		ENDIF
		pGCEntry:=PTR(_CAST,DWORD(_CAST,pGCDump)+_SIZEOF(DWORD))
		FOR nItem := 1 UPTO dwItems
			oLog:Write("Created by : 
"+Iif(pGCEntry.nGCType==GC_TYPE_STACK,"Compiler","RegisterKID()"))
			oLog:Write("Dyn.Addr.  : "+AsString(pGCEntry.pDynMem) + " Ref: " + 
AsString(pGCEntry.ppRefDynMem))
			oLog:Write("Size       : "+NTrim(pGCEntry.nSize))
			oLog:Write("Type       : "+GCVarType(pGCEntry.nVarType))
			oLog:Write("Value      : "+Psz2String(@pGCEntry.abValue[1]))
			oLog:Write("---------------------------------------------------------")
			pGCEntry:=pGCEntry+1
		NEXT
		IF !oLog:Close()
			DebugOutput("Error closing GCDumpFile")
		ELSE
			ShellExecute(NULL_PTR, 
PSZ("OPEN"),String2Psz(oLog:Filename),NULL_PSZ,NULL_PSZ,SW_SHOWNORMAL)
		ENDIF
	ELSE
		DebugOutputNoTrace("Exiting GCDump - all objects destroyed")
	ENDIF
	MemFree(pGCDump)
	gcDumpFileRoot := NULL_STRING	// clear global string

	DynUnLock()

	RETURN

0
Geoff
11/26/2005 9:23:22 AM
Geoff,

Thanks for Jean-Luc.

Greetings from frozen Belgium (-1�C, 20 cm snow).

Eric


"Geoff Schaller" <geoffxx@softxxwareobjectives.com.au> a �crit dans le 
message de news: 43882963@dnews.tpgi.com.au...
> FUNCTION ShowGCDump() AS VOID PASCAL
>
> LOCAL pGCEntry AS _GCENTRY
> LOCAL pGCDump AS _GCDUMP
> LOCAL dwItems AS DWORD
> LOCAL dwMax AS DWORD
> LOCAL nItem AS DWORD
> LOCAL cDumpFilename AS STRING
> LOCAL oLog AS GCSLogFile
> LOCAL oTemp AS OBJECT
>
> DoEvents()
> CollectForced()
> DynLock() // lock up dynamic mem to obtain accurate result
>
> dwMax:=100
> pGCDump:=MemAlloc(_SIZEOF(DWORD)+(dwMax*_SIZEOF(_GCENTRY)))
> pGCDump.nEntryCount:=dwMax
> dwItems:=CreateGCDump(pGCDump,6) // 0=All, 7=Strings, 5=Arrays, 3=FLOATs, 
> 6=Objects
> IF dwItems > 0
> cDumpFilename := gcDumpFileRoot+"_" + 
> Right(DToS(Today()),4)+Left(Time(),2)+SubStr(Time(),4,2)+".log"
> DebugOutputNoTrace("GCDump Found Items",dwItems, "GC Dump log file", 
> cDumpFilename)
> oLog := GCSLogFile{cDumpFilename,,,,FALSE} // create new file each time
> IF !oLog:IsOpen
> DebugOutput("Failed to create log file")
> ENDIF
> oLog:Write("Active references to dynamic memory: "+NTrim(dwItems))
> oLog:Write("---------------------------------------------------------")
> oLog:Write()
> IF dwItems = dwMax
> oLog:Write(" Maximum Entries inserted - Possibly more existed")
> oLog:Write()
> ENDIF
> pGCEntry:=PTR(_CAST,DWORD(_CAST,pGCDump)+_SIZEOF(DWORD))
> FOR nItem := 1 UPTO dwItems
> oLog:Write("Created by : 
> "+Iif(pGCEntry.nGCType==GC_TYPE_STACK,"Compiler","RegisterKID()"))
> oLog:Write("Dyn.Addr.  : "+AsString(pGCEntry.pDynMem) + " Ref: " + 
> AsString(pGCEntry.ppRefDynMem))
> oLog:Write("Size       : "+NTrim(pGCEntry.nSize))
> oLog:Write("Type       : "+GCVarType(pGCEntry.nVarType))
> oLog:Write("Value      : "+Psz2String(@pGCEntry.abValue[1]))
> oLog:Write("---------------------------------------------------------")
> pGCEntry:=pGCEntry+1
> NEXT
> IF !oLog:Close()
> DebugOutput("Error closing GCDumpFile")
> ELSE
> ShellExecute(NULL_PTR, 
> PSZ("OPEN"),String2Psz(oLog:Filename),NULL_PSZ,NULL_PSZ,SW_SHOWNORMAL)
> ENDIF
> ELSE
> DebugOutputNoTrace("Exiting GCDump - all objects destroyed")
> ENDIF
> MemFree(pGCDump)
> gcDumpFileRoot := NULL_STRING // clear global string
>
> DynUnLock()
>
> RETURN
> 


0
Eric
11/26/2005 11:37:12 AM
<g>

It was only 22C here today but the sun shone the whole day and it was 
really nice in the garden.



"Eric Hourant" <ehourant@nospamno-echo-soft.com> wrote in message 
news:43884a84$0$3696$ba620e4c@news.skynet.be:

> Geoff,
>
> Thanks for Jean-Luc.
>
> Greetings from frozen Belgium (-1�C, 20 cm snow).
>
> Eric

0
Geoff
11/26/2005 12:17:11 PM
Geoff,

>>It was only 22C here<<
I hate you  !

;-)


"Geoff Schaller" <geoffxx@softxxwareobjectives.com.au> a �crit dans le 
message de news: 4388521f$1@dnews.tpgi.com.au...
> <g>
>
> It was only 22C here today but the sun shone the whole day and it was 
> really nice in the garden.
>
>
>
> "Eric Hourant" <ehourant@nospamno-echo-soft.com> wrote in message 
> news:43884a84$0$3696$ba620e4c@news.skynet.be:
>
>> Geoff,
>>
>> Thanks for Jean-Luc.
>>
>> Greetings from frozen Belgium (-1�C, 20 cm snow).
>>
>> Eric
> 


0
Eric
11/26/2005 1:15:07 PM
Thanks a lot Eric and Geoff. But Geof, could you tell me what is the
class GCSLogFile ? 

Thank you,
Jean-Luc

0
Jean
11/28/2005 5:01:01 PM
Thanks Willem,

But I need the caption for the shortcut purpose.   &Save for example.


Jean-Luc

0
Jean
11/28/2005 5:01:53 PM
Thanks Eric...

I think that WinPrest will be improved in 2.7 if I find the trouble !

Jean-Luc

0
Jean
11/28/2005 5:03:00 PM
>>what is the class GCSLogFile ? <<
G stands for Geoff
SC stands for Schaller
LogFile is a generic name to write a simple text file with the result.

Geoff tries to make us believe he is the inventor of the log file   ;-)


Eric 


0
Eric
11/28/2005 5:28:56 PM
Eric,
>>>what is the class GCSLogFile ? <<
>G stands for Geoff
>SC stands for Schaller
Backwards ? <s,cr>
Karl
>LogFile is a generic name to write a simple text file with the result.
>
>Geoff tries to make us believe he is the inventor of the log file   ;-)
>
>
>Eric 
>
0
Karl
11/28/2005 5:46:31 PM
Eric,

I suspected something like that but I still don't know from what class
inherit this one... Write is a methode of the console class... but I
don't find any other class fo that...
Ok I finaly rewrite a similar class to manage that and now here the
file created:


Active references to dynamic memory: 17
---------------------------------------------------------

Created by : Compiler
Dyn.Addr.  : 0x04DE09F4 Ref: 0x02B6D030
Size       : 56
Value      : {(0x0038)0x04DE09F4} CLASS APP
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE1AA8 Ref: 0x100B44B8
Size       : 292
Value      : {(0x0124)0x04DE1AA8} CLASS STANDARDSHELLWINDOW
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5EEC
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5F1C
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5F4C
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5F7C
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5FAC
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5FDC
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FE8C
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FEBC
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FEEC
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FF1C
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FF4C
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FF7C
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FFAC
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FFDC
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE6014
Size       : 40
Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU

But I don't know if it's good or not ??


Jean-Luc

0
Jean
11/28/2005 7:37:33 PM
Geof,

I have had a 5333 now, and here is the log file generated when leaving:

Active references to dynamic memory: 2
---------------------------------------------------------

Created by : Compiler
Dyn.Addr.  : 0x045109F4 Ref: 0x0129D030
Size       : 56
Value      : {(0x0038)0x045109F4} CLASS APP
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x045116AC Ref: 0x100B44B8
Size       : 292
Value      : {(0x0124)0x045116AC} CLASS STANDARDSHELLWINDOW
---------------------------------------------------------

What can be wrong here ?

I provide also my Queryclose Method:

METHOD QueryClose(oEvent) CLASS StandardShellWindow

	LOCAL lAllowClose AS LOGIC
	LOCAL oserver AS OBJECT
	MEMVAR cnumcol,m_path
	MEMVAR M_SOCPATH,otrad

	lAllowClose := SUPER:QueryClose(oEvent)

	// Kill the timer
	SELF:RegisterTimer(0)

	// un-log the worker
	oserver:=collabor{}
	oserver:setorder(1)
	oserver:seek(cnumcol)
	IF !oserver:eof
		J_LOCKR(oserver,SELF)
		oserver:userIN:=FALSE
		J_COMUNLOCK(oserver,SELF)
	ENDIF
	oserver:close()

	// un-log the user
	oserver:=user{}
	DO WHILE !oserver:eof
		IF AllTrim(AsString(oserver:user)) == AllTrim(AsString(NetName()))
			J_LOCKR(oserver,SELF)
			oserver:userEROR:=FALSE
			oserver:userIN:=FALSE
			J_COMUNLOCK(oserver,SELF)
		ENDIF
		oserver:skip()
	ENDDO
	oserver:close()

	// if asked synchronize the file on the local drive
	IF READINI("SYNCHRO",M_SOCPATH+"gp.ini")=="O" .and.
M_PATH<>M_SOCPATH+"SYNCHRO\"
		igsynchro()
	ENDIF

	// save combobox print size (in the toolbar)
	WRITEINI("COMBOPRINTSIZE",M_SOCPATH+"WINPOS.INI",NTrim(SELF:oCB:size:width))

	// otrad is a MEMVAR object. This is the dbserver with the translation
	otrad:commit()
	otrad:close()

	RETURN lAllowClose

Am i doing something wrong ?

Jean-Luc

0
Jean
11/28/2005 8:01:56 PM
Geof, Eric,

I ask you an advice:

METHOD Start() CLASS app
local oWin as StandardShellWindow
local ofile as myfile

oWin:=StandardShellWindow{self}
oWin:show()

ofile:=myfile{}
.....
.....
ofile:close()

// Must I add this ?
ofile:=NULL_OBJECT

Self:Exec()

// Must I add this ?
oWin:=NULL_OBJECT


Because with the showdump of Geof, all these variables stay open...
It seems (I touch wood here) that I don't have the error...; I Pray
8-)))


Jean-Luc

0
Jean
11/28/2005 8:26:40 PM
J-L,

Firstly, you do a lot of things in this method (function calls etc) that 
could do anything so I don't really know - they pass in references to 
the shell, for example. Why not make those function calls server class 
methods?

Secondly, this is an abuse of the QueryClose concept <g>. All of this 
kind of code belongs in the Close() method. In your case lAllowClose is 
only ever TRUE.

Thirdly, this is not the important code. It's the Function Start and 
Method Start that matter the most.

Fourthly, having Class App show in your GC Dump probably doesn't matter 
because I suspect it still exists when you write your dump. So this 
could also be true for the shellwindow.

Fifth, get in the habit of subclassing all classes you use so that you 
can isolate your added behaviour from default baheviour. It makes it a 
lot easier to fault-find.

So we need to see the point where the 5333 happens, not your QueryClose.

Geoff


"Jean-Luc Stassen" <jls@igsoft.be> wrote in message 
news:1133208116.748045.284160@g43g2000cwa.googlegroups.com:

> Geof,
>
> I have had a 5333 now, and here is the log file generated when leaving:
>
> Active references to dynamic memory: 2
> ---------------------------------------------------------
>
> Created by : Compiler
> Dyn.Addr.  : 0x045109F4 Ref: 0x0129D030
> Size       : 56
> Value      : {(0x0038)0x045109F4} CLASS APP
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x045116AC Ref: 0x100B44B8
> Size       : 292
> Value      : {(0x0124)0x045116AC} CLASS STANDARDSHELLWINDOW
> ---------------------------------------------------------
>
> What can be wrong here ?
>
> I provide also my Queryclose Method:
>
> METHOD QueryClose(oEvent) CLASS StandardShellWindow
>
> LOCAL lAllowClose AS LOGIC
> LOCAL oserver AS OBJECT
> MEMVAR cnumcol,m_path
> MEMVAR M_SOCPATH,otrad
>
> lAllowClose := SUPER:QueryClose(oEvent)
>
> // Kill the timer
> SELF:RegisterTimer(0)
>
> // un-log the worker
> oserver:=collabor{}
> oserver:setorder(1)
> oserver:seek(cnumcol)
> IF !oserver:eof
> J_LOCKR(oserver,SELF)
> oserver:userIN:=FALSE
> J_COMUNLOCK(oserver,SELF)
> ENDIF
> oserver:close()
>
> // un-log the user
> oserver:=user{}
> DO WHILE !oserver:eof
> IF AllTrim(AsString(oserver:user)) == AllTrim(AsString(NetName()))
> J_LOCKR(oserver,SELF)
> oserver:userEROR:=FALSE
> oserver:userIN:=FALSE
> J_COMUNLOCK(oserver,SELF)
> ENDIF
> oserver:skip()
> ENDDO
> oserver:close()
>
> // if asked synchronize the file on the local drive
> IF READINI("SYNCHRO",M_SOCPATH+"gp.ini")=="O" .and.
> M_PATH<>M_SOCPATH+"SYNCHRO\"
> igsynchro()
> ENDIF
>
> // save combobox print size (in the toolbar)
> WRITEINI("COMBOPRINTSIZE",M_SOCPATH+"WINPOS.INI",NTrim(SELF:oCB:size:width))
>
> // otrad is a MEMVAR object. This is the dbserver with the translation
> otrad:commit()
> otrad:close()
>
> RETURN lAllowClose
>
> Am i doing something wrong ?
>
> Jean-Luc

0
Geoff
11/28/2005 8:34:50 PM
J-L,

I just have my own log file class. I didn't like the VO one so I adapted 
some code I got from this NG some time back:

ACCESS Buffer() CLASS GCSLogFile
	RETURN SELF:sWriteString

CLASS GCSLogFile
	PROTECT ptrHandle		AS PTR 			// ptrHandle f�r das GCSLogFile
	PROTECT sWriteString	AS STRING		// Zu schreibender Buffer
	PROTECT	lMakeCRLF		AS LOGIC		// Automatisches anf�gen von CRLF
	PROTECT	lShDate			AS LOGIC		// Mitschreiben des Datums
	PROTECT	lShTime			AS LOGIC		// Mitschreiben der Zeit
	PROTECT	lOpen			AS LOGIC		// File konnte angelegt bwz ge�ffnet werden
	PROTECT	dwLastError		AS DWORD		// Letzter aufgetretner Fehler
	PROTECT cFileName		AS STRING		// final name computed
	PROTECT junk AS INT
	PROTECT dwMaxReadLen	AS DWORD		// 18/11/04 AJ: Number of chars to read 
per line
METHOD Close CLASS GCSLogFile

	LOCAL lRet := TRUE	AS LOGIC

	IF SELF:lOpen
		// Versuchen wir noch den verdammten Restbuffer ins File zu bringen
		IF !Empty( SELF:sWriteString )
			SELF:Write( SELF:sWriteString )			
		ENDIF
		FCommit(ptrHandle)
		lRet := FClose( ptrHandle )
		IF !lRet
			SELF:dwLastError := DosError()
		ELSE
			SELF:lOpen := FALSE
		ENDIF
	ENDIF

	RETURN lRet


ACCESS IsOpen() CLASS GCSLogFile
	RETURN SELF:lOpen

ACCESS LastError( )   CLASS GCSLogFile
	RETURN SELF:dwLastError

METHOD Write( sString ) CLASS GCSLogFile	

	LOCAL lRet := FALSE  AS LOGIC
	// Zusammensetzen des zu schreibenden Strings
	Default (@sString, "")

	IF SELF:lShDate
		SELF:sWriteString += DToS( Today() ) + " "
	ENDIF	

	IF SELF:lShTime
		SELF:sWriteString += Time() + " "
	ENDIF

	SELF:sWriteString += sString

	IF SELF:lMakeCRLF
		SELF:sWriteString += CRLF
	ENDIF

	// Wir wollen es ja auch hinten anh�ngen
	FSeek( SELF:ptrHandle, 0, FS_END )

	// Und rein in die Datei
	IF FWrite( SELF:ptrHandle, SELF:sWriteString ) == SLen( 
SELF:sWriteString )
		SELF:sWriteString := ""
		lRet := TRUE
	ELSE
		SELF:dwLastError := DosError()
	ENDIF

	RETURN lRet

METHOD Init( sFilename, lAutoCRLF, lDate, lTime, lAdditive, nMaxReadLen) 
CLASS GCSLogFile
	
	LOCAL oGlobal AS GCSGlobalObjectBase

	// Set defaults where required - note we keep appending by default
	Default(@sFilename, gcDumpFileRoot+".log")
	Default(@lAdditive, TRUE)	// append to existing file
	Default(@lAutoCRLF, TRUE)
	Default(@lDate, FALSE)
	Default(@lTime, FALSE)
	Default(@nMaxReadLen, 256)			// 18/11/04 AJ
	
	// put the log file in the errors directory unless a dir is specified
	IF !Instr("\", sFilename)
		oGlobal := GetGlobal()
		sFilename := oGlobal:report_directory + sFilename
	ENDIF

	// Set internal variables
	SELF:dwMaxReadLen := nMaxReadLen	// 18/11/04 AJ
	SELF:lShDate := lDate
	SELF:lShTime := lTime
	SELF:lMakeCRLF := lAutoCRLF
	SELF:cFilename := sFileName

	dwLastError := DosError()

	// Open the file according to selected mode
	DO CASE
	CASE !File( sFileName )
		SELF:ptrHandle := FCreate2( sFileName, FC_NORMAL )
	CASE !lAdditive	// new file anyway
		SELF:ptrHandle := FCreate2( sFileName, FC_NORMAL )
	OTHERWISE
		SELF:ptrHandle := FOpen2( sFileName, FO_READWRITE + FO_SHARED )
	ENDCASE

	// �berpr�fen des �ffnes
	IF SELF:ptrHandle == F_ERROR
		SELF:dwLastError := DosError()
		SELF:lOpen := FALSE
	ELSE
		SELF:lOpen := TRUE
	ENDIF

	RETURN SELF

ACCESS LineCount CLASS GCSLogFile

	LOCAL dwLines AS DWORD
	LOCAL Line AS STRING

	dwLines := 0
	DO WHILE !FEof(SELF:ptrHandle)
		line := FReadLine(SELF:ptrHandle)
		dwLines += 1
	ENDDO
	
	RETURN dwLines
METHOD ReadLine() CLASS GCSLogFile
	
	LOCAL cLine AS STRING
	
	cLine := FReadLine(SELF:ptrHandle, SELF:dwMaxReadLen) 	// 18/11/04 AJ: 
Added dwMaxReadLen
	SELF:dwLastError := DosError()
	
	RETURN cLine
	
METHOD GoTop() CLASS GCSLogFile
	FRewind(SELF:ptrHandle)
	RETURN NIL
METHOD GoBottom() CLASS GCSLogFile
	FSeek(SELF:ptrHandle, 0, FS_END)
	RETURN NIL
ACCESS Eof CLASS GCSLogFile
	RETURN FEof(SELF:ptrHandle)
ACCESS FileName CLASS GCSLogFile
	RETURN cFilename

ACCESS Size CLASS GCSLogFile
	
	LOCAL nSize AS INT
	
	FSeek(SELF:ptrHandle, 0, FS_SET)				// rewind
	nSize := FSeek(SELF:ptrHandle, 0, FS_END) 		// go to end
	
	RETURN nSize
METHOD Seek(nOffset, nStart) CLASS GCSLogFile

	// returns logical not EOF as an indicator the seek worked	
	Default(@nStart, FS_RELATIVE)
	
	FSeek(SELF:ptrHandle, nOffset, nStart)
	
	RETURN !FEof(SELF:ptrHandle)
METHOD WriteLine(sString) CLASS GCSLogFile	

	LOCAL lRet := FALSE  AS LOGIC
	// Write and append a CRLF regardless, nodate/times etc
	Default (@sString, "")

	// Wir wollen es ja auch hinten anh�ngen
	FSeek( SELF:ptrHandle, 0, FS_END )

	// Und rein in die Datei
	IF FWriteLine(SELF:ptrHandle, sString ) == SLen(sString)
		lRet := TRUE
	ELSE
		SELF:dwLastError := DosError()
	ENDIF

	RETURN lRet


0
Geoff
11/28/2005 8:37:54 PM
J-L,

Normally you would not need to null_object these things but again, we 
don't know what they do. It might help clear the objects sooner I guess. 
I also noticed earlier that you use memvars (you shouldn't - switch to 
globals or ivars on the app class or something) but thshouldn't have an 
effect on the outcome.

So what is oFile and why are you doing stuff here in the Start method? 
Couldn't this be better handled as a process (method) of the shell 
window class? Its all easier to trace what is going on.

Geoff

"Jean-Luc Stassen" <jls@igsoft.be> wrote in message 
news:1133209600.544358.49490@g43g2000cwa.googlegroups.com:

> Geof, Eric,
>
> I ask you an advice:
>
> METHOD Start() CLASS app
> local oWin as StandardShellWindow
> local ofile as myfile
>
> oWin:=StandardShellWindow{self}
> oWin:show()
>
> ofile:=myfile{}
> ....
> ....
> ofile:close()
>
> // Must I add this ?
> ofile:=NULL_OBJECT
>
> Self:Exec()
>
> // Must I add this ?
> oWin:=NULL_OBJECT
>
>
> Because with the showdump of Geof, all these variables stay open...
> It seems (I touch wood here) that I don't have the error...; I Pray
> 8-)))
>
>
> Jean-Luc

0
Geoff
11/28/2005 8:43:04 PM
Which class uses emptyshellmenu???? <g>
I can guess.

So the menu is not destroying but it is reloading multiple times. How 
might this come about?

Geoff


"Jean-Luc Stassen" <jls@igsoft.be> wrote in message 
news:1133206653.736598.22410@g44g2000cwa.googlegroups.com:

> Eric,
>
> I suspected something like that but I still don't know from what class
> inherit this one... Write is a methode of the console class... but I
> don't find any other class fo that...
> Ok I finaly rewrite a similar class to manage that and now here the
> file created:
>
>
> Active references to dynamic memory: 17
> ---------------------------------------------------------
>
> Created by : Compiler
> Dyn.Addr.  : 0x04DE09F4 Ref: 0x02B6D030
> Size       : 56
> Value      : {(0x0038)0x04DE09F4} CLASS APP
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE1AA8 Ref: 0x100B44B8
> Size       : 292
> Value      : {(0x0124)0x04DE1AA8} CLASS STANDARDSHELLWINDOW
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5EEC
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5F1C
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5F4C
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5F7C
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5FAC
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE5FDC
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FE8C
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FEBC
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FEEC
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FF1C
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FF4C
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FF7C
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FFAC
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x0466FFDC
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x04DE2A20 Ref: 0x07FE6014
> Size       : 40
> Value      : {(0x0028)0x04DE2A20} CLASS EMPTYSHELLMENU
>
> But I don't know if it's good or not ??
>
>
> Jean-Luc

0
Geoff
11/28/2005 8:45:10 PM
Jean-Luc,
Geoff is right. The QueryClose method is just there to answer the question 
"do you agree to close the window ?".
Imagine that your Super:QueryClose method replies false. So you are going to 
kill the timer, unlock the user and all your stuff. But your window is still 
open.
So you try to close it another time and ask a new QueryClose and try to 
rekill the timer and to re-unlock the user ....

I do not say this is THE cause to your 5333 but this can one of the reason 
to have it.

Another point : in your QueryClose method :
LOCAL oserver AS OBJECT
....
oserver:=collabor{}

Why do you declare oServer as an object and not a dbserver or a dataserver ?

Also after an oserver:close(), I always set oServer :=null_object. I do not 
know if this can help the GC but it cannot hurt it.

I think that one of the diffrence between 2.5 (the version you are using) 
and the 2.7 is that the 5333 are shown faster.

Read the excellent Geoff article about 5333 and you will understand better 
how this can happen.

HTH

Eric

"Jean-Luc Stassen" <jls@igsoft.be> a �crit dans le message de news: 
1133208116.748045.284160@g43g2000cwa.googlegroups.com...
> Geof,
>
> I have had a 5333 now, and here is the log file generated when leaving:
>
> Active references to dynamic memory: 2
> ---------------------------------------------------------
>
> Created by : Compiler
> Dyn.Addr.  : 0x045109F4 Ref: 0x0129D030
> Size       : 56
> Value      : {(0x0038)0x045109F4} CLASS APP
> ---------------------------------------------------------
> Created by : RegisterKid()
> Dyn.Addr.  : 0x045116AC Ref: 0x100B44B8
> Size       : 292
> Value      : {(0x0124)0x045116AC} CLASS STANDARDSHELLWINDOW
> ---------------------------------------------------------
>
> What can be wrong here ?
>
> I provide also my Queryclose Method:
>
> METHOD QueryClose(oEvent) CLASS StandardShellWindow
>
> LOCAL lAllowClose AS LOGIC
> LOCAL oserver AS OBJECT
> MEMVAR cnumcol,m_path
> MEMVAR M_SOCPATH,otrad
>
> lAllowClose := SUPER:QueryClose(oEvent)
>
> // Kill the timer
> SELF:RegisterTimer(0)
>
> // un-log the worker
> oserver:=collabor{}
> oserver:setorder(1)
> oserver:seek(cnumcol)
> IF !oserver:eof
> J_LOCKR(oserver,SELF)
> oserver:userIN:=FALSE
> J_COMUNLOCK(oserver,SELF)
> ENDIF
> oserver:close()
>
> // un-log the user
> oserver:=user{}
> DO WHILE !oserver:eof
> IF AllTrim(AsString(oserver:user)) == AllTrim(AsString(NetName()))
> J_LOCKR(oserver,SELF)
> oserver:userEROR:=FALSE
> oserver:userIN:=FALSE
> J_COMUNLOCK(oserver,SELF)
> ENDIF
> oserver:skip()
> ENDDO
> oserver:close()
>
> // if asked synchronize the file on the local drive
> IF READINI("SYNCHRO",M_SOCPATH+"gp.ini")=="O" .and.
> M_PATH<>M_SOCPATH+"SYNCHRO\"
> igsynchro()
> ENDIF
>
> // save combobox print size (in the toolbar)
> WRITEINI("COMBOPRINTSIZE",M_SOCPATH+"WINPOS.INI",NTrim(SELF:oCB:size:width))
>
> // otrad is a MEMVAR object. This is the dbserver with the translation
> otrad:commit()
> otrad:close()
>
> RETURN lAllowClose
>
> Am i doing something wrong ?
>
> Jean-Luc
> 


0
Eric
11/28/2005 10:19:22 PM
Geoff,

I have found the problem with the menu. The menu is reloaded when
changing language or modifying access to some under-menu.
I have something like that:
	// re-shower la shell si on change de langue
	IF M_LANGUE<>M_LANGUE_START
		SELF:Menu:Destroy()
		SELF:Menu := EmptyShellMenu{ SELF }

I have add the destroy method, and now I only have one instance of the
menu. Good.

But for my start method... it's a long long method.... 714 lines !
Because I do a lot a things there... check user entry, check
installation code...

Do you suggest I must put all that code in a method of the
standardshell window and call it from the start method ?

NB: This the my last dump

Active references to dynamic memory: 3
---------------------------------------------------------

Created by : Compiler
Dyn.Addr.  : 0x04510D30 Ref: 0x0129D030
Size       : 56
Value      : {(0x0038)0x04510D30} CLASS APP
---------------------------------------------------------
Created by : Compiler
Dyn.Addr.  : 0x04510D30 Ref: 0x0012FF8C
Size       : 56
Value      : {(0x0038)0x04510D30} CLASS APP
---------------------------------------------------------
Created by : RegisterKid()
Dyn.Addr.  : 0x045121B4 Ref: 0x100B44B8
Size       : 292
Value      : {(0x0124)0x045121B4} CLASS STANDARDSHELLWINDOW
---------------------------------------------------------

I miss still some function to make your ShowGCDump() function working:

DebugOutputNoTrace
DebugOutput
GCVarType
GCSGlobalObjectBase

I have found workaround to make it working...  But it will be better
with these functions too...


Thank you for your help ? 

Jean-Luc

0
Jean
11/28/2005 10:32:11 PM
8-) ...Oops Geoff, please understand: "Thank you for your help !"  and
not "Thank you for your help ?"

11:34 pm.... not so late for programmers !
Jean-Luc

0
Jean
11/28/2005 10:35:15 PM
Geoff,

Why I use MEMVAR  ? Because I need them in some DLL or Libraries... Is
there any other way ? GLOBAL are note visible in a library, only MEMVAR
can do that...

Am I wrong ?

Jean-Luc

0
Jean
11/28/2005 10:54:16 PM
Yes you are wrong <g>

Firstly I would contemplate subclassing your app object and putting your 
'globals' in there as ivars. It is easy to get the app object anywhere 
in your app if you create your own Function Start() and use the 
following lines:

		oApp := GCSApp{}
		__SetAppObject(oApp)
		SetGCSAppObject(oApp)
		oApp:Start()
		// clear the application object and null the global holding it
		oApp := NULL_OBJECT
		__SetAppObject(NULL_OBJECT)
		SetGCSAppObject(NULL_OBJECT)
		WCDCClear()

This code then allows you employ your own app class throughout and 
strongly typed to your class name.

Inco conjunction with this (or alternately) you can use a global from a 
DDLL like this:

FUNCTION GetGCSAppObject() AS GCSApp
	RETURN goApp
STATIC GLOBAL goApp AS GCSApp
FUNCTION SetGCSAppObject(oApp)
	goApp := oApp
	RETURN NIL

Instead of the app object you could create a global object class and 
treat it the same way. If you don't like the functional approach you can 
always use SysObject{} to store and retrieve your global object class.

Geoff


"Jean-Luc Stassen" <jls@igsoft.be> wrote in message 
news:1133218456.058293.266350@g43g2000cwa.googlegroups.com:

> Geoff,
>
> Why I use MEMVAR  ? Because I need them in some DLL or Libraries... Is
> there any other way ? GLOBAL are note visible in a library, only MEMVAR
> can do that...
>
> Am I wrong ?
>
> Jean-Luc

0
Geoff
11/28/2005 11:27:09 PM
J-L,

Good... progress <g>.

Now, your 714 lines in the start <sigh... bg>. Yes, break them up into 
functional groups and make them method calls in your shell class. I 
think this is best.

> DebugOutputNoTrace
> DebugOutput
> GCVarType
> GCSGlobalObjectBase

Well you can just comment out the use of these things, they are for 
debugging but here is the code if you are interested:

FUNCTION DebugOutput()

	LOCAL dwN, dwCount, dwActivation AS DWORD
	LOCAL uValue AS USUAL
	LOCAL cProcName, cOutput AS STRING

	dwCount := PCount()
	uValue := _GETFPARAM(1)
	cProcName := ProcName(0)

	IF cProcName = "DEBUG"
		dwActivation := 1			// debug is on in this module
		cProcName := ProcName(1)
		IF cProcName = "DEBUG"
			dwActivation := 2		// debug is on another debug function calling this 
one
		ENDIF
	ELSE
		dwActivation := 0
	ENDIF
	cOutput := ProcName(dwActivation) + " Line:" + 
StrZero(ProcLine(dwActivation),4)+", " + AsString(uValue)

	IF !IsNil(uValue)
		FOR dwN := 2 UPTO dwCount
			uValue := _GETFPARAM(dwN)
			IF IsObject(uValue)
				uValue := ClassName(uValue)
			ENDIF
			cOutput += ", " + AsString(uValue)
		NEXT
		// OutputDebugString() crashes for string lengths somewhere around 250 
chars
		IF SLen(cOutput) > 240
			cOutput := Left(cOutput, 240) + "..."
		ENDIF
	ENDIF

	_DebOut32(String2Psz(cOutput))		// allows use whilst in the IDE

	RETURN NIL

FUNCTION DebugOutputNoTrace()

	LOCAL cOutput AS STRING
	LOCAL nN, nCount AS DWORD
	LOCAL uValue AS USUAL
	
	nCount := PCount()
	uValue := _GETFPARAM(1)

	IF !IsNil(uValue)
		cOutput := AsString(uValue)
		FOR nN := 2 UPTO nCount
			uValue := _GETFPARAM(nN)
			IF IsObject(uValue)
				IF uValue = NULL_OBJECT	
					uValue := "NULL_OBJECT"
				ELSE
					uValue := ClassName(uValue)
				ENDIF
			ENDIF
			cOutput += ", " + AsString(uValue)
		NEXT
		// OutputDebugString() crashes for string lengths somewhere around 250 
chars
		IF SLen(cOutput) > 240
			cOutput := Left(cOutput, 240) + "..."
		ENDIF
		_DebOut32(String2Psz(cOutput))		// allows use whilst in the IDE
	ENDIF

	RETURN NIL

FUNCTION GCVarType( nType AS DWORD ) AS STRING STRICT
	
	LOCAL cRet AS STRING

	// using this function stops the ShowGCDump reporting the array it uses
    DO CASE
    	CASE nType = 3
			cRet := "FLOAT"
    	CASE nType = 5
			cRet := "ARRAY"
    	CASE nType = 6
			cRet := "OBJECT"
    	CASE nType = 7
			cRet := "STRING"
    	OTHERWISE
			cRet := "*****"
    ENDCASE

	RETURN cRet

	

0
Geoff
11/28/2005 11:33:57 PM
Jean-Luc

Jean-Luc Stassen wrote:
> Geoff,
> 
> Why I use MEMVAR  ? Because I need them in some DLL or Libraries... Is
> there any other way ? GLOBAL are note visible in a library, only MEMVAR
> can do that...
> 
> Am I wrong ?
> 


Very much so.

You are correct i8n that globals, very frequently, have scoping issues 
within foreign DLLs and libraries. They are best avoided.

Imstead, one of the more effective methods of addressing the issue of 
so-called global variables is to consider them in a more object oriented 
manner - they are "global" within the context of the application, aren't 
they?

And your application has an App class, doesn't it?

Subclass the App class, make your "globals" properties of the app class, 
wrap the GetAppObject() function to get around its strong typing, and 
these problems just go away, never, ever to be seen again.

And you should have lots of examples of this stuff; just look at some of 
the samples in your samples directory. There's heaps of them; you just 
need to explore.


-- 
g.
Gary Stark
gstark@RedbacksWeb.com
http://www.RedbacksWeb.com
0
Gary
11/29/2005 12:15:08 AM
Geoff,

Interesting response from you. I note that you're advocating the App 
Object approach as the first choice, in preference to the use of the 
System Object.

What's prompted this change in your PoV?



Geoff Schaller wrote:
> Yes you are wrong <g>
> 
> Firstly I would contemplate subclassing your app object and putting your 
> 'globals' in there as ivars. It is easy to get the app object anywhere 
> in your app if you create your own Function Start() and use the 
> following lines:
> 
>         oApp := GCSApp{}
>         __SetAppObject(oApp)
>         SetGCSAppObject(oApp)
>         oApp:Start()
>         // clear the application object and null the global holding it
>         oApp := NULL_OBJECT
>         __SetAppObject(NULL_OBJECT)
>         SetGCSAppObject(NULL_OBJECT)
>         WCDCClear()
> 
> This code then allows you employ your own app class throughout and 
> strongly typed to your class name.
> 
> Inco conjunction with this (or alternately) you can use a global from a 
> DDLL like this:
> 
> FUNCTION GetGCSAppObject() AS GCSApp
>     RETURN goApp
> STATIC GLOBAL goApp AS GCSApp
> FUNCTION SetGCSAppObject(oApp)
>     goApp := oApp
>     RETURN NIL
> 
> Instead of the app object you could create a global object class and 
> treat it the same way. If you don't like the functional approach you can 
> always use SysObject{} to store and retrieve your global object class.
> 
> Geoff
> 
> 
> "Jean-Luc Stassen" <jls@igsoft.be> wrote in message 
> news:1133218456.058293.266350@g43g2000cwa.googlegroups.com:
> 
>> Geoff,
>>
>> Why I use MEMVAR  ? Because I need them in some DLL or Libraries... Is
>> there any other way ? GLOBAL are note visible in a library, only MEMVAR
>> can do that...
>>
>> Am I wrong ?
>>
>> Jean-Luc
> 
> 


-- 
g.
Gary Stark
gstark@RedbacksWeb.com
http://www.RedbacksWeb.com
0
Gary
11/29/2005 12:17:40 AM
Gary,

Functionally I have no preference but you and a few others seem to 
favour the app object. Hence, if we're offering advice to others its 
conceptually simpler for the correspondent to see a more united front. 
Hence I've shelved my earlier preference for SysObject with AppObject.

I still like SysObject but we are now writing lots of little stand-alone 
tools that have nothing but an exe. In this case, it is definitely 
easier to just add the app object approach. Also, as we now always have 
a subclassed app object, SysObject becomes a redundancy. Its more self 
contained.

Hence my change of direction.

Cheers,

Geoff



"Gary Stark" <bogusemail@yahoo.com> wrote in message 
news:3v1l28F13ir59U1@individual.net:

> Geoff,
>
> Interesting response from you. I note that you're advocating the App
> Object approach as the first choice, in preference to the use of the
> System Object.
>
> What's prompted this change in your PoV?
>
>
>
> Geoff Schaller wrote:
>
> > Yes you are wrong <g>
> >
> > Firstly I would contemplate subclassing your app object and putting your
> > 'globals' in there as ivars. It is easy to get the app object anywhere
> > in your app if you create your own Function Start() and use the
> > following lines:
> >
> >         oApp := GCSApp{}
> >         __SetAppObject(oApp)
> >         SetGCSAppObject(oApp)
> >         oApp:Start()
> >         // clear the application object and null the global holding it
> >         oApp := NULL_OBJECT
> >         __SetAppObject(NULL_OBJECT)
> >         SetGCSAppObject(NULL_OBJECT)
> >         WCDCClear()
> >
> > This code then allows you employ your own app class throughout and
> > strongly typed to your class name.
> >
> > Inco conjunction with this (or alternately) you can use a global from a
> > DDLL like this:
> >
> > FUNCTION GetGCSAppObject() AS GCSApp
> >     RETURN goApp
> > STATIC GLOBAL goApp AS GCSApp
> > FUNCTION SetGCSAppObject(oApp)
> >     goApp := oApp
> >     RETURN NIL
> >
> > Instead of the app object you could create a global object class and
> > treat it the same way. If you don't like the functional approach you can
> > always use SysObject{} to store and retrieve your global object class.
> >
> > Geoff
> >
> >
> > "Jean-Luc Stassen" <jls@igsoft.be> wrote in message
> > news:1133218456.058293.266350@g43g2000cwa.googlegroups.com:
> >
>
> >> Geoff,
> >>
> >> Why I use MEMVAR  ? Because I need them in some DLL or Libraries... Is
> >> there any other way ? GLOBAL are note visible in a library, only MEMVAR
> >> can do that...
> >>
> >> Am I wrong ?
> >>
> >> Jean-Luc
> >
>
> >
>
>
>
> --
> g.
> Gary Stark
> gstark@RedbacksWeb.com
> http://www.RedbacksWeb.com

0
Geoff
11/29/2005 1:33:09 AM
Geoff,

Thanx I was curious.


Geoff Schaller wrote:
> Gary,
> 
> Functionally I have no preference but you and a few others seem to 
> favour the app object. Hence, if we're offering advice to others its 
> conceptually simpler for the correspondent to see a more united front. 
> Hence I've shelved my earlier preference for SysObject with AppObject.
> 
> I still like SysObject but we are now writing lots of little stand-alone 
> tools that have nothing but an exe. In this case, it is definitely 
> easier to just add the app object approach. Also, as we now always have 
> a subclassed app object, SysObject becomes a redundancy. Its more self 
> contained.
> 
> Hence my change of direction.
> 
> Cheers,
> 
> Geoff
> 
> 
> 
> "Gary Stark" <bogusemail@yahoo.com> wrote in message 
> news:3v1l28F13ir59U1@individual.net:
> 
>> Geoff,
>>
>> Interesting response from you. I note that you're advocating the App
>> Object approach as the first choice, in preference to the use of the
>> System Object.
>>
>> What's prompted this change in your PoV?
>>
>>
>>
>> Geoff Schaller wrote:
>>
>> > Yes you are wrong <g>
>> >
>> > Firstly I would contemplate subclassing your app object and putting 
>> your
>> > 'globals' in there as ivars. It is easy to get the app object anywhere
>> > in your app if you create your own Function Start() and use the
>> > following lines:
>> >
>> >         oApp := GCSApp{}
>> >         __SetAppObject(oApp)
>> >         SetGCSAppObject(oApp)
>> >         oApp:Start()
>> >         // clear the application object and null the global holding it
>> >         oApp := NULL_OBJECT
>> >         __SetAppObject(NULL_OBJECT)
>> >         SetGCSAppObject(NULL_OBJECT)
>> >         WCDCClear()
>> >
>> > This code then allows you employ your own app class throughout and
>> > strongly typed to your class name.
>> >
>> > Inco conjunction with this (or alternately) you can use a global from a
>> > DDLL like this:
>> >
>> > FUNCTION GetGCSAppObject() AS GCSApp
>> >     RETURN goApp
>> > STATIC GLOBAL goApp AS GCSApp
>> > FUNCTION SetGCSAppObject(oApp)
>> >     goApp := oApp
>> >     RETURN NIL
>> >
>> > Instead of the app object you could create a global object class and
>> > treat it the same way. If you don't like the functional approach you 
>> can
>> > always use SysObject{} to store and retrieve your global object class.
>> >
>> > Geoff
>> >
>> >
>> > "Jean-Luc Stassen" <jls@igsoft.be> wrote in message
>> > news:1133218456.058293.266350@g43g2000cwa.googlegroups.com:
>> >
>>
>> >> Geoff,
>> >>
>> >> Why I use MEMVAR  ? Because I need them in some DLL or Libraries... Is
>> >> there any other way ? GLOBAL are note visible in a library, only 
>> MEMVAR
>> >> can do that...
>> >>
>> >> Am I wrong ?
>> >>
>> >> Jean-Luc
>> >
>>
>> >
>>
>>
>>
>> -- 
>> g.
>> Gary Stark
>> gstark@RedbacksWeb.com
>> http://www.RedbacksWeb.com
> 
> 


-- 
g.
Gary Stark
gstark@RedbacksWeb.com
http://www.RedbacksWeb.com
0
Gary
11/29/2005 3:02:29 AM
Hi Jean-Luc,

just a quick question, does your start function return something ? If not, 
make it return a nil or a zero. I remember, that there was an error in the 
stub code which expects that the start function return something. If nothing 
was returned and accidently somehting is in the registers which is not zero, 
the stub code is trying to access this, which ( sometimes, not always ) lead 
to the 5333 while ending the application.

Regards,
Meinhard

"Jean-Luc Stassen" <jls@igsoft.be> schrieb im Newsbeitrag 
news:1133197380.799910.24420@f14g2000cwb.googlegroups.com...
> Thanks Eric...
>
> I think that WinPrest will be improved in 2.7 if I find the trouble !
>
> Jean-Luc
> 


0
Meinhard
11/29/2005 7:43:19 AM
Reply: