Что нового

Запрет выхода или выполнения каких-либо действий во время работы программы

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Иногда бывает так, что Ваша программа, при нажатии на определенную кнопку в окне, должна произвести какие-либо важные действия, которые выполняются некоторое время (например, ищет файлы, записывает что-нибудь в файл и т.д. В моем примере возводит в куб числа от 1 до 100 с полу-секундной паузой) и эти действия крайне не желательно прерывать. Можно дезактивировать окно или его элементы в начале действий и активировать в конце:
Код:
;начало действий
GUISetState(@SW_DISABLE, $hGui)
;или
GUICtrlSetState($nID, $GUI_DISABLE)
;действия
GUISetState(@SW_ENABLE, $hGui)
;или
GUICtrlSetState($nID, $GUI_ENABLE)

Я предлагаю другой способ, основанный на обработке WM-сообщений Вашего окна.
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <MenuConstants.au3>
#include <WinAPI.au3>

Opt('MustDeclareVars', 1)
Opt('TrayMenuMode', 1)

Global $fPause, $fWork, $hGui, $nLabelInfo, $nLabelGo, $nLabelPause, $nLabelExit, $nButtonGo, $nButtonPause, $nButtonExit

If WinExists(@ScriptName & '{[/@$@\]}') Then Exit
AutoItWinSetTitle(@ScriptName & '{[/@$@\]}')

$hGui = GUICreate('Test', 400, 115)
$nLabelInfo = GUICtrlCreateLabel('', 100, 12, 200, 15, $SS_CENTER)
$nLabelGo = GUICtrlCreateLabel('', 10, 72, 120, 30, $SS_CENTER)
$nLabelPause = GUICtrlCreateLabel('', 140, 72, 120, 30, $SS_CENTER)
$nLabelExit = GUICtrlCreateLabel('', 270, 72, 120, 30, $SS_CENTER)
For $i = $nLabelInfo To $nLabelExit
	GUICtrlSetBkColor($i, 0xD2D2D2)
Next
$nButtonGo = GUICtrlCreateButton('Вперед', 10, 40, 120, 30)
$nButtonPause = GUICtrlCreateButton('Пауза', 140, 40, 120, 30)
$nButtonExit = GUICtrlCreateButton('Выход', 270, 40, 120, 30)
GUISetState()
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')
GUIRegisterMsg($WM_SYSCOMMAND, 'WM_SYSCOMMAND')

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE, $nButtonExit
			Exit
		Case $nButtonGo
			$fWork = True
			$fPause = False
			GUICtrlSetData($nLabelGo, 'Работаем')
			GUICtrlSetData($nLabelPause, 'Нет паузы')
			For $i = 1 To 100
				While $fPause
					Sleep(10)
				WEnd
				GUICtrlSetData($nLabelInfo, StringFormat('%d ^ %d = %d', $i, 3, $i ^ 3))
				Sleep(500)
			Next
			$fWork = False
			For $i = $nLabelGo To $nLabelExit
				GUICtrlSetData($i, '')
			Next
	EndSwitch
WEnd

Func WM_SYSCOMMAND($hWnd, $iMsg, $iwParam, $ilParam)
	Local $n_ID = BitAND($iwParam, 0xFFFF)

	Switch $hWnd
		Case $hGui
			Switch $n_ID
				Case $SC_CLOSE
					If $fWork Then
						_WinAPI_MessageBeep(2)
						GUICtrlSetData($nLabelExit, 'Нельзя выходить во время работы')
						Return 1
					EndIf
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SYSCOMMAND

Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
	Local $n_ID = BitAND($iwParam, 0xFFFF)

	Switch $hWnd
		Case $hGui
			Switch $n_ID
				Case $nButtonGo
					If $fWork Then
						_WinAPI_MessageBeep(2)
						GUICtrlSetData($nLabelGo, 'Не надо меня тыкать, я уже работаю')
						Return 1
					EndIf
				Case $nButtonPause
					If Not $fWork Then
						_WinAPI_MessageBeep(2)
						GUICtrlSetData($nLabelPause, 'И где я должен сделать паузу7')
						Return 1
					EndIf
					$fPause = Not $fPause
					If $fPause Then
						GUICtrlSetData($nButtonPause, 'Продолжить')
						GUICtrlSetData($nLabelPause, 'Пауза в работе, перекур')
					Else
						GUICtrlSetData($nButtonPause, 'Пауза')
						GUICtrlSetData($nLabelPause, 'Нет паузы, перекур окончен')
					EndIf
				Case $nButtonExit
					If $fWork Then
						_WinAPI_MessageBeep(2)
						GUICtrlSetData($nLabelExit, 'Нельзя выходить во время работы')
						Return 1
					EndIf
			EndSwitch
	EndSwitch
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
madmasles
а в чем преимущество?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
madmasles [?]
А про преимущество я ничего не говорил
я имел в виду, раз есть два варианта реализации одного и того же, но один короче и понятнее другого, то для использования последнего нужно неоспоримое преимущество, помимо спортивного интереса :smile:
в моем примере в паузе.
честно говоря, я не понял как пауза может быть преимуществом ;D
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Это можно сделать через GUIOnEventMode:

Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>

