Русское сообщество AutoIt

Общий раздел по AutoIt => GUI - Графический интерфейс пользователя => Тема начата: VadimKHL от Декабрь 24, 2016, 17:41:09

Название: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Декабрь 24, 2016, 17:41:09
Всем привет!
Нужна помощь новичку.
Ситуация такая. Есть обработка кнопок в режиме OnEvent.
При их нажатии происходит передача данных в Com порт и принятие ответного сообщения от устройства.
Так же, в бесконечном цикле While каждые 100 мс происходит обмен данных через ком порт.

В итоге, иногда при нажатии кнопок нарушается логика обмена данными,
т.е. в цикле посылаются данные в ком порт, потом происходит нажатие кнопки, которое нарушает режим работы запрос/ответ.

Каким способом можно решить данную проблему?

Всем спасибо!
Название: Re: Режим OnEvent и приоритетность
Отправлено: ra4o от Декабрь 27, 2016, 00:48:08
Возможно во время обмена данными с СОМ портом отключать режим OnEvent , после окончания - включать. Таким образом во время обмена данными скрипт не будет реагировать на нажатие кнопки.  Или , как вариант на нажатие кнопки привязать просто установку какого-нибудь флага нажатия кнопки и обработку флага по кнопке производить вне цикла работы с СОМ портом.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 11, 2017, 09:56:54
Возможно во время обмена данными с СОМ портом отключать режим OnEvent , после окончания - включать. Таким образом во время обмена данными скрипт не будет реагировать на нажатие кнопки.  Или , как вариант на нажатие кнопки привязать просто установку какого-нибудь флага нажатия кнопки и обработку флага по кнопке производить вне цикла работы с СОМ портом.

Возможно. Но тогда смысл режима OnEvent вообще теряется.

А возможно ли в режиме OnEvent запустить таймер, который допустим каждые 100 мс генерирует событие, и выполняет функцию, блокируя выполнение других событий?
Т.е. как будто обычная кнопка в режиме OnEvent, которая нажимается каждые 100 мс автоматически, а не пользователем?


Название: Re: Режим OnEvent и приоритетность
Отправлено: ra4o от Январь 11, 2017, 11:58:19
Цитировать
каждые 100 мс генерирует событие, и выполняет функцию
Код: AutoIt [Выделить]
AdlibRegister("_MyFunc", 100)

Но это Вас не спасёт от не вовремя нажатых кнопок в режиме OnEvent.
Цитировать
Возможно. Но тогда смысл режима OnEvent вообще теряется.
Если объём информации не большой, а судя по тому. что Вы читаете/пишите в СОМ порт каждые 100 мс оно так и есть. то отключение режима OnEvent на время работы с СОМ портом Вы и не заметите. Ведь у Вас задача
Цитировать
блокируя выполнение других событий?
- не принимать никаких прерываний при обмене данными, тогда и решение :
Цитировать
во время обмена данными с СОМ портом отключать режим OnEvent
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 12, 2017, 15:51:15
тогда и решение :
Цитировать
во время обмена данными с СОМ портом отключать режим OnEvent

Я думаю это не верное решение. Ситуация такая,
отключаем OnEvent, происходит обмен данными по COM, а в это время пользователь кликает по кнопке.
Ведь после включения OnEvent кнопка не будет отработана?
В итоге безответный клик по кнопке?
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 12, 2017, 16:21:34
VadimKHL
Выставляйте флаги (разрешения) либо в цикле, либо в функциях-обработчиках. И проверяйте их, соответственно, либо в функциях, либо в цикле.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 13, 2017, 10:43:16
VadimKHL
Выставляйте флаги (разрешения) либо в цикле, либо в функциях-обработчиках. И проверяйте их, соответственно, либо в функциях, либо в цикле.

Т.е. при нажатии кнопок, вызывать функции, которые просто поднимают флаги (биты) в переменной, а в цикле While, после обмена данными с COM,
обрабатывать нажатые кнопки?

