В чем такая увереность?Всё работает
Всё работает
Это не автопауза. Это прерывание работы скрипта для обработки всплывающего меню.Щас сделаю видео...
AdlibRegister("Plus")
HotKeySet("{ESC}", "Quit")
Opt("TrayAutoPause", 0)
GUICreate("")
GUICtrlCreateMenuItem("Test", GUICtrlCreateContextMenu())
GUISetState()
While Sleep(111)
ConsoleWrite(".")
WEnd
Func Quit()
Exit
EndFunc
Func Plus()
ConsoleWrite("+")
EndFunc
Это не автопауза. Это прерывание работы скрипта для обработки всплывающего меню.
Запустите этот скрипт из SciTE и кликните ПКМ по окну или по иконке в трее. При появлении меню вывод в консоль SciTE будет остановлен. Даже AdlibRegister не работает.
Указывает останавливать ли работу скрипта самим нажатием на иконку в трее.что делает эта автопауза которая управляется через Opt("TrayAutoPause", X) ?
Использовать таймеры для обновления информации (не рекомендуется сильно нагружать функцию таймера)...Как тогда не останавливать скрипт при трей меню?
#include <Timers.au3>
HotKeySet('{ESC}', '_Quit')
Opt('TrayAutoPause', 0)
Opt('TrayMenuMode', 3)
$iProgress = 0
$iLoading_TrayItem = TrayCreateItem('Loading: 0')
$iExit_TrayItem = TrayCreateItem('Exit')
TraySetClick(16)
TraySetState(1)
_Timer_SetTimer(0, 100, '_Update')
While 1
Switch TrayGetMsg()
Case $iExit_TrayItem
_Quit()
EndSwitch
WEnd
Func _Quit()
Exit
EndFunc
Func _Update($hWnd, $iMsg, $iIDTimer, $iTime)
$iProgress += 0.1
If $iProgress > 100 Then
$iProgress = 0
EndIf
TrayItemSetText($iLoading_TrayItem, 'Loading: ' & Round($iProgress, 2) & '%')
EndFunc
#include <Timers.au3>
HotKeySet('{ESC}', '_Quit')
Opt('TrayAutoPause', 0)
Opt('TrayMenuMode', 3)
GUICreate("Test", 300, 300, -1, -1)
GUISetState(@SW_SHOW)
Global $Label = GUICtrlCreateLabel("", 50, 50, 100, 15)
Global $Label2 = GUICtrlCreateLabel("", 50, 65, 100, 15)
$iProgress = 0
$iProgress2 = 0
$iLoading_TrayItem = TrayCreateItem('Loading: 0')
$iExit_TrayItem = TrayCreateItem('Exit')
TraySetClick(16)
TraySetState(1)
_Timer_SetTimer(0, 100, '_Update')
While 1
Switch TrayGetMsg()
Case $iExit_TrayItem
_Quit()
EndSwitch
$iProgress2 += 0.1
If $iProgress2 > 100 Then
$iProgress2 = 0
EndIf
GUICtrlSetData($Label, 'Loading: ' & Round($iProgress2, 2) & '%')
sleep(100)
WEnd
Func _Quit()
Exit
EndFunc
Func _Update($hWnd, $iMsg, $iIDTimer, $iTime)
$iProgress += 0.1
If $iProgress > 100 Then
$iProgress = 0
EndIf
TrayItemSetText($iLoading_TrayItem, 'Loading: ' & Round($iProgress, 2) & '%')
GUICtrlSetData($Label2, 'Loading: ' & Round($iProgress, 2) & '%')
EndFunc
Использовать таймеры для обновления информации (не рекомендуется сильно нагружать функцию таймера)...
#include <Timers.au3>
#include <WinAPI.au3>
HotKeySet('{ESC}', '_Quit')
Opt('TrayAutoPause', 0)
Opt('TrayMenuMode', 3)
GUICreate("Test", 300, 300, -1, -1)
GUISetState(@SW_SHOW)
Global $Label = GUICtrlCreateLabel("", 50, 50, 100, 15)
$iProgress = 0
$iLoading_TrayItem = TrayCreateItem('Loading: 0')
$iExit_TrayItem = TrayCreateItem('Exit')
TraySetClick(16)
TraySetState(1)
; Настройки Tray меню при помощи WinAPI.
; https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setmenuinfo
Global Const $MIM_APPLYTOSUBMENUS = 0x80000000
Global Const $MIM_STYLE = 0x00000010
Global Const $MNS_AUTODISMISS = 0x10000000
Global Const $MNS_MODELESS = 0x40000000
; Общие установки для всего меню.
Local $hMenu = TrayItemGetHandle(0)
Local $tMenuInfo = DllStructCreate($tagMENUINFO)
DllStructSetData($tMenuInfo, 1, DllStructGetSize($tMenuInfo))
; Записать параметры dwStyle.
DllStructSetData($tMenuInfo, 2, BitOR($MIM_APPLYTOSUBMENUS, $MIM_STYLE))
; Автоматическое закрытие меню через ~10 сек. Режим MODELESS.
DllStructSetData($tMenuInfo, 3, BitOR($MNS_AUTODISMISS, $MNS_MODELESS))
DllCall("user32.dll", "int", "SetMenuInfo", "hwnd", $hMenu, "struct*", $tMenuInfo)
While 1
Switch TrayGetMsg()
Case $iExit_TrayItem
_Quit()
EndSwitch
$iProgress += 0.1
If $iProgress > 100 Then
$iProgress = 0
EndIf
TrayItemSetText($iLoading_TrayItem, 'Loading: ' & Round($iProgress, 2) & '%')
GUICtrlSetData($Label, 'Loading: ' & Round($iProgress, 2) & '%')
sleep(100)
WEnd
Func _Quit()
Exit
EndFunc
Любая callback-функция должна возвращать как можно быстрее, иначе могут быть непредвиденные последствия.что значит сильно не нагружать?
Вот в общем в чем проблема режима MODELESS:Есть еще один вариант, режим MODELESS.
Гляньте пример, скрипт не останавливается:
Например не желательно использовать MsgBox внутри этой функции.
#include <Timers.au3>
HotKeySet('{ESC}', '_Quit')
Opt('TrayAutoPause', 0)
Opt('TrayMenuMode', 3)
$iProgress = 0
$iLoading_TrayItem = TrayCreateItem('Loading: 0')
$iExit_TrayItem = TrayCreateItem('Exit')
TraySetClick(16)
TraySetState(1)
_Timer_SetTimer(0, 100, '_Update')
While 1
Switch TrayGetMsg()
Case $iExit_TrayItem
_Quit()
EndSwitch
WEnd
Func _Quit()
Exit
EndFunc
Func _Update($hWnd, $iMsg, $iIDTimer, $iTime)
$iProgress += 0.1
If $iProgress > 100 Then
$iProgress = 0
EndIf
TrayItemSetText($iLoading_TrayItem, 'Loading: ' & Round($iProgress, 2) & '%')
; Эта функция имеет неизвестное время выполнения, каждый раз разное.
; К примеру, это выполняется дольше, чем частота вызова по таймеру.
Sleep(150)
; Это приводит к зависанию.
EndFunc
Не использовать паузу в функции таймера, я же выше писал об этом.Как сделать, что бы не было зависаний от использования таймеров?
А это не пауза. Это неизвестное время выполнения кода, чтения данных по COM порту.Не использовать паузу в функции таймера, я же выше писал об этом.
Мне незачем обновлять информацию, пока не выполню пункт выше. Как помещать события в очередь?Это полезно для обновления информации, и всё, во всех остальных случаях нужно обрабатывать события помещая их в очередь (массив к примеру).
В этом случае лучше тогда вынести часть чтения данных в отдельный скрипт.Это неизвестное время выполнения кода, чтения данных по COM порту
#include <Timers.au3>
HotKeySet('{ESC}', '_Quit')
Opt('TrayAutoPause', 0)
Opt('TrayMenuMode', 3)
$bUpdate = True
$iProgress = 0
$iLoading_TrayItem = TrayCreateItem('Loading: 0')
$iExit_TrayItem = TrayCreateItem('Exit')
TraySetClick(16)
TraySetState(1)
$iTimer = _Timer_SetTimer(0, 100, '_Update')
While 1
Switch TrayGetMsg()
Case $iExit_TrayItem
_Quit()
EndSwitch
WEnd
Func _Quit()
Exit
EndFunc
Func _Update($hWnd, $iMsg, $iIDTimer, $iTime)
If $bUpdate Then
AdlibRegister('_GetData', 10)
EndIf
EndFunc
Func _GetData()
$bUpdate = False
AdlibUnRegister('_GetData')
; Тут выполняем то что нужно
;-------------------------
$iProgress += 0.1
If $iProgress > 100 Then
$iProgress = 0
EndIf
TrayItemSetText($iLoading_TrayItem, 'Loading: ' & Round($iProgress, 2) & '%')
;-------------------------
$bUpdate = True
EndFunc