Форум » GUI » Вылет из программы... » Ответить

Вылет из программы...

Andrey: Всем привет ! Как можно в МиниГуи программе сделать вызов своих функций при аварийном завершении программы (т.е. при вылете) ? Т.е. хочу сделать сразу после появления MsgBox() вызов 2-3 функций и потом сделать DbCloseAll(). Как это реализовать ? Для чего это нужно, поясню: при входе в свою программу я пишу в базу кто и когда вошел в программу (логин пользователя). И при выходе из программы, стираю этого пользователя из базы. Если программа "вылетает", то юзер числится как работающий. Древнее наследие с клипера, хотел переделать, да так и осталось.

Ответов - 167, стр: 1 2 3 4 5 6 7 8 9 All

Andrey: PSP пишет: Вот и проверяй, что за херня в cFileLog в этот момент содержится. Файл нормальный, ошибки в него печатаю, потом поднимаю: [pre2] IF FILE(cFileLog) cMsg := "Исправьте ошибки и повторите печать заново;" cMsg += "Всего ошибок = " + HB_NtoS( nErr ) + ";;" cMsg += "Список ошибок появиться после этого окна !" MG_Stop( cMsg, "Ошибки печати" ) // функция на базе HMG_Alert() DO EVENTS cMsg := CRLF + "Исправьте ошибки и повторите печать заново !" + CRLF cMsg += "Всего ошибок = " + HB_NtoS( nErr ) STRFILE( cMsg + CRLF, cFileLog, .T. ) DO EVENTS ShellExecute( , 'open', cFileLog, , , SW_SHOWNORMAL) // строка 1437 DO EVENTS ENDIF[/pre2] Блокнот открывает его и показывает ! Почему после открытия блокнота прога валиться ? Почему срабатывает вот этот код после ShellExecute() ? Called from UPPER(0) Called from (b)TCNLDATA(795) in module: h_objects.prg Called from TCNLDATA:DEL(0) Called from (b)TCNLDATA(834) in module: h_objects.prg Called from TCNLDATA:DESTROY(0) Called from TWNDDATA:__msgDestructor(736) in module: h_objects.prg Вот исходник h_objects.prg: [pre2]#ifndef __XHARBOUR__ METHOD PROCEDURE DestroyObject() CLASS TWndData ::Destroy() // строка 736 RETURN #endif[/pre2]

Dima: Andrey пишет: Почему срабатывает вот этот код после ShellExecute() ? ShellExecute ведь не приостанавливает работу программы , поэтому и срабатывает код далее. Или ShellExecute чем то отличается от WAPI_ShellExecute ?

PSP: Так что в переменной cFileLog?


Pasha: Возможно, при вызове ShellExecute вызывается LostFocus для какого-то объекта, внутри LostFocus вызывается Destroy для какого-то объекта, и в этом Destroy уже идет вызов Upper с параметром nil Дополню: при выполнении ShellExecute вызывается (почему - вопрос) Destroy для объекта класса TCnlData, у которого свойство ::cName равно nil.

Andrey: PSP пишет: Так что в переменной cFileLog? Имя файла. Файл создаётся нормально. В файле не особо много (20-30) строк. В конце вот эта строка: [pre2] cMsg := CRLF + "Исправьте ошибки и повторите печать заново !" + CRLF cMsg += "Всего ошибок = " + HB_NtoS( nErr ) STRFILE( cMsg + CRLF, cFileLog, .T. ) [/pre2] Она тоже есть.

Andrey: Поставил вместо MG_Stop() обычный: [pre2] MsgStop( cMsg , "Ошибки печати" )[/pre2] Убрал своё окно ошибок. Всё равно вылет после ShellExecute() Вот такое окно: Как исправить данную ситуацию ?

Dima: А вот тут точно Xname должно быть ? [pre2] METHOD Get( xName ) INLINE iif( HB_ISCHAR( xName ), ::oWin:oName:Get( Upper( xName ) ), ; ::oWin:oHand:Get( xName ) ) [/pre2] Может Cname.......

SergKis: Andrey пишет Как исправить данную ситуацию ? Смотреть код, что дальше работает после ShellExecute(). Паша верно указал направление, после ShellExecute() попадаем на Destroy окна (TWndData), идет Destroy контролам (TCnlData) и в списке регистрации на окно контролов по имени и handle получаем nil (Get(xName))

Pasha: Только не после ShellExecute(), а в процессе его выполнения вызывается (по неизвестной причине) Destroy какого-то контрола из Destroy: METHOD Destroy() INLINE ( ::Del(), ; ::oCargo := iif( HB_ISOBJECT( ::oCargo ), ::oCargo:Destroy(), Nil ), ; ::oEvent := iif( HB_ISOBJECT( ::oEvent ), ::oEvent:Destroy(), Nil ), ; ::oOnEventBlock := iif( HB_ISOBJECT( ::oOnEventBlock ), ::oOnEventBlock:Destroy(), Nil ), ; ::oUserKeys := iif( HB_ISOBJECT( ::oUserKeys ), ::oUserKeys:Destroy(), Nil ), ; ::oName := iif( HB_ISOBJECT( ::oName ), ::oName:Destroy(), Nil ), ; ::oHand := iif( HB_ISOBJECT( ::oHand ), ::oHand:Destroy(), Nil ), ; ::nParent := ::nIndex := ::cName := ::cType := ::cVar := ::cChr := NIL, ; hmg_DelWindowObject( ::nHandle ), ::nHandle := Nil ) вызывается метод Del, и затем в неи (это строка 795 в последней версии 21.05 ) METHOD Del() INLINE ( iif( HB_ISOBJECT( ::oWin:oName ), ::oWin:oName:Del( Upper( ::cName ) ), ), ; iif( HB_ISOBJECT( ::oWin:oHand ), ::oWin:oHand:Del( ::nHandle ), ) ) на Upper( ::cName ) программа сваливается

