Что нового

[Элементы GUI] Как построить обработку через OnEvents

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Скажите, пожалуйта, как при использовании OnEvent прописать функцию с параметром?
Код:
Func _ShowWindow()

For $iCount = 1 To $iFlags
	$aFlags[$iCount][0] = StringRegExpReplace($aFileFlag[$iCount],",.*","$1") ;тикер из файла ini
	$aFlags[$iCount][1] = StringRegExpReplace($aFileFlag[$iCount],".*,","$1") ;путь до файла ключа
	$aFlags[$iCount][2] = FileReadLine($aFlags[$iCount][1],1)                     ;значение флага - True или False
	$aFlags[$iCount][3] = GUICtrlCreateButton($aFlags[$iCount][0],1,($iCount-1)*25+1,400); кнопка
	GUICtrlSetOnEvent($aFlags[$iCount][3],"_PressButton")
	$aFlags[$iCount][4] = FileGetTime($aFlags[$iCount][1],0,1)				  ;время последней записи в файл
	If $aFlags[$iCount][2] = "False"  Then GUICtrlSetBkColor($aFlags[$iCount][3],0xFF3333)
	If $aFlags[$iCount][2] = "True" Then GUICtrlSetBkColor($aFlags[$iCount][3],0x00CC33)

Next

EndFunc

А хочу, чтобы функция в GUICtrlSetOnEvent($aFlags[$iCount][3],"_PressButton")
стала вроде ,"_PressButton(параметр)"

И чтобы по этому параметру я мог обработать сигнал одной функцией, а не писать их несколько. Чтобы этот параметр и был для меня описанием кнопки.

Например создались 5 кнопок. И при нажатии на одну из них, вызывалась моя функция с параметром, указывающим на конкретную эту кнопку, чтобы я мог обработать именно её назначение.
 

Dm666

Осваивающий
Сообщения
220
Репутация
48
Как вариант, можно в функции обработать @GUI_CtrlHandle. Что-то такое, например:
Код:
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)

$Form1 = GUICreate("Form1", 623, 449, 192, 114)

$btn_1 = GUICtrlCreateButton("1", 10, 10, 145, 49)
$btn_2 = GUICtrlCreateButton("2", 10, 100, 145, 49)
$btn_Exit = GUICtrlCreateButton("Exit", 239, 376, 145, 49)

GUICtrlSetOnEvent($btn_1, "_Trigger")
GUICtrlSetOnEvent($btn_2, "_Trigger")
GUICtrlSetOnEvent($btn_Exit, "_Exit")
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

GUISetState(@SW_SHOW)

While 1
	Sleep(1000)
WEnd

Func _Exit()
	Exit
EndFunc

Func _Trigger()
	Switch @GUI_CtrlHandle
		Case ControlGetHandle($Form1, "", $btn_1)
			MsgBox(0, "", "Button1")
		Case ControlGetHandle($Form1, "", $btn_2)
			MsgBox(0, "", "Button2")
	EndSwitch
EndFunc
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
Dm666,
А чем @GUI_CtrlId не устраивает?
 

Dm666

Осваивающий
Сообщения
220
Репутация
48
madmasles [?]
А чем @GUI_CtrlId не устраивает?
Тем, что номера контролов могут изменится, если автор вдруг решит добавить новых элементов до обрабатываемых кнопок. Я как-то в такую засаду уже попадал, с тех пор @GUI_CtrlId недолюбливаю. Может я его просто готовить не умею, не знаю. А в @GUI_CtrlHandle я уверен. :smile:
 

Garrett

Модератор
Локальный модератор
Сообщения
3 999
Репутация
964
Dm666 [?]
Тем, что номера контролов могут изменится, если автор вдруг решит добавить новых элементов до обрабатываемых кнопок.
В @GUI_CtrlId всегда будет содержаться ID элемента, и не важно каким он стоит в ряду элементов управления, первым или последним. Разница между @GUI_CtrlId и @GUI_WinHandle только в том, что один содержит ID а второй Handle.

