Спиране на програмата!

32 отговора 482 прегледа
#1

Спиране на програмата!

Ето какво се случи.

Програмата ми е с 4-5 форми, като една от тях е стартова. Основно кода е написан в нея. Останалите са About, Options, и т.н.
В кода на основната форма имам тези събития:


Private Sub mnuExit_Click()
End
End Sub

Private Sub frmMain_Unload(Cancel As Integer)
End
End Sub



Обаче се случва така, че ако гася програмата от менюто - всичко е наред. А ако затварям през бутона на формата "Х" - остава в паметта като активен процес.

Трасирах с F8 през сорса. Търсях активен процес. Няма. При натискане на "Х"-а, програмата приключва изпълнение. А от компилирано ЕХЕ остава в таск-менажера.

Е, пренаписах Form_Unload така:


Private Sub Form_Unload(Cancel As Integer)
On Error GoTo ErrHandle

Unload frmAbout
Unload frmDirectory
Unload frmDoubleFiles
Unload frmOptions
GoTo EndSub

ErrHandle:
Resume Next
EndSub:
End Sub



... и сега работи нормално. Затваря се. Но защо се случва така? Аз ли пропускам нещо, или е бъг, или трябва обновление на VB-то.

----------------------------------
помислих, хареса ми, помислих пак...
Отговор
в отговор на Щиpлиц #2

Re: Спиране на програмата!

:)
и на мен ми се е случвало и според мен имаш грешка в кода
ако си MDI пробвай така

Private Sub MDIForm_Unload(Cancel As Integer)
If ActiveForm Is Nothing Then
Unload Me
Else
Unload ActiveForm
End If
End
End Sub


Отговор
в отговор на ToViDebne #3

Re: Спиране на програмата!

Не, нямам MDI форма. По-скоро ме интересува защо има разлика между "End" и "End"? Това са инструкциите в първия вариант. Когато се изпълни от mnuExit_Click() - работи, и програмата се разкарва от паметта, но когато затварям с "Х"-а, пак се изпълнява "End", но от Form_Unload събитието. "End"-а си е същия, а се получава така, че програмата остава активна в паметта.

При втория вариант, където предварително разкарвам всички други форми, а те са vbModal, но също така няма значение дали съм ги изкарвал на екрана, работи нормално. В програмата няма код, с който формите се зареждат, без да е натиснато менюто. About, Options и т.н. се визуализират само в събитията от менюто.

Програмата е Single EXE, допълнителните форми са тип About dialog. Т.е. дори да не зареждам нищо, просто пускам програмата, и веднага я спирам, и проблема го имаше (преди втория начин де). Откъде аджиба се зареждат формите? Явно че в тях е проблема, щом с корекцията тръгна. Но не съм ги зареждал. А и остава въпроса, че "End" беше еднакъв и в двете събития. А не работеше само в едното.

----------------------------------
помислих, хареса ми, помислих пак...
Отговор
в отговор на Щиpлиц #4

Re: Спиране на програмата!

ти пък искаш всичко да знаеш.....не става така...все пак и Бил Гейтс има пръст в тая работа :)
преди време ми се случи нещо подобно....
във VB-то имам форма (vbModal) и съм я сетнал на CenterOwner и.....няма проблем,е да ама не.Като пусна exe-то и формичката отива на майната си в кишето.Аз и викам "Ко пра'иш ти там ма,нали съм та сетнал на център?",а тя ми вика "Гледай си работата на мен тук си ми е cool"
Брадясах
ама като я сложих на центърскриин и всичко заспа
бе майкросовска работа...
важното е да копаме

Отговор
в отговор на Щиpлиц #5

Re: Спиране на програмата!

A kakwo stawa ako izobshto razkarash towa :

Private Sub frmMain_Unload(Cancel As Integer)

End

End Sub

i natisnesh "X"-a na main formata ?

Отговор
в отговор на killall #6

Re: Спиране на програмата!

Току-що пробвах. Махнах изцяло събитието Form_Unload(...), и ефекта е същия. Програмата не се премахва от паметта.

----------------------------------
помислих, хареса ми, помислих пак...
Отговор
в отговор на Щиpлиц #7

Re: Спиране на програмата!

не знам дали ще стане,само като идея
сложи end-a в Form_QueryUnload

Отговор
в отговор на Щиpлиц #8

Re: Спиране на програмата!

Никой ли не е чел повече за End statement-а в този клуб... Какви са тези идеи сложи го тук, сложи го там и т.н. Потърсете малко в гугъл и ще намерите стотици статии по въпроса (даже потърсете на MS сайта и там има подробности)...

Накратко: най-добрия начин за спиране на програмата е чрез unload-ване на всички форми, най-накрая главната и тогава End. Т.е. във Unload event-а на главната форма се unload-ват всички форми и се вика End. Ако искате от менюто Exit да спрете програмата, там просто викате Unload frmMain.

Епа, това е моето хоби... [линк]
Отговор
в отговор на Щиpлиц #9

Re: Спиране на програмата!

Private Sub Form_Unload(Cancel As Integer)
On Error GoTo ErrHandle

Unload frmAbout
Unload frmDirectory
Unload frmDoubleFiles
Unload frmOptions
GoTo EndSub

ErrHandle:
Resume Next
EndSub:
End Sub


Не се заяждам но ако цялата програма ти е написана в този стил...мисля че можеш да очакаваш всичко от нея..:)

Отговор
в отговор на Hook #10

Re: Спиране на програмата!

Имаш по-добро предложение ли?

П.П. И очаквам да се обосновеш кое не ти харесва в този код. ;о)

----------------------------------
помислих, хареса ми, помислих пак...