А в чем тогда будет разница данного решения по сравнению с использованием режима MessegeLoop?
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 13, 2017, 13:01:06
VadimKHL
Цитировать
разница данного решения по сравнению с использованием режима MessegeLoop
Принципиальной разницы нет. Вопрос только в скорости реакции интерфейса. Как написано в справке по MessageLoop "вы должны убедиться, что вызываете функцию довольно часто (более 20-ти раз в секунду), иначе ваш GUI не будет откликаться на взаимодействие с элементами управления". А если вы в цикл обмена данными включите GUIGetMsg(), то всё равно придётся запоминать нажатые кнопки и обрабатывать их при выходе из цикла.
Название: Re: Режим OnEvent и приоритетность
Отправлено: ra4o от Январь 13, 2017, 14:39:33
Ведь даже , если устанавливать флаг нажатия кнопки скрипту нужно будет выйти из цикла работы с СОМ портом, установить флаг и вернуться обратно.  Если все-же необходимо не прерывать обработку данных с СОМ порта и работать одновременно с интерфейсом , тогда работу с СОМ портом можно вынести в отдельный скрипт (dll итп) и при необходимости из основного скрипта вызывать скрипт обработки данных.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 13, 2017, 16:00:48
Ведь даже , если устанавливать флаг нажатия кнопки скрипту нужно будет выйти из цикла работы с СОМ портом, установить флаг и вернуться обратно. 

Похоже вопрос не верно описал.

Функцию работы с COM портом, которая выполняется каждые 100 мс прерывать можно сколько угодно, хоть на 10 секунд.
Нельзя нарушать условие ЗАПРОС (сообщение от ПК) - ОТВЕТ (ПК принимает).

Конкретно как происходит крах:
Функция, которая выполняется каждые 100 мс посылает запрос, и ожидает ответ.
В это время пользователь нажал кнопку, сразу посылается НОВЫЙ ЗАПРОС,  а на предыдущий запрос ответ еще не пришел.
Функция нажатия кнопки в итоге получает ответ, но не на свой запрос, а от предыдущего запроса.

Вот где проблема.

 

Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 13, 2017, 16:17:05
VadimKHL
Цитировать
посылает запрос, и ожидает ответ
И сколько времени это занимает?
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 13, 2017, 16:23:10
Все зависит от загруженности МК. Ответ может придти в интервале от 1 мс до 200 мс.
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 13, 2017, 16:30:21
VadimKHL
Цитировать
до 200 мс
Для MessageLoop многовато... но попробовать можно. Тут зависит от того, как часто кнопки нажимаются и как быстро нужна реакция на нажатие.
В противном случае придётся делать гибрид - либо с флагами, либо с вкл/выкл режима.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 13, 2017, 16:37:57
Накидал тестовую прогу.
OnEvent очень интересно работает.
он все события нажатия кнопок ставит в очередь. И это дает 100 процентов выполнения всех операций с GUI.
Для меня это самый правильный вариант.

Но как сгенерить события OnEvent программно, а не нажатием кнопки, что бы каждые 100 мс добавлялась в очередь еще одна функция?

Код: AutoIt [Выделить]
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

Opt("GUIOnEventMode", 1) ; Включить режим отслеживания событий GUI.

; ====================================================================================================================
; Создаем визуальное окно и объекты в нем.
; ====================================================================================================================

; Создать визуальное окно.
$WINGUI = GUICreate("TEST", 470, 245, -1, -1, BitOr($WS_POPUP, $WS_BORDER))