Код:
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)

$Form1 = GUICreate("Form1", 623, 449, 192, 114)

$btn1 = GUICtrlCreateButton("1", 10, 190, 145, 49)
$btn2 = GUICtrlCreateButton("2", 10, 100, 145, 49)
$btn3 = GUICtrlCreateButton("3", 10, 10, 145, 49)
$btn_Exit = GUICtrlCreateButton("Exit", 239, 376, 145, 49)

GUICtrlSetOnEvent($btn3, "_Trigger")
GUICtrlSetOnEvent($btn1, "_Trigger")
GUICtrlSetOnEvent($btn2, "_Trigger")

GUICtrlSetOnEvent($btn_Exit, "_Exit")
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

GUISetState(@SW_SHOW)

While 1
    Sleep(1000)
WEnd

Func _Exit()
    Exit
EndFunc

Func _Trigger()
    Switch @GUI_CTRLID
        Case $btn1
            MsgBox(0, "",  "Button1")
        Case $btn2
            MsgBox(0, "",  "Button2")
        Case $btn3
            MsgBox(0, "",  "Button3")
    EndSwitch
EndFunc
 
Автор
V

ViktorSPB

Новичок
Сообщения
109
Репутация
0
Добрый день.
Спасибо за ответы, конструкция с @GUI_CtrID и Switch почти заработала.
Почти, потому что работает не всегда, что-то не учел..
Вот что сделал:
Извините, что скрипт полностью кидаю, может ошибка моя не в OnEvent алгоритме..
Код:
#Include <File.au3>
#include <WindowsConstants.au3>
#Include <Array.au3>
#include <WinAPIEx.au3>
#include <GUIConstants.au3>

Opt("GUIOnEventMode", 1)
Dim $sFileFlag = @ScriptDir&"\Flags.ini"

If Not FileExists($sFileFlag) Then
    MsgBox(16, "Ошибка", "нет файла "&$sFileFlag)
    Exit
EndIf

Dim $iFlags = _FileCountLines ($sFileFlag)
Dim $aFileFlag[$iFlags]

If _FileReadToArray($sFileFlag,$aFileFlag) = 0 Then
	if @error = 2 Then MsgBox(16, "Ошибка", "нельзя разделить "&$sFileFlag)
EndIf
;_ArrayDisplay($aFileFlag,"Данные в ini")

Dim $aFlags[$iFlags+1][5]
Dim $bFlag
Dim $msg
$mainwindow = GUICreate("Состояние флагов экспорта",400,$iFlags*25)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
_ShowWindow()
GUISetState()
;_WinAPI_EmptyWorkingSet()
;_ArrayDisplay($aFlags,"Данные в ini полные вместе с флагами")

While 1
	For $iCountTime = 1 To $iFlags
		If $aFlags[$iCountTime][4] <> FileGetTime($aFlags[$iCountTime][1],0,1) Then _ShowWindow()
	Next
	Sleep(500)
WEnd

Exit

Func _ShowWindow()
	For $iCount = 1 To $iFlags
		$aFlags[$iCount][0] = StringRegExpReplace($aFileFlag[$iCount],",.*","$1") ;тикер из файла ini
		$aFlags[$iCount][1] = StringRegExpReplace($aFileFlag[$iCount],".*,","$1") ;путь до файла ключа
		$aFlags[$iCount][2] = FileReadLine($aFlags[$iCount][1],1)                     ;значение флага - True или False
		$aFlags[$iCount][3] = GUICtrlCreateButton($aFlags[$iCount][0],1,($iCount-1)*25+1,400); кнопка
		GUICtrlSetOnEvent($aFlags[$iCount][3],"_PressButton")
		$aFlags[$iCount][4] = FileGetTime($aFlags[$iCount][1],0,1)				  ;время последней записи в файл
		If $aFlags[$iCount][2] = "False"  Then GUICtrlSetBkColor($aFlags[$iCount][3],0xFF3333)
		If $aFlags[$iCount][2] = "True" Then GUICtrlSetBkColor($aFlags[$iCount][3],0x00CC33)
	Next
