Как разорвать цикл while в VFP (FoxPro) нажатием кнопки?

Я пытаюсь сделать простое приложение FoxPro с двумя кнопками. Первая кнопка запускает цикл while и работает корректно. Вторая кнопка должна разорвать этот цикл. Но я не могу найти корректно работающее решение. Есть код цикла:

DO WHILE !thisForm.cancelpressed

IF thisForm.cancelpressed
    EXIT
ENDIF

randNum=VAL(TRIM(STR(ROUND( 3*RAND(), 1))))
&&oneVar=VAL("1")

IF randNum = VAL("1")
    ThisForm.shape1.BackColor = greenColor
    ThisForm.shape2.BackColor = orangeColor
    ThisForm.shape3.BackColor = redColor
ENDIF

cs = seconds()
IF abs(cs - seconds()) >= 15
    doevents
    cs = seconds()
ENDIF

IF thisForm.cancelpressed
    EXIT
ENDIF

DOEVENTS
WAIT TIMEOUT 1   
ENDDO

Этот код находится в методе Click первой кнопки. Объект формы имеет определяемое пользователем свойство «cancelpressed». Во втором методе нажатия кнопки я поставил это:

thisForm.cancelpressed = .T.
Thisform.Release()
Clear Events

Но это не работает. Когда цикл запущен, он не хочет слушать никаких команд и щелчков, и не дает закрыть программу. Пожалуйста, помоги, если можешь


person Operator    schedule 22.04.2017    source источник
comment
В моей программе есть две кнопки и несколько фигур   -  person Operator    schedule 22.04.2017
comment
Если связать thisForm.cancelpressed = .T. с MouseEnter событием для моей кнопки выхода, то это работает хорошо. Но это не щелчок, он просто зависает над моей кнопкой выхода   -  person Operator    schedule 22.04.2017


Ответы (2)


Вы можете попробовать установить

Application.AutoYield = .T.

согласно https://msdn.microsoft.com/en-us/library/aa977324(v=vs.71).aspx

Но если это не сработает, то я думаю, что вы застряли, поскольку VFP не является настоящим многопоточным приложением. Вы можете обойти проблему, используя объект таймера в соответствии с http://fox.wikis.com/wc.dll?Wiki~TimerExample или с помощью многопоточного решения из https://blogs.msdn.microsoft.com/calvin_hsia/2006, но вы будете очень одиноки.

Я должен сказать, что запускать новое приложение в VFP сегодня, вероятно, не лучшая идея. Есть много современных альтернатив.

person Caltor    schedule 22.04.2017

Проблема в вашем окне ожидания. Убери это.

Local greenColor, orangeColor, redColor
m.greenColor = 0x00FF00
m.orangeColor = 0x3060FF
m.redColor = 0xFF0000
Do While !Thisform.cancelpressed
    randNum=Val(Trim(Str(Round( 3*Rand(), 1))))

    If m.randNum = Val("1")
        Thisform.shape1.BackColor = m.greenColor
        Thisform.shape2.BackColor = m.orangeColor
        Thisform.shape3.BackColor = m.redColor
    Endif
    Doevents
Enddo

(Я не понимаю, почему вы делаете такую ​​​​странную настройку randNum и проверяете, а также цель установки одних и тех же цветов снова и снова, но это не главное в этом вопросе)

Обычно вы предпочитаете использовать таймер с таким кодом.

И, кстати, это не имеет никакого отношения к многопоточности ни в VFP, ни в другом языке. Вы просто выполняете цикл с проверкой флага отмены. Обновление пользовательского интерфейса, скажем, в C#, с тем же подходом не будет проще.

person Cetin Basoz    schedule 24.04.2017