Andrey: SergKis пишет: после ShellExecute() попадаем на Destroy окна (TWndData), идет Destroy контролам (TCnlData) и в списке регистрации на окно контролов по имени и handle получаем nil (Get(xName)) Блин, не там искал... Всё мыслю старыми категориями. На кнопке вызова печати имею такое событие: [pre2] :Event( 2, {| | Form_1Prn.Btn_02.Enabled := .F. ,; Darken2Open(hForm) ,; // Затенение на форме Print_A81(.....) ,; // сама печать lStaticOkPrintA81 := .T. ,; // кнопка печати нажата Form_1Prn.Btn_02.Enabled := .T. ,; Darken2Close(hForm) ,; // Затенение на форме RefreshWin( hForm ) ,; // перерисовать объекты на форме DoEvents(), This1Focus() } )[/pre2] И где тут идёт Destroy ?

Andrey: Pasha пишет: вызывается метод Del, и затем в неи (это строка 795 в последней версии 21.05 ) Вот я про это и писал, почему так происходит ? Как исправить эту ситуацию ?

Pasha: В том то и дело, что ошибка возникает не после ShellExecute(), а в процессе его выполнения, иначе ShellExecute() не было бы в логе ошибок Ну а Destroy не надо вызывать напрямую. Он вызовется из деструктора объекта, а деструктор вызовется, если очистить переменную, содержащую объект, либо при завершении функции, в которой объект был создан, если этот объект не был присвоен другой переменной

Pasha: Andrey пишет: Как исправить эту ситуацию ? Можно хоть двадцать раз повторять эту мантру, и через сообщения кидать лог ошибок Надо разбираться в коде, а по одному логу ничего не сделать. Все, что можно вытащить из лога, я вытащил

Andrey: Блин и в других местах стало так же вылетать при вызове ShellExecute() Раньше не вылетало.... Вот ошибка пример: [pre2]Error BASE/1102 Неверный аргумент: UPPER Args: [1] = U Called from UPPER(0) Called from (b)TCNLDATA(795) in module: h_objects.prg Called from TCNLDATA:DEL(0) Called from (b)TCNLDATA(834) in module: h_objects.prg Called from TCNLDATA:DESTROY(0) Called from TWNDDATA:__msgDestructor(736) in module: h_objects.prg Called from SHELLEXECUTE(0) Called from PASTERTFTOFIELD(373) in module: Source\util_Word.prg Called from WORD_WRITE(87) in module: Source\util_Word.prg[/pre2]

Dima: Andrey пишет: Блин и в других местах стало так же вылетать при вызове ShellExecute( Видимо в новой версии MG косячок

SergKis: Andrey Попробуй minigui.lib, которую положил на ftp. В ней правка такая[pre2] CLASS TWndData ... METHOD Del() INLINE ( iif( HB_ISOBJECT( ::oWin:oName ), ; iif( HB_ISCHAR(::cName), ::oWin:oName:Del( Upper( ::cName ) ), ), ), ; iif( HB_ISOBJECT( ::oWin:oHand ), ; iif( HB_ISNUMERIC( ::nHandle ), ::oWin:oHand:Del( ::nHandle ), ), ) ) [/pre2] PS. это проверка наличия контрола, т.к. похоже возникает ситуация destroy для контрола, которого нет или уже нет (повторный destroy)

Andrey: SergKis пишет: Попробуй minigui.lib Спасибо БОЛЬШОЕ !!! Буду пробовать.

Andrey: SergKis пишет: В ней правка такая Потестировал ! Вроде не вылетает !!! Надо бы добавить эту правку Григорию для новой версии МиниГуи !

gfilatov2002: Andrey пишет: добавить эту правку Уже добавил Благодарю за проверку

Pasha: Если такая ошибка в прежней версии возникает стабильно, то можно поймать первопричину, и попытаться ее устранить В тестовой версии библиотеки добавить что-то вроде: METHOD Del() INLINE ( iif( HB_ISOBJECT( ::oWin:oName ), ; iif( HB_ISCHAR(::cName), ::oWin:oName:Del( Upper( ::cName ) ), writelog(::ClassName) ), ), ; iif( HB_ISOBJECT( ::oWin:oHand ), ; iif( HB_ISNUMERIC( ::nHandle ), ::oWin:oHand:Del( ::nHandle ), ), ) ) чтобы хоть понять, какой наследник TCnlData генерирует ошибку. Для дальнейшей локализации можно в лог выдавать и другие параметры объекта wrilelog - сделать функцию выводе текста в файл, или использовать аналог



полная версия страницы