Вопрос

Что делают "Doevents" в VB6? Почему я получаю сообщение об ошибке "из места стека"? Что это значит ?

Это было полезно?

Решение

Doevents () позволяет обрабатывать другие сообщения Windows.

Причина, по которой вы получаете ошибку в пространстве стека, вероятно, заключается в том, что DOEVENTS () позволяет происходить события, которые снова вызывают ваш код, который снова вызывает DOEVENTS (), и так далее, пока пространство стека, которое отслеживает обратные адреса для всех этих Звонки, закончились.

В целом, я не рекомендую использовать doevents () из-за таких проблем и того факта, что он нарушает общий дизайн Windows, управляемый событиями.

Другие советы

Немного другой способ взглянуть на Doevents заключается в том, что он промывает события в очереди событий. Если ваш Sub или функция запускает событие, этот обработчик событий становится подставкой, которая находится в очереди, чтобы запустить, как только ваша подводная/функция будет завершена. Doevents говорит, что теперь запускает этот подставщик для обработчика событий, вместо того, чтобы ждать до конца вашего подбола.

Несмотря на то, что я согласен с Джонатоном о том, что я не использует Doevents, я бы испекла его утверждение, сказав, что я рекомендую использовать его только в том случае, если вы точно знаете, и знаете все последствия изменения порядка очереди события таким образом. Чаще всего Doevents указывается, когда вы хотите каким -то образом обновить свой экран из контекста подпрограммы, прежде чем подпрограмма завершится выполнять.

Примером этого является то, что вы используете управление ProgressBar. Предположим, вы переживаете через несколько тысяч записей и хотите предоставить пользователю обратную связь о том, насколько далеко вы находитесь, обновив планку прогресса. Вы можете прервать свой цикл каждую сотню записей и менять значение управления ProgressBar. Однако (если вы не сделаете что -то с этим), вы не увидите изменение на экране до тех пор, пока не запускается обработчик событий FroductBar, и этот обработчик не будет работать до тех пор, пока ваша подставка не будет выполнена. Это просто будет помещено в очередь событий. Способ заставить событие изменения сразу же запустить, приостановленную вашу подставку, состоит в том, чтобы позвонить в Doevents. Это будет промыть все существующие события из очереди-в этом случае событие изменения вашего ProgressBar-и обновит управление ProgressBar на экране.

Теперь, «вне пространства стека» в основном означает, что вы попали в бесконечную цикл функциональных вызовов. Самый базовый способ вызвать это:

Public sub MySub()
    MySub
End Sub

А потом позвоните MySub откуда -то. Вы получите ошибку в пространстве стека. Если вы посмотрите на стек вызовов, вы увидите очень длинную линию звонков MySub.

Хорошо известный пример реального мира произойдет в более старых версиях VB:

Public Sub TextBoxArray_LostFocus(index as Integer)
    If TextBoxArray(index) = "" Then
        TextBoxArray(index).SetFocus
        MsgBox "Please enter a value"
    End If
End Sub

Эта ситуация предполагает, что два члена управляющего массива Textbox называют TextBoxArray. Теперь, если пользователь начинает с первого (Index 0) и перемещается ко второму (индекс 1), то событие LostFocus Index 0 будет стрелять. Тем не менее, VB также будет внутренне установить фокус на коробку «Индекс 1». Затем код установит фокус обратно на индекс 0, событие LostFocus Index 1! Ты пойман в петле. Они исправили это в VB5 или 6, ожидая, чтобы установить фокус до тех пор, пока не было выполнено событие LostFocus.

Я бы прояснил ответ Джонатона в том, что он накачивает цикл сообщений VB и позволяет времени выполнения VB обрабатывать сообщения Windows, что противоположно снаму Но когда VB6 был написан Windows 9x была доминирующей ОС, и жесткой петлей, в которой имели только Doevents в нем, увеличивает использование процессора до 100%). Так что видит такие вещи, как

While fDoneFile = False
    DoEvents
    Sleep 55
Wend

был общей схемой во всем мире VB6.

Как указано еще, где, Doevents позволяет другим событиям в вашем приложении. Вот пример того, как вы можете использовать Doevents без проблемы «вне стека». Это гарантирует, что вы не проходите через код несколько раз, используя логическое, чтобы указать, что код работает.

Sub Example()
    'Create static variable to indicate the sub is running.
    Static isRunning As Boolean
    'Exit the sub if isRunning
    If isRunning Then Exit Sub
    'Indicate sub is running
    isRunning = True
    'Sub does stuff
    DoEvents
    'Ends up calling sub again
    Example 'Added just to prove via testing.
    'Indicate sub is no longer runningrunning
    isRunning = False
End Sub
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top