Редактирано от Щиpлиц на

Отговор
в отговор на Щиpлиц #11

Re: Спиране на програмата!

Аз никога не ползвам End, но програмата спира въпреки че имам 7-8 форми.
Явно нещо бъркам!

(Нали знаете, ако всичко е станало както трябва, значи е станала голяма грешка... )


Отговор
в отговор на Щиpлиц #12

Re: Спиране на програмата!

[линк]

When executed, the End statement resets all module-level variables and all static local variables in all modules. To preserve the value of these variables, use the Stop statement instead. You can then resume execution while preserving the value of those variables.

Note The End statement stops code execution abruptly, without invoking the Unload, QueryUnload, or Terminate event, or any other Visual Basic code. Code you have placed in the Unload, QueryUnload, and Terminate events of forms and class modules is not executed. Objects created from class modules are destroyed, files opened using the Open statement are closed, and memory used by your program is freed. Object references held by other programs are invalidated.

The End statement provides a way to force your program to halt. For normal termination of a Visual Basic program, you should unload all forms. Your program closes as soon as there are no other programs holding references to objects created from your public class modules and no code executing.

Хората обикновено слагат End след последния unload за да са уверени че програмата найтина ще спре, независимо дали "there are no other programs holding references to objects created from your public class modules or code executing"

Епа, това е моето хоби... [линк]
Отговор
в отговор на fiffy #13

Re: Спиране на програмата!

Е, това вече е отговор.

----------------------------------
помислих, хареса ми, помислих пак...
Отговор
в отговор на Щиpлиц #14

Аз имам

Най-малкото да се напише горе On Error Resume Next вместо Goto на майната си, там да се дава Resume Next и като свърши тялото пак да използваме Goto

Отговор
в отговор на fiffy #15

Re: Спиране на програмата!

имам едно програмче с 178(!) форми
мислиш ли ,че трябва да ги unload-вам една по една?!

Отговор
в отговор на Щиpлиц #16

Re: Спиране на програмата!

Разбира се, че ти си пропуснал нещо.
А това, което си пропуснал е да прочетеш главата за дебъг и трасиране на програми, която я има във всяка една книга за VB.
Защото ако я беше прочел щеше да разбереш как точно се дебъгва и щеше да разбереш следното:

Написал си, че си трасирал, чрез F8 следните две "събития":

Private Sub mnuExit_Click()
End
End Sub

Private Sub frmMain_Unload(Cancel As Integer)
End
End Sub


Това не са събития, а подпрограми, които се извикват от някъде другаде (може да е от събитие, може от друга подпрограма, може от ....)
Но за да се извика една подпрограма от дадено събитие, тя трябва да отговаря на определени условия.
Първата ти подпрограма отговаря на такива условия и ще бъде извикана при кликване върху меню, бутон и т.н. с име mnuExit.
Втората ти подпрограма не отговаря на никакви условия за извикване на събитие, така че тя няма да бъде извикана от събитие. И ако беше трасирал внимателно щеше да разбереш че подпрограмата, която се извиква при ънлоудване на форма се нарича Form_Unload, а не frmMain_Unload
Поради тази причина тази подпрограма не се изпълнява при ънлоудване на формата, при натискане на бутона Х например и програмата ти остава в паметта, защото командата End не се изпълнява.
А според мен няма разлика къде се изпълнява командата End, тя винаги си значи край. Въпросът е обаче дали се изпълнява, което пък от своя страна се установява, чрез ... дебъгване, брекпоинти, команда Stop и т.н.

Бии, за да те уважават!
Отговор
в отговор на ToViDebne #17

Re: Спиране на програмата!

Баси що за програма е това, я поясни!??


Отговор
в отговор на пpoГЪPMИcт #18

Re: Спиране на програмата!

Извинявам се за грешката, която съм допуснал при преписването на тази проблемна част от кода.

Всъщност двете събития в които съм сложил "End" са mnuExit_Click и Form_Unload.

Написах, че съм трасирал програмата с F8. Да, и също така написах, че през сорса си спира нормално. А "F8" го натискам последователно от стартирането и. Т.е. със и без брийк-поинт програмата спира на всяка инструкция. Вижда се, че "End" се изпълнява във събитието Form_Unload(...), и програмата спира, но това се случва само докато е на сорс. След компилация като пусна ЕХЕ-то, и не искаше да спира. После махнах този "End" във Form_Unload и написах кода за унлоадване на формите. И сработи.

Ако формите са много, признавам, че ще стане мацаница от ънлоадване, но най-вероятно ще може да се напише някакъв модул за ънлоадване на форми без да ги описваме всичките.

Ето част от едно екземпълче за изтриване съдържанието на всички текстови полета в дадена форма:


Dim c As Object
For Each c In frmMain
If c Is TextBox Then c.Text = ""
Next


Дали можем да сглобим нещо подобно за ънлоадване на форми от Project-а?

----------------------------------
помислих, хареса ми, помислих пак...
Отговор
в отговор на ToViDebne #19

Re: Спиране на програмата!

Ебахти програмата....178 форми...

Отговор
в отговор на Щиpлиц #20

Re: Спиране на програмата!

:)

Как да ти повярвам че след изпълнение на End, където и да се намира то, програмата ти не спира ? :) Освен ако не правиш Inject на твоя функция в друг процес в което се съмнявам, или пък имаш някакъв Thread, който още не е свършил (това не съм го пробвал как се "сработва" с End).

Има нещо в кода ти, което пропускаш да кажеш. Ако не е нещо "Secure", можеш да го Upload някъде (или да Upload EXE файла) за да го тестваме...

Отговор