Что нового

Цикл в окне

winkot

Новичок
Сообщения
169
Репутация
0
При нажатии на кнопку $Button1запускается цикл и программа не реагирует на нажатие кнопки $Button2. Как это исправить?

Код:
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case $Button1 ; Старт
            While 1
                ;Внутренний код
            WEnd

        Case $Button2 ; Стоп
            Exit

    EndSwitch
WEnd
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Код:
$iFlag = 0
Do
    $nMsg = GUIGetMsg()
    If $nMsg = $Button1 Then
        $iFlag = 1
    EndIf
    If $iFlag = 1 Then
        ; вставить очередное действие цикла (или список действий)
    EndIf
Until $nMsg = $GUI_EVENT_CLOSE Or $nMsg = $Button2
Можно также организовать, чтобы вторая кнопка приводила не к закрытию GUI, а к остановке цикла с возможностью повторного запуска.
Код:
$iFlag = 0
Do
    $nMsg = GUIGetMsg()
    If $nMsg = $Button1 Then
        $iFlag = 1
    ElseIf $nMsg = $Button2
        $iFlag = 0
    EndIf
    If $iFlag = 1 Then
        ; вставить очередное действие цикла (или список действий)
    EndIf
Until $nMsg = $GUI_EVENT_CLOSE
А ещё можно организовать начальные действия по инициализации цикла. Тогда вместо условия $nMsg = $Button1 следует поставить условие $nMsg = $Button1 And $iFlag = 0 и при его выполнении не только менять значение флага, но и выполнять начальное действие.

В качестве постскриптупа добавлю, что инструкции While 1, Switch, ContinueLoop, ExitLoop и Exit в организации GUI обычно неуместны и являются признаком плохого кода. К сожалению, в справке одно и то же простейшее действие ожидания закрытия окна GUI лишь иногда демонстрируется вот таким простым и естественным кодом.
Код:
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
А чаще всего вот таким "индусским", приучащим новичков (и не только!) городить подобные конструкции.
Код:
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd
 
Последнее редактирование:

lettterssino

Знающий
Сообщения
109
Репутация
10
При нажатии на кнопку $Button1запускается цикл и программа не реагирует на нажатие кнопки $Button2. Как это исправить?

Код:
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case $Button1 ; Старт
            While 1
                ;Внутренний код
            WEnd

        Case $Button2 ; Стоп
            Exit

    EndSwitch
WEnd
Вроде бы у тебя в цикле на первой кнопки и нет переменной 2 кнопки, как я понял можно добавить
Код:
Case $Button1 ; Старт
           While 1
                ;Внутренний код
                  If _IsPressed("12",$hDLL)  Then
                  ExitLoop
                  endif
           WEnd
 
Автор
W

winkot

Новичок
Сообщения
169
Репутация
0
Код:
If _IsPressed("12",$hDLL)  Then
Это работает, если нажать кнопку на клавиатуре. А мне нужно нажать кнопку в окне. Как на нее можно установить срабатывание?
Сообщение автоматически объединено:

; вставить очередное действие цикла (или список действий)
Дело в том, что у меня здесь должен работать цикл While. И он не дает выполнять другие строки кода в окне. Поэтому программа не реагирует на нажатия других кнопок. В этом и проблема.
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Дело в том, что у меня здесь должен работать цикл While.
В моём скрипте вместо всего цикла нужно поставить только то, что внутри цикла, в том месте, где указывает комментарий. Дополнительный цикл не нужен. Обо всём позаботится основной цикл.
Сообщение автоматически объединено:

Например, предположим, что цикл имел такой вид (совершая порцию из 3 действий при каждом проходе цикла).
Код:
While 1
   MouseMove(100, 200)
   Sleep(500)
   MouseClick("right")
Wend
Тогда в соответствующем месте моего скрипта должно быть не так.
Код:
If $iFlag = 1 Then
   While 1
      MouseMove(100, 200)
      Sleep(500)
      MouseClick("right")
   Wend
