Что нового

Макро AutoIT

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Можно ли в АИ создавать свои макро? Искал тут, честно! "Пользовательские макро" и "макро", но поиск захламлен темами про игры.

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

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
1. макро - это функция не принимающая параметров. Всё. Пиши функцию, получится макро.
2. Глобальные переменные видны везде (искключение, если в функции локальная с тем же именем). Ссылка
 

sims

Осваивающий
Сообщения
184
Репутация
24
Macro, он же макрос, это не функция. Это автоматизированный копипаст. https://ru.wikipedia.org/wiki/Макрокоманда
В языках ассемблера, а также в некоторых других языках программирования, макрос — символьное имя, заменяемое при обработке препроцессором на последовательность программных инструкций.
 
Автор
C

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Ок, а как тогда мне сделать так, чтобы функция SomeFunc() обрабатывала кучу элементов GUI? давайте проверьте меня:
1. создаю все GUICtrl как Global.
2. в теле функции в самом начале пишу Gobal ***,**,**,**,*,*,* ?

Пробовал писать в теле функции без global, но интерпретатор всегда предупреждение выкидывает, что переменная не объявлена, я тут же пугаюсь и закрываю окно Scite
 

InnI

AutoIT Гуру
Сообщения
4,982
Репутация
1,460
Core2Duo76, давайте лучше на примере.
Код:
HotKeySet("{F1}", "SomeFunc")

GUICreate("gui")
Global $button, $edit, $label, $var = 10
$button = GUICtrlCreateButton("button", 10, 10, 50, 20)
$edit = GUICtrlCreateEdit("edit", 10, 40, 100, 100)
$label = GUICtrlCreateLabel("label", 10, 150, 50, 20)
GUISetState()

Do
Until GUIGetMsg() = -3

Func SomeFunc()
  GUICtrlSetData($button, "кнопка")
  GUICtrlSetData($edit, "редактор")
  GUICtrlSetData($label, $var)
EndFunc
Поясните, что не понятно в этом примере. Или приведите свой пример.
 
Автор
C

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Вот! Вот именно так я и сделал! Но функцию вынес в файл (мне удобно держать все функции в отдельном файле, потому что главный скрипт огромен просто), в таком случаю интерпретатор говорит, что я использую не объявленные переменные, но скрипт запускает. Когда таких функции в файле много, то ошибок вылезает по одной на каждую. Написал в теле каждой функции Global *,*,*,* и ошибок не падает.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
Core2Duo76 [?]
функцию вынес в файл
Func.au3:
Код:
#include-once
#include <GUIConstantsEx.au3>

Global $hGui, $iButton, $iEdit, $iLabel, $iLang = 0

Func _GUICreate()
	$hGui = GUICreate('', 200, 200)
	$iButton = GUICtrlCreateButton('', 10, 10, 50, 20)
	$iEdit = GUICtrlCreateEdit('', 10, 40, 100, 100)
	$iLabel = GUICtrlCreateLabel('', 10, 150, 50, 20)
	_MyFunc()
	GUISetState()
EndFunc   ;==>_GUICreate

Func _GUIEvent()
	While 1
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				GUIDelete()
				Return
			Case $iButton
				_MyFunc()
		EndSwitch
	WEnd
EndFunc   ;==>_GUIEvent

Func _MyFunc()
	Local $a_Str[4][2] = [['Окно', 'Gui'],['кнопка', 'button'],['редактор', 'edit'],['надпись', 'label']]

	$iLang = Not $iLang
	WinSetTitle($hGui, '', $a_Str[0][$iLang])
	GUICtrlSetData($iButton, $a_Str[1][$iLang])
	GUICtrlSetData($iEdit, $a_Str[2][$iLang])
	GUICtrlSetData($iLabel, $a_Str[3][$iLang])
EndFunc   ;==>_MyFunc
Script.au3:
Код:
#include 'Func.au3'

Do
_GUICreate()
_GUIEvent()
Until MsgBox(36, 'Question', 'Next?') = 7
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
Core2Duo76 [?]
Написал в теле каждой функции Global
В теле функции Global не пишут. Лично я использовал это только для окна About, потому что его будут вызывать 1 раз к 1000 и зачем скрипту обрабатывать неиспользуемое при старте. А для внешних функций (UDF) это вообще нонсенс.

