e estou tentando modificá-la para usar com a WVW (GT).Peguei um exemplo de uma errorsys da hmg
Já fiz as seguintes substituições:
1 - Quando apresenta um erro de RUNTIME, aparece para o usuário final uma tela gráfica, na verdade é um boxmessage da API windows com o corpo da mensagem.
2 - Também já cria imediatamente um arquivo de LOG com o mesmo nome do .EXE (somente a parte do nome, a da extensão não me interessa) e o restante do nome .HTM.
Exemplo: digamos que o arquivo .EXE chama-se DEMO.EXE, então o arquivo de LOG será: DEMO-ErrorLog.HTM
3 - Quero implementar algumas opções para o usuário, e, para isso não quero a mensagem do ALERT() (QUE É CONSOLE). Também não serve as mensagens padrões do Windows API. Para isso estou tentando criar um tipo de janela MODAL (como vi no exemplo HMG). As opções que supostamente quero apresentar ao usuário são:
- IMPRIMIR MENSAGEM ERRO
- CRIAR ARQUIVO DE LOG.HTM
- CRIAR ARQUIVO DE LOG.TXT
- ENVIAR EMAIL
- VISUALIZAR O ERRO
- SAIR
Aí que tá pegando... como não entendo ainda 1% de harbour e muito menos suas LIBs. E, como não conheço nenhuma apostila ou guia ou livros, etc, etc... o jeito é pegar os exemplos da pasta \tests e "fuçar" pra ver se sai alguma coisa...
Então os códigos abaixo, já funcionam em parte, os quais tentarei explicar o que "entendi". De repente não é o que V.Sas. (leitores/professores) entendem ou sabem:
1- no lugar de uma errorsys.prg já está integrada as funções que tratam o erro dentro do próprio aplicativo "cobaia":
ErrorBlock( {| e | MyError( e ) } )
No início do MAIN tem esta chamada à função MyError.
2 - a função myerror é bem pequena e contém:
STATIC PROCEDURE MyError( e )
LOCAL i := 1
LOCAL cErr := "Erro durante a execu‡„o do aplicativo (Runtime error)" + hb_eol() + ;
hb_eol() + ;
"Gencode: " + hb_ntos( e:GenCode ) + hb_eol() + ;
"Descri‡„o do Erro: " + e:Description + + hb_eol() + ;
"Sub-sistema: " + hb_ntos( e:SubCode ) + hb_eol() + ;
hb_eol() + ;
"Linha(s) onde ocorreu(ram) o(s) erro(s):" + hb_eol() + ;
hb_eol()
HtmArch := Html_ErrorLog()
cMessage := ErrorMessage( e )
IF ! Empty( e:osCode )
cDOSError := "(DOS Error " + LTrim( Str( e:osCode ) ) + ")"
ENDIF
// "Quit" selected
IF ! Empty( e:osCode )
cMessage += " " + cDOSError
ENDIF
Html_LineText(HtmArch, '<p class="updated">Data:' + Dtoc(Date()) + " " + "Horario: " + Time() )
Html_LineText(HtmArch, cMessage + "</p>" )
n := 2
ai = cmessage + chr(13) + chr (10) + chr(13) + chr (10)
WHILE ! Empty( ProcName( n ) )
xText := "Called from " + ProcName( n ) + "(" + AllTrim( Str( ProcLine( n++ ) ) ) + ")" + hb_eol() // +CHR(13) +CHR(10)
ai = ai + xText
Html_LineText(HtmArch,xText)
ENDDO
Html_Line(HtmArch)
DO WHILE ! Empty( ProcName( ++i ) )
cErr += RTrim( ProcName( i ) ) + "(" + hb_ntos( ProcLine( i ) ) + ")" + hb_eol()
ENDDO
// ? cErr // Calls quit
// ldebug( cErr )
lBoxMsgMyError( cErr )
hb_gtInfo( HB_GTI_INKEYFILTER, NIL )
QUIT
RETURN
3 - a próxima função (onde começa o "póbrema") é chamada pelo nome de ERROMESSAGE(e), dentro da função MyError acima. Vejam por favor:
STATIC FUNCTION ErrorMessage( oError )
LOCAL cMessage
// start error message
cMessage := iif( oError:severity > ES_WARNING, "Erro", "Alerta" ) + " "
// add subsystem name if available
IF ISCHARACTER( oError:subsystem )
cMessage += oError:subsystem()
ELSE
cMessage += "???"
ENDIF
// add subsystem's error code if available
IF ISNUMBER( oError:subCode )
cMessage += "/" + LTrim( Str( oError:subCode ) )
ELSE
cMessage += "/???"
ENDIF
// add error description if available
IF ISCHARACTER( oError:description )
cMessage += " " + oError:description
ENDIF
// add either filename or operation
DO CASE
CASE !Empty( oError:filename )
cMessage += ": " + oError:filename
CASE !Empty( oError:operation )
cMessage += ": " + oError:operation
ENDCASE
// ShowError(oError)
RETURN cMessage
Observem por favor, que a função SHOWERROR(oERROR) está comentada.
Então se ela estiver comentada (como já está) a coisa funciona direitinho (ou quase pois quero um algo mais). Vejam a tela:
No caso do erro acima:
1- está referindo-se a uma variável que não existe. Notem que não aparece o nome dela. Mas, tudo bem dá pra usar;
2 - é um BoxMessage da API do windows, e como não temos opção de botões (só os da API: ok/cancel - yes/no), tanto faz o SIM ou o NÃO são a mesma coisa: encerra o aplicativo;
3 - o arquivo .HTM é gerado com sucesso e com mais informações. Vejam:
Tudo isso, até aqui tá bacana. Feito em harbour 3.4.0 e lib gráfica GTWVW (exemplo DEMO adaptado) e windows 10/64 bits.
Agora se eu descomentar a função ShowError(oError) que a que se idealiza colocar os botões personalizados, etc, etc...
A coisa fica preta, ou melhor, em loop, ao ponto de só poder fechar o aplicativo, ou esperando muito tempo até o windows enviar mensagem "o aplicativo parou de funcionar" ou fechando-o através do "gerenciador de tarefas".
Observem que o conteúdo da função abaixo está com diversas partes comentadas (de propósito), na tentativa desesperada (por não conhecer o harbour nem muito menos a lib GTWVW - apesar de parecer bem simples) de fazer funcionar o que se pretende (como descrito no caput deste tópico).
Claro que ela chama outras funções. Então é muito complexa.
Ou se algum dos professores tiver uma ShowError() com a ideia que aqui propomos, ficaremos todos gratos.
Enfim, vejam o conteúdo da "dita cuja" (que tirei daqui de algum lugar do fórum):
*******************************************
Function ShowError ( oError )
********************************************
LOCAL i, cTelaErro, cMsg_e
LOCAL nCurWindow, GetList := {}
// LOCAL cLabel := "EXVD - Excluir Presta‡”es Antigas"
LOCAL cLabel := "Ops... Erro na Execu‡„o do Aplicativo!"
LOCAL nTop := 4
LOCAL nLeft := 4
LOCAL nBottom := 21
LOCAL nRight := 75
LOCAL nColGet := 8
LOCAL nCursor := SetCursor( SC_NORMAL )
PRIVATE vRichedit1
PRIVATE oRichedit1, oButton1, oButton2, oButton3, oButton4
/*
// MEMVAR __temp__
IF ( nCurWindow := wvw_nOpenWindow( "EXVD - Erro Durante a Execu‡„o do Aplicativo (Run-Time Error)", nTop, nLeft, nBottom, nRight ) ) == 0
lboxmessage( "Ops! Falha na Cria‡„o Desta Tela. Tente Novamente Mais Tarde!" + hb_eol() + "Caso o Problema Persista, Favor Informar … MVinfo Sistemas & Automa‡„o para a Solu‡„o do Problema!!" )
RETURN
ENDIF
// clear typeahead
ResetMiscObjects( nCurWindow )
AddMiscObjects( nCurWindow, {| nWindow | wvw_DrawLabel( nWindow, 1, nRight - nLeft - 4, cLabel, 2,, WIN_RGB( 255, 255, 255 ), WIN_RGB( 198, 198, 198 ), "Arial", s_afontinfo[ 2 ], , , , , .T., .T. ) } )
AddMiscObjects( nCurWindow, {| nWindow | wvw_DrawBoxGroup( nWindow, 10 - nTop, 10 - nLeft, 16 - nTop, 68 - nLeft ) } )
AddMiscObjects( nCurWindow, {| nWindow | __temp__ := nWindow, AEval( GetList, {| oGet | wvw_DrawBoxGet( __temp__, oGet:Row, oGet:Col, Len( Transform( oGet:VarGet(), oGet:Picture ) ) ) } ) } )
wvwm_ResetMouseObjects( nCurWindow )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Enviar Erro" , 20 , 05 , , , {|| xDebugInfo() } ) )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Ver Arquivo Log" , 20 , 20 , , , {|| xDebugInfo() } ) )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Ver Arquivo HTML", 20 , 40 , , , {|| xDebugInfo() } ) )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Imprimir Erro" , 20 , 60 , , , {|| xDebugInfo() } ) )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Sair" , 21 , 60 , , , {|| xDebugInfo() } ) )
#if 0
// we now use native push button
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Info", MaxRow() - 1, MaxCol() - 15, , , {|| xDebugInfo() } ))
#endif
wvw_pbCreate( nCurWindow, MaxRow() - 1, MaxCol() - 15, MaxRow() - 1, MaxCol() - 5, "Info", , {|| xDebugInfo() } )
************************************************** ACRESCENTADO 15/2/16W ************************
*/
lEmailEnviado := .F.
SETCANCEL(.F.)
SET CURSOR OFF
SET DEVICE TO SCREEN
* MsgBeep()
Tone(1000)
/*
cArq_Log_Erro:=StrTran(Lower(hb_cmdargargv()),".exe","_error.log")
x_body_erro:=""+CRLF
x_body_erro+=" "+ErrorMessage(oError)+CRLF
x_body_erro+=""+CRLF
x_body_erro+=" Date.................: " + DToC( Date() )+" Time: " + Time()+CRLF
x_body_erro+=" Application Name.....: " + hb_cmdargargv()+CRLF
x_body_erro+=" Current Workstation..: " + NetName()+CRLF
x_body_erro+=" Operating System.....: " + OS()+CRLF
x_body_erro+=" Error................: " + ErrorMessage(oError)+CRLF
x_body_erro+=" File.................: " + oError:filename()+CRLF
x_body_erro+=" DOS error code.......: " + strvalue( oError:oscode() )+CRLF
x_body_erro+=""+CRLF
x_body_erro+=" Memory for character..: " + ALLTRIM(STR(MEMORY(0))) + " for Block: " + ALLTRIM(STR(MEMORY(1)))+" for RUN: " + ALLTRIM(STR(MEMORY(2)))+CRLF
x_body_erro+=""+CRLF
*/
cArq_Log_Erro:=StrTran(Lower(hb_ARGV()),".exe","_error.log")
x_body_erro:=""+hb_eol()
x_body_erro+=" "+ErrorMessage(oError)+hb_eol()
x_body_erro+=""+hb_eol()
x_body_erro+=" Data do Erro.............: " + DToC( Date() )+" Hor rio: " + Time()+hb_eol()
x_body_erro+=" Nome do Aplicativo.......: " + hb_ARGV()+hb_eol()
x_body_erro+=" Nome do Computador.......: " + NetName()+hb_eol()
x_body_erro+=" Sistema Operacional......: " + OS()+hb_eol()
x_body_erro+=" Nome Completo do Erro....: " + ErrorMessage(oError)+hb_eol()
x_body_erro+=" Arquivo..................: " + oError:filename()+hb_eol()
x_body_erro+=" C¢digo (DOS Error).......: " + strvalue( oError:oscode() )+hb_eol()
x_body_erro+=""+hb_eol()
x_body_erro+=" Mem¢ria para Caracteres..: " + ALLTRIM(STR(MEMORY(0))) + " Para Blobcos: " + ALLTRIM(STR(MEMORY(1)))+" Para Execu‡„o: " + ALLTRIM(STR(MEMORY(2)))+hb_eol()
x_body_erro+=""+hb_eol()
IF ALIAS() # ""
x_body_erro+=" Tabela (Banco de Dados): " + ALIAS() + " Arquivo NTX/CDX: "+INDEXKEY(INDEXORD())+hb_eol()+""+hb_eol()
ENDIF
x_body_erro+=" Argument: "+hb_eol()+""+hb_eol()
IF VALTYPE(oError:args) == "A"
x_body_erro+=" Array: "+ LTRIM(STR(LEN(oError:args)))+" Elements "+hb_eol()
i := 1
DO WHIL i < 4
x_body_erro+=" Elemen[" + STR(i,2) + "]......: = Type: "+Valtype(oError:args[i])+" Val: "+hb_CStr(oError:args[i])+hb_eol()
IF i == LEN(oError:args)
EXIT
ENDIF
i++
ENDDO
ELSE
x_body_erro+=" "+hb_CStr(oError:args)+hb_eol()+""+hb_eol()
ENDIF
x_body_erro+=" Traget¢ria do Erro:"+hb_eol()
x_body_erro+=" -------------------"+hb_eol()
i := 3
while ( !Empty(ProcName(i)) )
x_body_erro+=" Called from: " + Trim(ProcName(i)) + "(" + ALLTRIM(STR(ProcLine(i))) + ") - "+Subs(ProcFile(i),RAT("/",ProcFile(i))+1)+hb_eol()
i++
end
cCod_erro:=RTRIM(oError:subSystem)+'/'+LTRIM(STR(oError:subCode))
if left(cCod_erro,1)=='/'
cCod_erro:=SUBS(cCod_erro,2)
endif
IF FILE("ERROR.DBF")
USE ERROR EXCLUSIVE NEW
e_x_t:=ORDBAGEXT()
IF e_x_t=".CDX"
IF !FILE("ERROR.CDX")
INDEX ON CODE_ER TAG INDEX1 TO ERROR
ENDIF
ELSE
IF !FILE("ERROR.NTX")
INDEX ON CODE_ER TO ERROR
ENDIF
ENDIF
USE
USE ERROR SHARED NEW
SET INDEX TO ERROR
GO TOP
SEEK cCod_erro
cType_:=""
IF FOUND()
DO WHILE cCod_erro=ALLTRIM(CODE_ER)
IF cType_!=TYPE_ER
x_body_erro+=""+CRLF
cType_:=TYPE_ER
IF cType_=="C"
x_body_erro+=" Descri‡„o do Erro:"+hb_eol()
ELSE
x_body_erro+=" A‡„o:"+hb_eol()
ENDIF
ENDIF
x_body_erro+=" "+MESSAGE_ER+hb_eol()
SKIP
ENDDO
x_body_erro+=""+hb_eol()
ENDIF
USE
ENDIF
IF oError:osCode # 4
nHandle := FCreate( cArq_Log_Erro, 0 )
IF nHandle < 3
nHandle := FCreate( cArq_Log_Erro, 0 )
ENDIF
IF nHandle < 3
ELSE
FWrite( nHandle, x_body_erro )
ENDIF
FClose( nHandle )
ENDIF
// MEMVAR __temp__
IF ( nCurWindow := wvw_nOpenWindow( "EXVD - Erro Durante a Execu‡„o do Aplicativo (Run-Time Error)", nTop, nLeft, nBottom, nRight ) ) == 0
lboxmessage( "Ops! Falha na Cria‡„o Desta Tela. Tente Novamente Mais Tarde!" + hb_eol() + "Caso o Problema Persista, Favor Informar … MVinfo Sistemas & Automa‡„o para a Solu‡„o do Problema!!" )
RETURN
ENDIF
// clear typeahead
/*
ResetMiscObjects( nCurWindow )
AddMiscObjects( nCurWindow, {| nWindow | wvw_DrawLabel( nWindow, 1, nRight - nLeft - 4, cLabel, 2,, WIN_RGB( 255, 255, 255 ), WIN_RGB( 198, 198, 198 ), "Arial", s_afontinfo[ 2 ], , , , , .T., .T. ) } )
AddMiscObjects( nCurWindow, {| nWindow | wvw_DrawBoxGroup( nWindow, 10 - nTop, 10 - nLeft, 16 - nTop, 68 - nLeft ) } )
AddMiscObjects( nCurWindow, {| nWindow | __temp__ := nWindow, AEval( GetList, {| oGet | wvw_DrawBoxGet( __temp__, oGet:Row, oGet:Col, Len( Transform( oGet:VarGet(), oGet:Picture ) ) ) } ) } )
wvwm_ResetMouseObjects( nCurWindow )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Enviar Erro" , 20 , 05 , , , {|| xDebugInfo() } ) )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Ver Arquivo Log" , 20 , 20 , , , {|| xDebugInfo() } ) )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Ver Arquivo HTML", 20 , 40 , , , {|| xDebugInfo() } ) )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Imprimir Erro" , 20 , 60 , , , {|| xDebugInfo() } ) )
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Sair" , 21 , 60 , , , {|| xDebugInfo() } ) )
#if 0
// we now use native push button
wvwm_AddMouseObjects( nCurWindow, WVWMouseButton():New( "Info", MaxRow() - 1, MaxCol() - 15, , , {|| xDebugInfo() } ))
#endif
wvw_pbCreate( nCurWindow, MaxRow() - 1, MaxCol() - 15, MaxRow() - 1, MaxCol() - 5, "Info", , {|| xDebugInfo() } )
************************************************** ACRESCENTADO 15/2/16W ************************
*/
/*
inkey(0)
cls
*/
// @ 02 - nTop, nColGet - nLeft + 04 SAY x_body_erro
fMyModal( 09 , 06 , 14 , 72 , 'EXVD Erro de Execução do Aplicativo! ' , ' Erro de "RuntimeError"' , 'Passe essas informações para a MVinfo Sistemas & Automação ' , ' Desculpe!' , x_body_erro , 'r/w' )
// lBoxMessage(x_body_erro)
/*
// @ 02 - nTop, nColGet - nLeft + 04 SAY "< Per¡odo Inicial para Exclus„o de PRESTA€™ES Baixadas >"
@ 07 - nTop, nColGet - nLeft + 04 SAY "< Per¡odo Final para Exclus„o de PRESTA€™ES Baixadas >"
@ 06 - nTop, nColGet - nLeft + 04 get dDTINIC pict '@D'
*/
/*
@ 22 - nTop, nColGet - nLeft + 04 GET dDTFINL pict '@D'
set conf on
readExit(.t.)
READ
readExit(.f.)
set conf off
*/
/*
if lastkey()= 27
wvw_lCloseWindow()
// restore state
wvwm_ResetMouseObjects( nCurWindow )
ResetMiscObjects( nCurWindow )
SetCursor( nCursor )
return
endif
*/
/*
oMouse := WVWMouseButton():New( "Encerrar Aplicativo", MaxRow() / 2 - 2 , MaxCol() / 2 - ( len ( "Encerrar Aplicativo" ) / 2 ), , , {|| EncerraErro() } )
oMouse:lTight := .T.
wvwm_AddMouseObjects( nCurWindow, oMouse )
oMouse := WVWMouseButton():New( "Export PDF", MaxRow() / 2 + 2 , MaxCol() / 2 - ( len ( "Export PDF" ) / 2 ), , , {|| ExpErrorPDF(cArq_Log_Erro) } )
oMouse:lTight := .T.
wvwm_AddMouseObjects( nCurWindow, oMouse )
oMouse := WVWMouseButton():New( "Imprimir Erro", MaxRow() / 2 + 2 , MaxCol() / 2 - ( len ( "Imprimir Erro" ) / 2 ), , , {|| PrintError(cArq_Log_Erro) } )
oMouse:lTight := .T.
wvwm_AddMouseObjects( nCurWindow, oMouse )
/*
DEFINE WINDOW wndError ;
AT 0, 0 ;
WIDTH 760 ;
HEIGHT 560 ;
TITLE 'Program Error' ;
MODAL ;
NOSYSMENU
@ 5,5 RICHEDITBOX oRichEdit_ers ;
WIDTH 740 ;
HEIGHT 475 ;
VALUE x_body_erro ;
FONT 'Courier New' ;
SIZE 10
@ 490,660 BUTTON Button_1ers ;
CAPTION 'Exit' ;
ACTION {|| wndError.release} ;
WIDTH 80 ;
HEIGHT 28
@ 490,105 BUTTON Button_2ers ;
CAPTION 'Export PDF' ;
ACTION {|| ExpErrorPDF(cArq_Log_Erro)} ;
WIDTH 80 ;
HEIGHT 28
@ 490, 10 BUTTON Button_3ers ;
CAPTION 'Print' ;
ACTION {|| PrintError(cArq_Log_Erro)} ;
WIDTH 80 ;
HEIGHT 28
END WINDOW
CENTER WINDOW wndError
ACTIVATE WINDOW wndError
*/
/*
// wait "aguardando..."
// inkey(0)
// epilogue
lboxmessage( "Desculpe-nos o transtorno! Estamos Trabalhando na Solu‡„o Deste Problema o Quanto Antes!!!" )
wvw_lCloseWindow()
// restore state
wvwm_ResetMouseObjects( nCurWindow )
ResetMiscObjects( nCurWindow )
SetCursor( nCursor )
//
*/
SETCANCEL(.T.)
// SET CURSOR ON
// UnloadAllDll()
dbcloseall()
// ExitProcess(0)
quit
Return Nil
Se alguém, achar interessante a proposta deste tópico, fique à vontade para criticar, comentar, sugerir, alterar, melhorar, corrigir, ensinar, redarguir... enfim, o que puder fazer para ajudar a todos quantos precisarem desta ideia como agora preciso!