Opt('MustDeclareVars', 1)
Opt('TrayMenuMode', 1)

Global $fPause, $fWork, $hGui, $nLabelInfo, $nLabelGo, $nLabelPause, $nLabelExit, $nButtonGo, $nButtonPause, $nButtonExit

If WinExists(@ScriptName & '{[/@$@\]}') Then Exit
AutoItWinSetTitle(@ScriptName & '{[/@$@\]}')

$hGui = GUICreate('Test', 400, 115)

$nLabelInfo = GUICtrlCreateLabel('', 100, 12, 200, 15, $SS_CENTER)
$nLabelGo = GUICtrlCreateLabel('', 10, 72, 120, 30, $SS_CENTER)
$nLabelPause = GUICtrlCreateLabel('', 140, 72, 120, 30, $SS_CENTER)
$nLabelExit = GUICtrlCreateLabel('', 270, 72, 120, 30, $SS_CENTER)

For $i = $nLabelInfo To $nLabelExit
	GUICtrlSetBkColor($i, 0xD2D2D2)
Next

$nButtonGo = GUICtrlCreateButton('Вперед', 10, 40, 120, 30)
$nButtonPause = GUICtrlCreateButton('Пауза', 140, 40, 120, 30)
$nButtonExit = GUICtrlCreateButton('Выход', 270, 40, 120, 30)

GUISetState()

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE, $nButtonExit
			Exit
		Case $nButtonGo
			$fWork = True
			$fPause = False
			
			Opt('GUIOnEventMode', 1)
			
			GUISetOnEvent($GUI_EVENT_CLOSE, "_Events")
			
			For $ID = $nLabelInfo To $nButtonExit
				GUICtrlSetOnEvent($ID, "_Events")
			Next
			
			GUICtrlSetData($nLabelGo, 'Работаем')
			GUICtrlSetData($nLabelPause, 'Нет паузы')
			
			For $i = 1 To 100
				While $fPause
					Sleep(10)
				WEnd
				
				GUICtrlSetData($nLabelInfo, StringFormat('%d ^ %d = %d', $i, 3, $i ^ 3))
				Sleep(500)
			Next
			
			$fWork = False
			
			For $i = $nLabelGo To $nLabelExit
				GUICtrlSetData($i, '')
			Next
			
			Opt('GUIOnEventMode', 0)
	EndSwitch
WEnd

Func _Events()
	Local $n_ID = @GUI_CtrlId
	Local $hWnd = @GUI_WinHandle
	
	Switch $hWnd
		Case $hGui
			Switch $n_ID
				Case $nButtonGo
					If $fWork Then
						_WinAPI_MessageBeep(2)
						GUICtrlSetData($nLabelGo, 'Не надо меня тыкать, я уже работаю')
						Return 1
					EndIf
				Case $nButtonPause
					If Not $fWork Then
						_WinAPI_MessageBeep(2)
						GUICtrlSetData($nLabelPause, 'И где я должен сделать паузу7')
						Return 1
					EndIf
					
					$fPause = Not $fPause
					
					If $fPause Then
						GUICtrlSetData($nButtonPause, 'Продолжить')
						GUICtrlSetData($nLabelPause, 'Пауза в работе, перекур')
					Else
						GUICtrlSetData($nButtonPause, 'Пауза')
						GUICtrlSetData($nLabelPause, 'Нет паузы, перекур окончен')
					EndIf
				Case $GUI_EVENT_CLOSE, $nButtonExit
					If Not $fPause Then
						_WinAPI_MessageBeep(2)
						GUICtrlSetData($nLabelExit, 'Нельзя выходить во время работы')
						Return 1
					Else
						Exit
					EndIf
			EndSwitch
	EndSwitch
EndFunc
 
Верх