главный скрипт огромен просто
Главное чтобы он изначально был правильно написан. Если функция использует глобальные переменные то они должны быть объявлены до строки включения в файл. Если глобальные используются только этой функцией, то их можно вынести во внешний файл (UDF), а если нет, то хоть и может не вылетать ошибка то это всё равно структурно не правильно.

Пробовал писать в теле функции без global, но интерпретатор всегда предупреждение выкидывает, что переменная не объявлена, я тут же пугаюсь и закрываю окно Scite
Потому что переменная внутри функции без global создаётся локальной, если её ещё нет и в глобальной области видимости и другие функции эту переменную не видят, если она используется в функции вызванной из этой функции.

Если нельзя, то я хотел бы проконсультироваться про глобальные переменные. Если в начале скрипта я задаю одну такую, то при запуске функции из файла через include эта переменная внутри функции будет иметь то же значение???
Глобальная переменная должна быть объявлена раньше include. Хоть тут конечно важнее точка вызова функции, но как то логически спокойнее, если функция использующая глобальную переменную объявляется после переменной которую она использует. Библиотеки же используемые в include пишут всё в себе, то есть глобальные пишутся в самой include и используются только самой include.
Представь что вместо include вставится сам файл, вот так оно и будет реально работать. Переменная внутри функции будет иметь тоже самое значение, если она не объявлена в функции как локальная и если вызов функции сделан после объявления глобальной переменной. А так как у вас тенденция объявлять глобальную внутри функции, то естественно другие функции не увидят эту переменную, пока не сработает функция с объявлением глобальной переменной. Отсюда вывод: глобальные переменные объявляются в начале скрипта, а не внутри функции.


sims
Мы разбираем в рамках AutoIT. В Си при компиляции делается замена, а мы тут то не компилируем. И даже если это так или было бы так, то всё равно это аналог функции. В Си после компиляции все дефлайны уже заменены своими конструкциями. Возьми функцию получи с неё указатель, допиши а начало @ м чем это будет отличаться? Спор ради спора опять.
 

sims

Осваивающий
Сообщения
184
Репутация
24
AZJIO [?]
И даже если это так или было бы так, то всё равно это аналог функции.
Макрос работает не как функция.
Функция позволяет вызывать один и тот же код из разных мест программы. При этом адрес возврата хранится в стеке.
Макрос вставляет копию кода в каждое место вызова. Стек не используется.
Понимаете в чем разница?
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
sims
Макрос вставляет копию кода в каждое место вызова. Стек не используется.
Понимаете в чем разница?
С чего вы взяли что AutoIt действует именно так? Даже если это так или было бы так, автору вопроса собственно ровно как внутренне устроен механизм, важно как сделать это синтаксически одинаково просто, указав ключевое слово, получить в точку вызова результат. Если AutoIt не предоставляет внутри кода конструировать макрос (да и зачем), то он может быть легко эмулирован функцией, и кому какая разница как это будет происходить под ковром.
 
Автор
C

Core2Duo76

Новичок
Сообщения
58
Репутация
1
Давайте подеритесь еще) про меня совсем и забыли!
Я сделал, как вы писали - все работает. НО! когда я корректирую файл и функциями, то при проверке кода куча предупреждений сыплется. Неудобно такое поведение, а в главном скрипте все норм.
 

InnI

AutoIT Гуру
Сообщения
4,982
Репутация
1,460
Core2Duo76
Если у вас глобальные переменные объявлены в главном скрипте, а используются в подключаемых файлах, то проверку подключаемого файла нужно производить путём запуска главного скрипта. Но есть и решения этой проблемы.

1. В подключаемых файлах использовать функцию IsDeclared()
Код:
If Not IsDeclared("var") Then Global $var = "!!!"


2. Вынести все глобальные переменные в отдельный файл с директивой #include-once и в каждом подключаемом файле подключить этот файл
Код:
#include "GlobalVars.au3"


3. Использовать #forcedef - скрипт будет проходить проверку, но не будет выполняться
Код:
Func test()
  #forcedef $var
  ConsoleWrite($var & @CRLF)
EndFunc
 
Верх