Что нового

Цикл в окне

Oki

Продвинутый
Сообщения
452
Репутация
63
Надо учесть что цикл будет работать медленно, так как в каждом опросе заложена принудительная задержка, чтобы не нагружать процессор.
Закомментировать опрос и счётчик побежит в десять раз быстрее.
Замечание в целом разумное для случая быстрой порции действий, но закомментировать уместно только для теста. На практике в таком случае нужно организовать опросы периодически. Как-то так.
Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
$Form1 = GUICreate("Form1", 390, 87, 559, 246)
$iButton1 = GUICtrlCreateButton("Button1", 24, 24, 161, 25)
$iButton2 = GUICtrlCreateButton("Button2", 216, 24, 153, 25)
GUISetState(@SW_SHOW)
$iFlag = 0
Const $iCounterMax = 100
$iCounter = 0
Do
    If $iCounter = 0 Then
        $nMsg = GUIGetMsg()
        $iCounter = $iCounterMax
    Else
        $iCounter -= 1
    EndIf
    If $nMsg = $iButton1 Then
        $iFlag = 1
        $nMsg = ""
    ElseIf $nMsg = $iButton2 Then
        $iFlag = 0
        $nMsg = ""
    EndIf
    If $iFlag = 1 Then
        ConsoleWrite('Test')
        ToolTip($iCounter)
    EndIf
Until $nMsg = $GUI_EVENT_CLOSE
Но если же всё-таки порция действий, которые нужно циклически повторять, сама по себе занимает достаточно много времени, то этого делать не следует. Это даже в таком случае может помешать откликам при опросе (именно по этой причине не рекомендуется после опросов вставлять дополнительную задержку от пользователя).

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

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
Можно через AdlibRegister() реже опрашивать окно.
Код:
Global $hGUI, $iBtnStart, $iBtnStop, $iStatusBar, $i, $ExitLoop1
$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
            $ExitLoop1 = 0
            AdlibRegister("GUIGetMsg2", 250)
            While 1
                $i += 1
                WinSetTitle ($hGUI, "", "Началось "  & $i)
                GUICtrlSetData($iStatusBar, "Началось "  & $i)
                If $ExitLoop1 Then
                    ExitLoop
                EndIf
            WEnd
            AdlibUnRegister()
        Case -3
            Exit

    EndSwitch
WEnd

Func GUIGetMsg2()
    Switch GUIGetMsg()
        Case $iBtnStart, $iBtnStop
            WinSetTitle ($hGUI, "", "Отмена 0" )
            GUICtrlSetData($iStatusBar, 'Отмена 0')
            $ExitLoop1 = 1
        Case -3
            Exit
    EndSwitch
EndFunc
 

RaZum

Знающий
Сообщения
78
Репутация
14
А если использовать действие по событию и разные тригеры, в том числе отложенные ?
Сообщение автоматически объединено:

Для первого поста (если это еще актуально), нужно перенести проверку второй кнопки из внешнего цикла во внутренний
Код:
If $Button2 = GuiGetMsg() Then ExitLoop

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

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
Возможно через WM_COMMAND кому-то подойдёт - код не причёсывал - взял из справки, вставив пару условий...
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
Global $k = 0
$Gui = GUICreate("WM_COMMAND", 390, 220)
$Input = GUICtrlCreateInput("Text", 10, 10, 75, 21)
$Checkbox = GUICtrlCreateCheckbox("Checkbox", 10, 40, 90, 17)
$Radio = GUICtrlCreateRadio("Radio", 10, 60, 90, 17)
Global $Button1 = GUICtrlCreateButton("Старт", 10, 85, 75, 25, 0)
Global $Button2 = GUICtrlCreateButton("Стоп", 10, 85+25, 75, 25, 0)
$Label = GUICtrlCreateEdit('Функция WM_COMMAND выполняется при клике на элементах окна.', 115, 5, 270, 210, $ES_MULTILINE)
GUICtrlSetBkColor(-1, 0xfffbd7)
$List = GUICtrlCreateList('', 10, 115+30, 75, 55)
GUICtrlSetData($List, 'Text1|Text2|Text3', 'Text3')
GUISetState()

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
Global $i=0,$iFlag=0

Do
 If $iFlag Then
    While 1
      $i += 1
      WinSetTitle ($Gui, "", "Счётчик "  & $i)
      If $iFlag=0 Then ExitLoop
      If GUIGetMsg() = -3 Then Exit
    WEnd
 EndIf
Until GUIGetMsg() = -3

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $nID = BitAND($wParam, 0x0000FFFF) ; _WinAPI_LoWord
    Local $nNotifyCode = BitShift($wParam, 16) ; _WinAPI_HiWord
    Switch $nID
      Case $Button1
        $iFlag=1
      Case $Button2
        $iFlag=0
        $i=0
    EndSwitch

    GUICtrlSetData($Label, _
        ' Параметры:' & @CRLF & _
        ' $hWnd (дескриптор окна) ' & @TAB & ':' & $hWnd & @CRLF & _
        ' $Msg (код сообщения)' & @TAB & ':' & Hex(Int($Msg), 4) & @CRLF & _
        ' $wParam' & @TAB & ':' & $wParam & @CRLF & _
        ' $lParam' & @TAB & ':' & $lParam & @CRLF & @CRLF & _
        ' Информация:' & @CRLF & _
        ' -----------------------------' & @CRLF & _
        ' Код уведомления (NotifyCode)' & @TAB & ':' & $nNotifyCode & @CRLF & _
        ' Идентификатор элемента (CtrlID)' & @TAB & ':' & $nID & @CRLF & _
        ' Дескриптор элемента (CtrlHWnd)' & @TAB & ':' & $lParam & @CRLF & _
        ' -----------------------------' & @CRLF & _
        ' ' & GUICtrlRead($nID) & ' - ' & GUICtrlRead($nID, 1))
    $k += 1
    WinSetTitle($Gui, '', 'Кликнул ' & $k & ' раз')
    Return $GUI_RUNDEFMSG
EndFunc
 

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
Если внутри цикла запрос GUIGetMsg() это ничего не решает.

Изначально автор неправильно задал постановку задачи - обязательно нажать кнопку 2, ну и все последствия из этого.
У меня в программе TextReplace тоже есть задача, которую иногда необходимо прервать, допустим я начал поиск текста в 50 Мб данных в тысячах файлах, а потом понял что неправильно задал поиск и надо отменить. Да, можно убить процесс, в этом случае не сохраняются предыдущие поисковые запросы и рег.выр. В итоге сделал HotKeySet на функцию, которая включает флаг отмены а "True" и в цикле проверяется флаг, при этом в GUI красным цветом вывел текст "Esc - Отмена", после завершения цикла хоткей разрегистрируется, а текст-подсказка убирается. Это позволяет циклу работать максимально быстро и не исключает возможности отмены операции.
 

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
задал постановку задачи
Я полностью согласен - всё зависит от задачи.
У меня, к примеру есть плеер - все элементы окна работают, но параллельно создаётся скрытое окно с плейлистом в 10-50.000 песен -- это один подход
Есть генератор слов/фраз и чтобы прервать создание 10-20 млн. комбинаций есть горячие клавиши... - это другой
Задача + варианты её решения + тестирование скорости и ... выбор что лучше.
 
Верх