;GUISetState()
;Sleep(2000)
EndFunc

Func _PressButton()
	For $iCountFlags = 1 To $iFlags
		Switch @GUI_CtrlId
			Case $aFlags[$iCountFlags][3]
				If  $aFlags[$iCountFlags][2] = "True" Then $bFlag = True
				If  $aFlags[$iCountFlags][2] = "False" Then $bFlag = False
				;_FileWriteToLine($aFlags[$iCountFlags][1],1,Not $bFlag,1)
				;Sleep(500)
				ConsoleWrite($aFlags[$iCountFlags][0]&"="&Not $bFlag)
				;_ShowWindow()
				;Return
		EndSwitch
	Next
;_ShowWindow()
EndFunc

Func CLOSEClicked()
	;MsgBox(0, "GUI Event", "You clicked CLOSE! Exiting...")
	Exit
EndFunc


В чем проблема. Если скрипт в таком виде, то в консоль при клике на клавишу выдается корректное сообщение. Однако, если (жаль не подсвечиваются номера строк в скрипте, приходится описывать где находится то, о чем я говорю) в конце _PressButton запускаю _ShowWindow(), то сей скрипт один раз исполняется, один раз после нажатия отрабатывается событие и обработка кнопок умирает. Ни на что не реагирует, кроме закрытия. То есть, OnEvent режим в принципе остается в работе, но почему то вырубаются мои клавиши.
Похожая ситуация, если окрываю _FileWriteToLine($aFlags[$iCountFlags][1],1,Not $bFlag,1) даже без _ShowWindow() в конце. Один раз перезаписывает строку и опять все засыпает.. Должно же вроде работать, срабатывает прерывание, пошла обработка, вернулись в цикл.. не понимаю.

ВНИМАНИЕ!(не хочу зря тратить ваше время)
Удалось решить вопрос. Вывел в отдельную функцию назначение кнопок и все заработало. Если у вас есть время, то с благодарностью выслушаю критику на принцип построения скрипта. Только начинаю работать с AutoIt, надо сразу учиться правильному)
 

AZJIO

Меценат
Меценат
Сообщения
2 752
Репутация
1 149
ViktorSPB
Код:
If $aFlags[$iCountTime][4] <> FileGetTime($aFlags[$iCountTime][1],0,1) Then _ShowWindow()

Что эта строка означает? Если количество строк не равно времени полученному из файла, который на самом деле не файл? Ну или должен быть тестовый файл ini

Это всего лишь счётчик, не нужно такой длинный текст писать, это для имени массива но ни как не для счётчика, обычно $i

присвоение можно так записать
Код:
GUICtrlSetOnEvent(-1,"_PressButton")
        If $aFlags[$i][2] = "False"  Then GUICtrlSetBkColor(-1,0xFF3333)
        If $aFlags[$i][2] = "True" Then GUICtrlSetBkColor(-1,0x00CC33)


Вызов _ShowWindow() в цикле провоцирует создание кнопок друг на друге, целыми кучами. Надо либо удалять старые и создавать новые, либо само окно сделать в виде функции и пересоздавать его.

Код:
ConsoleWrite($aFlags[$iCountFlags][0]&"="&Not $bFlag&@CRLF)

Перенос строки добавил
 

Dm666

Осваивающий
Сообщения
220
Репутация
48
Garrett [?]
В @GUI_CtrlId всегда будет содержаться ID элемента, и не важно каким он стоит в ряду элементов управления, первым или последним. Разница между @GUI_CtrlId и @GUI_WinHandle только в том, что один содержит ID а второй Handle.
А... Вон оно как. Вот и разобрались, я действительно его готовить не умею :smile:
Я по необразованности вместо Case $btn1 использовал реальный ID контрола, который показывает ControlViewer, то есть писал Case 3. Естественно, что нумерация у меня после этого съезжала. :D
Теперь буду знать, спасибо. :ok:
 
Верх