EndIf
А вот так.
Код:
If $iFlag = 1 Then
   MouseMove(100, 200)
   Sleep(500)
   MouseClick("right")
EndIf
И тогда при нажатии второй кнопки цикл этих действий прервётся после очередной порции действий. Можно сделать по потребности возможность прервать и между действиями одной порции, но это будет чуть помуторней.
 
Последнее редактирование:
Автор
W

winkot

Новичок
Сообщения
169
Репутация
0
И тогда при нажатии второй кнопки цикл этих действий прервётся после очередной порции действий.
Так то, оно так. В этом случае цикл действительно прерывается. Но дело в том, что цикл должен запуститься от первой кнопки и самостоятельно работать. А в этом случае, при нажатии первой кнопки цикл выполнит только один проход и остановится до повторного нажатия кнопки. То есть самостоятельно он работать не будет.
 
Последнее редактирование:

Oki

Продвинутый
Сообщения
452
Репутация
62
Так то, оно так. В этом случае цикл действительно прерывается. Но дело в том, что цикл должен запуститься от первой кнопки и самостоятельно работать. А в этом случае, при нажатии первой кнопки цикл выполнит только один проход и остановится до повторного нажатия кнопки. То есть самостоятельно он работать не будет.
Ничего подобного. Ты пробовал? Значение флага сменилось после нажатия первой кнопки, а посему при каждом проходе основного цикла вплоть до нажатия второй кнопки (если только окно GUI не закрыто, конечно же), которая опустит флаг, условие снова и снова будет выполняться, а потому порция действий снова и снова будет повторяться.
 

lettterssino

Знающий
Сообщения
109
Репутация
10
Это работает, если нажать кнопку на клавиатуре. А мне нужно нажать кнопку в окне. Как на нее можно установить срабатывание?
Сообщение автоматически объединено:


Дело в том, что у меня здесь должен работать цикл While. И он не дает выполнять другие строки кода в окне. Поэтому программа не реагирует на нажатия других кнопок. В этом и проблема.
Можно определить её статус. Но всё же не очень понятно, про какое окно идёт речь и тд. Возможно окно wpf и уже сложнее.
Код:
_GUICtrlButton_GetState()

Если это wpf, я бы сделал просто в цикле ожидание через
Код:
#include "UIAutomate.au3"

_UIA_WaitControlTypeElement()
 
Последнее редактирование:
Автор
W

winkot

Новичок
Сообщения
169
Репутация
0
Да, пробовал. Основной цикл в окне работать будет. Но мой код выполняется по нажатию первой кнопки. А если она не нажата, то основной цикл это код игнорирует. С какой стати он в этом случае должен его выполнять?
Сообщение автоматически объединено:

не очень понятно, про какое окно идёт речь
Обычное окно программы. GUI. В нем кнопка 1, когда она нажимается должен запускаться цикл и работать до тех пор пока не будет нажата Кнопка 2.
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Нужно опросить кнопку. А как раз сделать это не получается, т.к выполняется цикл в другом месте программы.
У меня получается. Покажи, как ты исправил свой скрипт с моей правкой.
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Код:
Global $hGUI, $iBtnStart, $iBtnStop, $iStatusBar, $i
$hGUI = GUICreate('Моя программа', 290, 260)
$iBtnStart = GUICtrlCreateButton('Старт', 10, 10, 120, 22)
$iBtnStop = GUICtrlCreateButton('Стоп', 10, 40, 120, 22)
$iStatusBar = GUICtrlCreateLabel('Строка состояния', 5, 260 - 20, 150, 17)
GUISetState()

