Again I come with a problem I can't solve. I know it has already been
discussed here, but I don't find any solution to the problem.
In My app I have :
METHOD FileExit() CLASS StandardShellWindow
SELF:EndWindow()
RETURN NIL
Called when the user select Quit in the main menu. Then the QueryClose:
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)
//Put your changes here
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()
//
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()
// synchro
IF READINI("SYNCHRO",M_SOCPATH+"gp.ini")=="O" .and.
M_PATH<>M_SOCPATH+"SYNCHRO\"
igsynchro()
ENDIF
// sauvegarde de la dimension du combo box de la toolbar
WRITEINI("COMBOPRINTSIZE",M_SOCPATH+"WINPOS.INI",NTrim(SELF:oCB:size:width))
otrad:commit()
otrad:close()
* SELF:Owner:Quit()
* SELF:Owner:Destroy()
RETURN lAllowClose
All that code works ok, but after that goes here:
SELF:Exec()
oMainPGMWIN :=NULL_OBJECT
oTrad :=NULL_OBJECT
SELF:quit()
RETURN NIL
And the bug come after the NIL on the //End of entity line.
Any suggestion ?
TIA
Jean-Luc
1. Why are you using MEMVARs? GLOBAL variables are better.
2. EndWindow() in FileExit( ) performs the Quit(), so you do not need this
method after Self:Exec().
3. Do not put anything after SELF:Exec( )
3. The two variables you're trying to destroy (NULL...), may have been
already destroyed.
The proper way (I think), if these are global variables, is to use the
INIT2 functionality:
For example:
PROCEDURE InitExit AS VOID PASCAL _INIT2
// Register the exit dispatcher.
_RegisterExit(@ExitMyApp())
RETURN
FUNCTION ExitMyApp( ) AS VOID PASCAL
xVar := NULL_OBJECT
// etc...
RETURN
HTH,
Jamal
"Jean-Luc Stassen" <j...@igsoft.be> wrote in message
news:1129581101....@g43g2000cwa.googlegroups.com...
I agree with Jamal except for one thing. You can put as much code as you
like after the SELF:Exec() but the way you have written your code, it
can't get executed. Just don't call oApp:quit() from anywhere. By all
means close the window you opened in the start method and if you must
quite from within the app, use __Quit() instead.
Geoff
"Jean-Luc Stassen" <j...@igsoft.be> wrote in message
news:1129581101....@g43g2000cwa.googlegroups.com:
I use MEMVAR's because they are accessible in DLL, GLOBAL not (or I
miss something and this is possible 8-))
In the begining, I had nothing after the self:exec(), I had appended
those lines to try to avoid 5333 when leaving the app !
Is the procdure INIT2 automatically called on close ?
Jean-Luc
You can use RegisterExit() to have something execute on shutdown.
To use a globals from a dll, use a function (that way you can also
strongly type it)
Ie... in the DLL
GLOBAL oGlob as xxxx
Function GetGlobal() as xxxx
Return oGlob
Etc
Geoff
"Jean-Luc Stassen" <j...@igsoft.be> wrote in message
news:1129614361.4...@o13g2000cwo.googlegroups.com:
I have removed all after the self:exec(), but the problem is still
there. I must say: I'm remembering that I have a "special" feature to
display an image in the background of the shell window and I suspect
that the problem is there, thus in the init of the standardshell, I
have that:
SetWindowLong( hWndClient, GWL_WNDPROC, LONG( _CAST, @ShellWinProc() )
)
and here is the shellwinproc function:
FUNCTION ShellWinProc( hWnd AS PTR, uMsg AS DWORD, wParam AS DWORD,
lParam AS LONG ) AS LONG _WINCALL
// Replacement WinProc for the Shell only
LOCAL liRetVal AS LONG
LOCAL hDC AS PTR
LOCAL ps IS _WINPAINTSTRUCT
LOCAL lpfnDefaultProc AS PTR
LOCAL oShell AS OBJECT
LOCAL rc IS _WINRECT
LOCAL hNewBrush AS PTR
LOCAL hOldBrush AS PTR
IF hWnd <> NULL_PTR
oShell := SysObject() // pickup my shell window
ENDIF
// Get VO's default window procedure
lpfnDefaultProc := GetClassLong( hWnd, GCL_WNDPROC )
DO CASE
CASE uMsg == WM_PAINT .AND. hWnd = oShell:Handle(4)
hDC := BeginPaint( hWnd, @ps )
GetClientRect( hWnd, @rc )
hNewBrush := CreateSolidBrush( RGB(192,192,192))
hOldBrush := SelectObject( hDC, hNewBrush )
FillRect( hDC, @rc, hNewBrush )
SelectObject( hDC , hOldBrush )
DeleteObject( hNewBrush )
EndPaint( hWnd, @ps )
CASE uMsg == WM_SIZE
// Force a complete repaint for the new size
InvalidateRect( hWnd, NULL_PTR, TRUE )
liRetVal := CallWindowProc( lpfnDefaultProc , hWnd, uMsg, wParam,
lParam )
OTHERWISE
// Let VO's orig WinProc handle the rest of the messages
liRetVal := CallWindowProc( lpfnDefaultProc , hWnd, uMsg, wParam,
lParam )
ENDCASE
RETURN liRetVal
FUNCTION NewClientProc(hwnd AS PTR, uMsg AS DWORD, wParam AS
DWORD,lParam AS LONG) AS LONG _WINCALL
LOCAL LRet AS LONG
LRet := CallWindowProc(pfnOldFunc,hWnd,uMsg,wParam,lParam)
IF uMsg == WM_PAINT
oMainShell:UpdateBG()
ENDIF
IF uMsg == WM_SIZE
oMainShell:UpdateBG()
ENDIF
RETURN Lret
GLOBAL pfnOldFunc
Maybe I must unregister that before leaving... but I don't know how...
Jean-Luc
Many thanks for your precious help.
Jean-Luc