; Информауионные строки.
$lbTMR1 = GUICtrlCreateLabel("TMR1:", 10, 10, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR2 = GUICtrlCreateLabel("TMR2:", 10, 25, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR3 = GUICtrlCreateLabel("TMR3:", 10, 40, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

$idTMR1 = GUICtrlCreateLabel("0", 55, 10, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR2 = GUICtrlCreateLabel("0", 55, 25, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR3 = GUICtrlCreateLabel("0", 55, 40, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

; Кнопки.
GUICtrlCreateButton("TMR1", 260, 70, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR1")
GUICtrlCreateButton("TMR2", 260, 95, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR2")
GUICtrlCreateButton("TMR3", 260, 120, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR3")

; Системные события.
GUISetOnEvent($GUI_EVENT_CLOSE, "_CLOSEEvent")

GUISetState(@SW_SHOW, $WINGUI)

While 1
   Sleep(100)
WEnd


Func _TMR1()
   For $TMR1 = 1 To 10
      GUICtrlSetData ($idTMR1, $TMR1)
      sleep (500)
   Next
EndFunc

Func _TMR2()
   For $TMR2 = 1 To 10
      GUICtrlSetData ($idTMR2, $TMR2)
      sleep (500)
   Next
EndFunc

Func _TMR3()
   For $TMR3 = 1 To 10
      GUICtrlSetData ($idTMR3, $TMR3)
      sleep (500)
   Next
EndFunc


; ====================================================================================================================
; Функции системных событий.
; ====================================================================================================================
Func _CLOSEEvent()
    Exit
EndFunc

Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 13, 2017, 17:04:35
VadimKHL
Цитировать
сгенерить события OnEvent программно, а не нажатием кнопки
Нужно просто программно нажать кнопку ;)
Код: AutoIt [Выделить]
AdlibRegister("BtnClick", 100)

Func BtnClick()
  GUICtrlSendMsg($idBtn, 0xF5, 0, 0) ; $BM_CLICK
;~   ControlClick($WINGUI, "", "TMR1") ; или так
EndFunc



Добавлено: Январь 13, 2017, 19:32:38
VadimKHL  [?]
Цитировать
OnEvent очень интересно работает.
он все события нажатия кнопок ставит в очередь
На самом деле очередь получается из-за того, что очередное событие не может прервать функцию, вызванную другим событием.

В режиме MessageLoop события тоже встают в очередь. Просто эта очередь "забивается" событиями движения курсора мыши. А функция GuiGetMsg() за один вызов читает одно событие. Вот и получается, что если её вызывать редко, то интерфейс "тормозит".

Вот вариант вашей "тестовой проги" в режиме MessageLoop (все события $GUI_EVENT_MOUSEMOVE вычищаются и интерфейс не тормозит)
(нажмите для показа/скрытия)
Название: Re: Режим OnEvent и приоритетность
Отправлено: Naisho от Январь 14, 2017, 14:55:49
Может так?

Код: AutoIt [Выделить]
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)

Global $bAuto = False, $bBusy = False, $bManual = False



#Region ### START Koda GUI section ### Form=
Local $Form1 = GUICreate("Form1", 401, 218, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Close")
Local $Button1 = GUICtrlCreateButton("Start Auto Check", 64, 88, 128, 25)
GUICtrlSetOnEvent(-1, "Button1Click")
Local $Button2 = GUICtrlCreateButton("Manual Check", 224, 88, 128, 25)
GUICtrlSetOnEvent(-1, "Button2Click")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
    Sleep(100)
WEnd

Func Button1Click()

    $bAuto = ($bAuto)?(False):(True)

    If $bAuto Then
        GUICtrlSetData($Button1, "Stop Auto Check")
        AdlibRegister("CheckFunc",3000)
    Else
        GUICtrlSetData($Button1, "Start Auto Check")
        AdlibUnRegister("CheckFunc")
    EndIf

EndFunc

Func Button2Click()

    $bManual = True

    GUICtrlSetBkColor($Button2,0xffff00)

    If Not $bAuto Then AdlibRegister("CheckFunc",20)

EndFunc

Func Form1Close()
    Exit
EndFunc

Func CheckFunc()

    If $bBusy Then Return SetExtended(1)

    If $bManual Then
        If Not $bAuto Then AdlibUnRegister("CheckFunc")
        $bManual = False
        GUICtrlSetStyle($Button2, $GUI_SS_DEFAULT_BUTTON)
    EndIf

    If $bAuto Then GUICtrlSetBkColor($Button1,0xffff00)

    $bBusy = True
    Action()
    $bBusy = False

    If $bAuto Then GUICtrlSetStyle($Button1, $GUI_SS_DEFAULT_BUTTON)

EndFunc

Func Action()
    ConsoleWrite("!!!" & @CRLF)
    Sleep(Random(1000,2000))
EndFunc
 

Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 18, 2017, 11:55:35
Добрый день!

Проверил работу AdlibRegister.
Проблему не решает.
Функция, вызванная AdlibRegister, прерывается функцией, при нажатии кнопки.

Разбираюсь с вариантами, предложенными выше...
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 18, 2017, 12:06:29
VadimKHL
Цитировать
Функция, вызванная AdlibRegister, прерывается функцией, при нажатии кнопки
Такое поведение наблюдается при включении режима OnEvent. И ещё в этом режиме функция AdlibRegister не может прервать функцию-обработчик события. А в режиме MessageLoop всё наоборот.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 20, 2017, 13:33:23
Пока вышел из положения, путем введения флагов (режим OnEvent):
Код: AutoIt [Выделить]
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

Opt("GUIOnEventMode", 1) ; Включить режим отслеживания событий GUI.

Global $FLAGBUT = 0

; ====================================================================================================================
; Создаем визуальное окно и объекты в нем.
; ====================================================================================================================

; Создать визуальное окно.
$WINGUI = GUICreate("TEST", 470, 245, -1, -1, BitOr($WS_POPUP, $WS_BORDER))

; Информауионные строки.
$lbTMR1 = GUICtrlCreateLabel("TMR1:", 10, 10, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR2 = GUICtrlCreateLabel("TMR2:", 10, 25, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR3 = GUICtrlCreateLabel("TMR3:", 10, 40, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR4 = GUICtrlCreateLabel("TMR4:", 10, 55, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

$idTMR1 = GUICtrlCreateLabel("0", 55, 10, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR2 = GUICtrlCreateLabel("0", 55, 25, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR3 = GUICtrlCreateLabel("0", 55, 40, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR4 = GUICtrlCreateLabel("0", 55, 55, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

; Кнопки.
GUICtrlCreateButton("TMR1", 260, 70, 100, 25)
GUICtrlSetOnEvent(-1, "BCLK_TMR1")
GUICtrlCreateButton("TMR2", 260, 95, 100, 25)
GUICtrlSetOnEvent(-1, "BCLK_TMR2")
GUICtrlCreateButton("TMR3", 260, 120, 100, 25)
GUICtrlSetOnEvent(-1, "BCLK_TMR3")

; Системные события.
GUISetOnEvent($GUI_EVENT_CLOSE, "_CLOSEEvent")

GUISetState(@SW_SHOW, $WINGUI)

Global $TMRUPDATE = TimerInit()

While 1

   If BitAND($FLAGBUT, 1) > 0 Then
      $FLAGBUT = $FLAGBUT - 1
      _TMR1()
   EndIf
   If BitAND($FLAGBUT, 2) > 0 Then
      $FLAGBUT = $FLAGBUT - 2
      _TMR2()
   EndIf
   If BitAND($FLAGBUT, 4) > 0 Then
      $FLAGBUT = $FLAGBUT - 4
      _TMR3()
   EndIf

   If TimerDiff($TMRUPDATE) > 100 Then
      $TMRUPDATE = TimerInit()
      _TMR4()
   EndIf

WEnd

Func BCLK_TMR1()
   $FLAGBUT = BitOR(1, $FLAGBUT) ; Установить 0 бит.
EndFunc
Func BCLK_TMR2()
   $FLAGBUT = BitOR(2, $FLAGBUT) ; Установить 1 бит.
EndFunc
Func BCLK_TMR3()
   $FLAGBUT = BitOR(4, $FLAGBUT) ; Установить 2 бит.
EndFunc

Func _TMR1()
   For $TMR1 = 1 To 5
      GUICtrlSetData ($idTMR1, $TMR1)
      sleep (500)
   Next
EndFunc

Func _TMR2()
   For $TMR2 = 1 To 5
      GUICtrlSetData ($idTMR2, $TMR2)
      sleep (500)
   Next
EndFunc

Func _TMR3()
   For $TMR3 = 1 To 5
      GUICtrlSetData ($idTMR3, $TMR3)
      sleep (500)
   Next
EndFunc

Func _TMR4()
   For $TMR4 = 1 To 5
      GUICtrlSetData ($idTMR4, $TMR4)
      sleep (500)
   Next
EndFunc

; ====================================================================================================================
; Функции системных событий.
; ====================================================================================================================
Func _CLOSEEvent()
    Exit
EndFunc
 


Но очередность в данном случае не соблюдается.

Думаю, как можно решить другим способом.
Может спасут GUICtrlSendMsg или ControlClick, разбираюсь с ними.

Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 20, 2017, 14:05:24
VadimKHL
Цитировать
очередность в данном случае не соблюдается
Естественно. Если вы сначала нажимаете "большую" кнопку (например, +4), затем меньшую (+2), после чего проверяете СНАЧАЛА на наличие 2... конечно, 2 там будет. Как бы вы кнопки не нажимали, очередь у вас всегда будет от "меньшей" к "большей". Что-то вы перемудрили.

Чем вам не нравится код из вашего сообщения #13 с добавлением AdlibRegister и GUICtrlSendMsg из моего сообщения #14 ?
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 20, 2017, 14:25:49
VadimKHL
Цитировать
очередность в данном случае не соблюдается
Естественно. Если вы сначала нажимаете "большую" кнопку (например, +4), затем меньшую (+2), после чего проверяете СНАЧАЛА на наличие 2... конечно, 2 там будет. Как бы вы кнопки не нажимали, очередь у вас всегда будет от "меньшей" к "большей". Что-то вы перемудрили.

Чем вам не нравится код из вашего сообщения #13 с добавлением AdlibRegister и GUICtrlSendMsg из моего сообщения #14 ?

Да, действительно проще. И очередность в данном случае соблюдается. Уже ближе к решению.
Но сразу появляются вопрос, как тогда скрыть "ненужную кнопку" и как сделать что бы туда фокус не прыгал?
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 20, 2017, 14:38:18
VadimKHL
Цитировать
скрыть "ненужную кнопку"
Код: AutoIt [Выделить]
GUICtrlSetState($idBtn, $GUI_HIDE)


Цитировать
что бы туда фокус не прыгал
На скрытые элементы фокус ввода не передаётся.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 20, 2017, 14:46:59
Что бы фокус не прыгал, сделал так:
Код: AutoIt [Выделить]
AdlibRegister("BtnClick", 100)
Func BtnClick()
ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "")
EndFunc


Но не знаю что нужно указать в последнем поле "ControlID".
Как определить?


Добавлено: Январь 20, 2017, 14:54:43
Извиняюсь, в поле CommandID:
ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "????")

И вообще это правильное решение?
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 20, 2017, 15:13:34
VadimKHL
Откройте справку по функции ControlCommand и попробуйте найти в таблице хоть что-нибудь, связанное с Button.
Не работает эта функция с кнопками. Разобрался. Работает на уровне уведомлений.

По-моему, решение проблемы мы нашли. А различные "рюшечки" в виде фокусов и скрытых кнопок - это вообще не отсюда.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 20, 2017, 15:41:33
VadimKHL
Откройте справку по функции ControlCommand и попробуйте найти в таблице хоть что-нибудь, связанное с Button.
Не работает эта функция с кнопками.

По-моему, решение проблемы мы нашли. А различные "рюшечки" в виде фокусов и скрытых кнопок - это вообще не отсюда.

Готов поспорить. РАБОТАЕТ! :laugh: Оно как раз является решением моей проблемы.
 :beer:
Код: AutoIt [Выделить]
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

Opt("GUIOnEventMode", 1) ; Включить режим отслеживания событий GUI.

Global $FLAGBUT = 0

; ====================================================================================================================
; Создаем визуальное окно и объекты в нем.
; ====================================================================================================================

; Создать визуальное окно.
$WINGUI = GUICreate("TEST", 470, 245, -1, -1, BitOr($WS_POPUP, $WS_BORDER))

; Информауионные строки.
$lbTMR1 = GUICtrlCreateLabel("TMR1:", 10, 10, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR2 = GUICtrlCreateLabel("TMR2:", 10, 25, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR3 = GUICtrlCreateLabel("TMR3:", 10, 40, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR4 = GUICtrlCreateLabel("TMR4:", 10, 55, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

$idTMR1 = GUICtrlCreateLabel("0", 55, 10, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR2 = GUICtrlCreateLabel("0", 55, 25, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR3 = GUICtrlCreateLabel("0", 55, 40, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR4 = GUICtrlCreateLabel("0", 55, 55, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

; Кнопки.
GUICtrlCreateButton("TMR1", 260, 70, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR1")
GUICtrlCreateButton("TMR2", 260, 95, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR2")
GUICtrlCreateButton("TMR3", 260, 120, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR3")
$BTHIDE = GUICtrlCreateButton("TMR4", 260, 145, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR4")
GUICtrlSetState($BTHIDE, $GUI_HIDE)

; Системные события.
GUISetOnEvent($GUI_EVENT_CLOSE, "_CLOSEEvent")
GUISetState(@SW_SHOW, $WINGUI)

Global $TMRUPDATE = TimerInit()

While 1
   If TimerDiff($TMRUPDATE) > 100 Then
      $TMRUPDATE = TimerInit()
      ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "")
   EndIf
WEnd

Func _TMR1()
   For $TMR1 = 1 To 5
      GUICtrlSetData ($idTMR1, $TMR1)
      sleep (500)
   Next
EndFunc

Func _TMR2()
   For $TMR2 = 1 To 5
      GUICtrlSetData ($idTMR2, $TMR2)
      sleep (500)
   Next
EndFunc

Func _TMR3()
   For $TMR3 = 1 To 5
      GUICtrlSetData ($idTMR3, $TMR3)
      sleep (500)
   Next
EndFunc

Func _TMR4()
   For $TMR4 = 1 To 5
      GUICtrlSetData ($idTMR4, $TMR4)
      sleep (500)
   Next
EndFunc

; ====================================================================================================================
; Функции системных событий.
; ====================================================================================================================
Func _CLOSEEvent()
    Exit
EndFunc
 



Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 20, 2017, 17:32:10
VadimKHL
Цитировать
РАБОТАЕТ!
Код: AutoIt [Выделить]
ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "")

Чудеса. Элемент в этом случае получает WM_GETTEXT. А AutoIt считает, что элемент "нажали". :think:
Название: Re: Режим OnEvent и приоритетность
Отправлено: Alofa от Январь 20, 2017, 20:36:26
OffTopic
... Элемент в этом случае получает WM_GETTEXT...
Цитата: Из справки:
"SendCommandID", Command IDЭмулирует сообщение WM_COMMAND. Обычно используется для элемента ToolbarWindow32. Используйте вкладку ToolBar утилиты Au3Info чтобы получить Command ID.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 20, 2017, 21:47:23
VadimKHL
Цитировать
РАБОТАЕТ!
Код: AutoIt [Выделить]
ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "")

Чудеса. Элемент в этом случае получает WM_GETTEXT. А AutoIt считает, что элемент "нажали". :think:

Да. Причем кнопку можно даже не скрывать, в отличии от GUICtrlSendMsg или ControlClick, фокус (табуляция) на нее не прыгает.
Просто где то в "стэк" событий OnEvent добавляется в очередь (если она есть) событие о нажатии кнопки.

Я конечно хочу сделать так, что бы даже кнопку скрытую добавлять не нужно было, а сразу добавлять события в очередь,
но т.к. я очень мало знаю про скрипты AutoIt, остановлюсь на данном варианте.

Спасибо всем за помощь!

P.S.: Ну если конечно вариант найдется более "интересный", прошу написать об этом.
Ну и конечно так и не понял, что нужно вписать в последнее поле функции ControlCommand, которое CommandID (которое сейчас пустое, но все работает).
Если кто знает, дайте знать.


Название: Re: Режим OnEvent и приоритетность
Отправлено: Alofa от Январь 20, 2017, 22:20:55
... Ну если конечно вариант найдется более "интересный"...
Код: AutoIt [Выделить]
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

;~ Global $iOpt = Opt("GUIOnEventMode", 1) ; Включить режим отслеживания событий GUI.

Global $FLAGBUT = 0

; ====================================================================================================================
; Создаем визуальное окно и объекты в нем.
; ====================================================================================================================

; Создать визуальное окно.
$WINGUI = GUICreate("TEST", 470, 245, -1, -1, BitOr($WS_POPUP, $WS_BORDER))

; Информауионные строки.
$lbTMR1 = GUICtrlCreateLabel("TMR1:", 10, 10, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR2 = GUICtrlCreateLabel("TMR2:", 10, 25, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR3 = GUICtrlCreateLabel("TMR3:", 10, 40, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR4 = GUICtrlCreateLabel("TMR4:", 10, 55, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

$idTMR1 = GUICtrlCreateLabel("0", 55, 10, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR2 = GUICtrlCreateLabel("0", 55, 25, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR3 = GUICtrlCreateLabel("0", 55, 40, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR4 = GUICtrlCreateLabel("0", 55, 55, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

; Кнопки.
GUICtrlCreateButton("TMR1", 260, 70, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR1")
GUICtrlCreateButton("TMR2", 260, 95, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR2")
GUICtrlCreateButton("TMR3", 260, 120, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR3")
;~ $BTHIDE = GUICtrlCreateButton("TMR4", 260, 145, 100, 25)
;~ GUICtrlSetOnEvent(-1, "_TMR4")
;~ GUICtrlSetState($BTHIDE, $GUI_HIDE)

; Системные события.
GUISetOnEvent($GUI_EVENT_CLOSE, "_CLOSEEvent")
GUISetState(@SW_SHOW, $WINGUI)

Global $TMRUPDATE = TimerInit()

While 1
   If TimerDiff($TMRUPDATE) > 100 Then
      $TMRUPDATE = TimerInit()
;~       ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "")
    Opt("GUIOnEventMode", 0)
      _TMR4()
    Opt("GUIOnEventMode", 1)
   EndIf
WEnd
; ...

Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 20, 2017, 22:28:15
... Ну если конечно вариант найдется более "интересный"...
Код: AutoIt [Выделить]
While 1
   If TimerDiff($TMRUPDATE) > 100 Then
      $TMRUPDATE = TimerInit()
;~       ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "")
      _TMR4()
   EndIf
WEnd


Мда... Alofa, амбициозность неистребима.
Нажмите любую кнопку, когда функция TMR4 выполняется.
Потом сравните мой исходной пример.
Я думаю разницу Вы найдете.
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 20, 2017, 22:58:45
Alofa
Я тоже умею читать справку ;) и знаю, что делает WM_COMMAND. Меня смутило сообщение WM_GETTEXT, которое отлавливает SpyXX. Но, похоже, данное сообщение отправляет сам AutoIt, когда работаем с элементами его же окна. Потому что, если отправить WM_COMMAND "снаружи" (из другого приложения), то никакие WM-сообщения элементу не поступают.

VadimKHL
Цитировать
что нужно вписать в последнее поле функции ControlCommand, которое CommandID
Ничего не нужно. В этом сообщении передаётся дескриптор элемента и этого достаточно.

Цитировать
хочу сделать так, что бы даже кнопку скрытую добавлять не нужно было
Режим OnEvent рассчитан на элементы GUI, поэтому всё равно его (элемент) нужно добавлять. Но можно добавить "пустой" элемент - Dummy
Код: AutoIt [Выделить]
...
;$BTHIDE = GUICtrlCreateButton("TMR4", 260, 145, 100, 25)
$BTHIDE = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "_TMR4")
;GUICtrlSetState($BTHIDE, $GUI_HIDE)
...
      ;ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "")
      GUICtrlSendToDummy($BTHIDE)
...

Название: Re: Режим OnEvent и приоритетность
Отправлено: Alofa от Январь 20, 2017, 23:00:41
... Мда... Alofa, амбициозность неистребима...
Причем тут амбиции, это еще один вариант.
Вы спросили совета - вам его их дали. Самый главный из них мне кажется этот:
... в этом режиме функция AdlibRegister не может прервать функцию-обработчик события. А в режиме MessageLoop всё наоборот.
Вы же уперлись в этот OnEvent и пытаетесь подойти к решению проблемы с задней стороны.

P.s: К стати, там подправил.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 20, 2017, 23:43:00
Alofa
Я тоже умею читать справку ;) и знаю, что делает WM_COMMAND. Меня смутило сообщение WM_GETTEXT, которое отлавливает SpyXX. Но, похоже, данное сообщение отправляет сам AutoIt, когда работаем с элементами его же окна. Потому что, если отправить WM_COMMAND "снаружи" (из другого приложения), то никакие WM-сообщения элементу не поступают.

VadimKHL
Цитировать
что нужно вписать в последнее поле функции ControlCommand, которое CommandID
Ничего не нужно. В этом сообщении передаётся дескриптор элемента и этого достаточно.

Цитировать
хочу сделать так, что бы даже кнопку скрытую добавлять не нужно было
Режим OnEvent рассчитан на элементы GUI, поэтому всё равно его (элемент) нужно добавлять. Но можно добавить "пустой" элемент - Dummy
Код: AutoIt [Выделить]
...
;$BTHIDE = GUICtrlCreateButton("TMR4", 260, 145, 100, 25)
$BTHIDE = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "_TMR4")
;GUICtrlSetState($BTHIDE, $GUI_HIDE)
...
      ;ControlCommand($WINGUI, "", "TMR4", "SendCommandID", "")
      GUICtrlSendToDummy($BTHIDE)
...


Действительно работает. Интересно, почему такой вариант в начале темы не предложили :) Я бы две недели не рвал волосы на голове.
Но вопрос, если надо событий с разными временами, допустим одно событие каждые 10 секунд, другое 100 мс.
Как тогда различать "ПУСТЫШЕК"?

И очень интересно, мой найденный вариант с ControlCommand, это просто баг и случайность или имеет место жить?
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 20, 2017, 23:54:05
VadimKHL
Цитировать
Как тогда различать "ПУСТЫШЕК"?
Как и любых других элементов - по идентификатору.

Цитировать
или имеет место жить?
Для кнопки допустимо, т.к. она не меняет своё состояние, в отличие, например, от CheckBox.
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 21, 2017, 00:14:59
VadimKHL
Цитировать
Как тогда различать "ПУСТЫШЕК"?
Как и любых других элементов - по идентификатору.

Цитировать
или имеет место жить?
Для кнопки допустимо, т.к. она не меняет своё состояние, в отличие, например, от CheckBox.

Большое спасибо за помощь. Без Ваших наводок я думаю не справился.
Но зато я своей тупостью/упортостью нашел новое использование ControlCommand, о котором не знали даже "ГУРУ".
(сам себя не похвалишь, ...)

У меня мозг заточен под 8 бит, ассемблер, для МК PIC, и все прерывания должны быть под моим контролем :)


Добавлено: Январь 21, 2017, 00:46:17
... Мда... Alofa, амбициозность неистребима...
Причем тут амбиции, это еще один вариант.
Вы спросили совета - вам его их дали. Самый главный из них мне кажется этот:
... в этом режиме функция AdlibRegister не может прервать функцию-обработчик события. А в режиме MessageLoop всё наоборот.
Вы же уперлись в этот OnEvent и пытаетесь подойти к решению проблемы с задней стороны.

P.s: К стати, там подправил.

Подправили. Не работает. Если нажать кнопку когда выключен OnEvent клик пользователя остается не обработанным.
Плохо подправили :)

Почему я уперся в Event?
Да потому что кнопок сейчас 15, а завтра захочу добавить еще 10. Потом еще 10.
Да и еще привык работать с прерываниями, только конечно на микроконтроллерах. Я мыслю логикой МК, и зная, а точнее делаю так, что бы он соблюдал свои протоколы передачи данных (время, задержки, контрольные суммы и т.д.), успевая делать остальные свои работы кроме переферии.
Вроде пока получается..., с Вашей помощью, форумчани.
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 21, 2017, 01:07:53
OffTopicVadimKHL
Цитировать
о котором не знали
Знали, только применяли "с другой стороны": получали, а не отправляли :)
Пустой последний параметр отправляет кнопке 0, что для неё значит $BN_CLICKED (меня нажали), о чём она и сообщала своему окну. Всё просто.
Название: Re: Режим OnEvent и приоритетность
Отправлено: Alofa от Январь 21, 2017, 01:13:25
OffTopicInnI
(нажмите для показа/скрытия)

VadimKHL
(нажмите для показа/скрытия)
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 21, 2017, 01:25:23
OffTopicVadimKHL
Цитировать
о котором не знали
Знали, только применяли "с другой стороны": получали, а не отправляли :)
Пустой последний параметр отправляет кнопке 0, что для неё значит $BN_CLICKED (меня нажали), о чём она и сообщала своему окну. Всё просто.

Спасибо.  $BN_CLICKED


Добавлено: Январь 21, 2017, 01:31:15
У меня прям слов нет, я сечас напишу поэзию


Добавлено: Январь 21, 2017, 01:31:49
но поэзии нет нет


Добавлено: Январь 21, 2017, 01:33:37
Можно к новеньким как то нормально относиться?
Название: Re: Режим OnEvent и приоритетность
Отправлено: Alofa от Январь 21, 2017, 01:52:20
OffTopicVadimKHL
(нажмите для показа/скрытия)
Название: Re: Режим OnEvent и приоритетность
Отправлено: InnI от Январь 21, 2017, 03:17:28
Alofa
OffTopic
(нажмите для показа/скрытия)
Название: Re: Режим OnEvent и приоритетность
Отправлено: VadimKHL от Январь 21, 2017, 17:08:30
OffTopic Alofa, все ок.


Добавлено: Январь 21, 2017, 17:44:06
Да, ну конечно самое "красивое" решение данной темы считаю вот этим (использование GUICtrlCreateDummy, GUICtrlSendToDummy и таймера):

Код: AutoIt [Выделить]
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

Opt("GUIOnEventMode", 1) ; Включить режим отслеживания событий GUI.

; ====================================================================================================================
; Создаем визуальное окно и объекты в нем.
; ====================================================================================================================

; Создать визуальное окно.
$WINGUI = GUICreate("TEST", 470, 245, -1, -1, BitOr($WS_POPUP, $WS_BORDER))

; Информауионные строки.
$lbTMR1 = GUICtrlCreateLabel("TMR1:", 10, 10, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR2 = GUICtrlCreateLabel("TMR2:", 10, 25, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR3 = GUICtrlCreateLabel("TMR3:", 10, 40, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR4 = GUICtrlCreateLabel("TMR4:", 10, 55, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

$idTMR1 = GUICtrlCreateLabel("0", 55, 10, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR2 = GUICtrlCreateLabel("0", 55, 25, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR3 = GUICtrlCreateLabel("0", 55, 40, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR4 = GUICtrlCreateLabel("0", 55, 55, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

; Кнопки.
GUICtrlCreateButton("TMR1", 260, 70, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR1")
GUICtrlCreateButton("TMR2", 260, 95, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR2")
GUICtrlCreateButton("TMR3", 260, 120, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR3")
$BTDUMMY = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "_TMR4")

; Системные события.
GUISetOnEvent($GUI_EVENT_CLOSE, "_CLOSEEvent")
GUISetState(@SW_SHOW, $WINGUI)

Global $TMRUPDATE = TimerInit()

While 1
   If TimerDiff($TMRUPDATE) > 100 Then
      $TMRUPDATE = TimerInit()
      GUICtrlSendToDummy($BTDUMMY)
   EndIf
WEnd

Func _TMR1()
   For $TMR1 = 1 To 5
      GUICtrlSetData ($idTMR1, $TMR1)
      sleep (500)
   Next
EndFunc

Func _TMR2()
   For $TMR2 = 1 To 5
      GUICtrlSetData ($idTMR2, $TMR2)
      sleep (500)
   Next
EndFunc

Func _TMR3()
   For $TMR3 = 1 To 5
      GUICtrlSetData ($idTMR3, $TMR3)
      sleep (500)
   Next
EndFunc

Func _TMR4()
   For $TMR4 = 1 To 5
      GUICtrlSetData ($idTMR4, $TMR4)
      sleep (500)
   Next
EndFunc

; ====================================================================================================================
; Функции системных событий.
; ====================================================================================================================
Func _CLOSEEvent()
    Exit
EndFunc