While 1
    Switch GUIGetMsg()

        Case $iBtnStart
            ; $ToggleButton = 1 - $ToggleButton
            While 1
                $i += 1
                WinSetTitle ($hGUI, "", "Началось "  & $i)
                GUICtrlSetData($iStatusBar, "Началось "  & $i)
                Switch GUIGetMsg()
                    Case $iBtnStart, $iBtnStop
                        WinSetTitle ($hGUI, "", "Отмена 0" )
                        GUICtrlSetData($iStatusBar, 'Отмена 0')
                        ExitLoop
                    Case -3
                        Exit
                EndSwitch
            WEnd
            
        Case -3
            Exit

    EndSwitch
WEnd
 
Последнее редактирование:

lettterssino

Знающий
Сообщения
109
Репутация
10
Я тоже не понимаю, как не получается если ты вставляешь опрос в этот цикл и каждый раз она опрашивается. Либо ты иначе как-то сделал. Но без полного кода ничего не понятно.
 
Автор
W

winkot

Новичок
Сообщения
169
Репутация
0
Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 390, 87, 559, 246)
$Button1 = GUICtrlCreateButton("Button1", 24, 24, 161, 25)
$Button2 = GUICtrlCreateButton("Button2", 216, 24, 153, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

$Flag1 = 1
$i=0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case $Button1 ; Старт
            If $Flag1 = 1 Then
                ConsoleWrite('Test')
                $Flag1 = 0
            ElseIf $Flag1 = 0 Then
                $i=$i+1
                ConsoleWrite($i)
            EndIf

        Case $Button2
            Exit

    EndSwitch
WEnd
 

lettterssino

Знающий
Сообщения
109
Репутация
10
Код:
Global $hGUI, $iBtnStart, $iBtnStop, $iStatusBar, $i
$hGUI = GUICreate('Моя программа', 290, 260)
$iBtnStart = GUICtrlCreateButton('Старт', 10, 10, 120, 22)
$iBtnStop = GUICtrlCreateButton('Стоп', 10, 40, 120, 22)
$iStatusBar = GUICtrlCreateLabel('Строка состояния', 5, 260 - 20, 150, 17)
GUISetState()

While 1
    Switch GUIGetMsg()

        Case $iBtnStart
            ; $ToggleButton = 1 - $ToggleButton
            While 1
                $i += 1
                WinSetTitle ($hGUI, "", "Началось "  & $i)
                GUICtrlSetData($iStatusBar, "Началось "  & $i)
                Switch GUIGetMsg()
                    Case $iBtnStart, $iBtnStop
                        WinSetTitle ($hGUI, "", "Отмена 0" )
                        GUICtrlSetData($iStatusBar, 'Отмена 0')
                        ExitLoop
                    Case -3
                        Exit
                EndSwitch
            WEnd
           
        Case -3
            Exit

    EndSwitch
WEnd
Я думаю этот вариант как раз и подходит для решения данной задачи.
 

Oki

Продвинутый
Сообщения
452
Репутация
62
С теми, действиями, по которым сформулированы задачи, в исправленном скрипте топикстартера как раз тоже всё в порядке. Но в нём проявилась другая проблема: первая кнопка не отжимается. Есть на этот счёт собственное действие. Вот в этом топике есть на этот счёт строка _SendMessage($hbut, $BM_SETSTATE, True) в скрипте.
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 390, 87, 559, 246)
$iButton1 = GUICtrlCreateButton("Button1", 24, 24, 161, 25)
$iButton2 = GUICtrlCreateButton("Button2", 216, 24, 153, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
$iFlag = 0
Do
    $nMsg = GUIGetMsg()
    If $nMsg = $iButton1 Then
        $iFlag = 1
    ElseIf $nMsg = $iButton2 Then
        $iFlag = 0
    EndIf
    If $iFlag = 1 Then
        ConsoleWrite('Test')
    EndIf
Until $nMsg = $GUI_EVENT_CLOSE
Не надо было в добавленные переменные в моём решении вмешиваться по-своему. Вот так работает.
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Надо учесть что цикл будет работать медленно, так как в каждом опросе заложена принудительная задержка, чтобы не нагружать процессор.
Закомментировать опрос и счётчик побежит в десять раз быстрее.
 
Верх