Что нового

Несколько непонятных моментов в работе Autoit'а

mathem

Новичок
Сообщения
26
Репутация
0
Здравствуйте! Я хотел бы написать скрипт для автоматического ввода массива/матрицы в LaTeX'е, но столкнулся с несколькими непонятным для меня моментами. Не могли бы вы мне объяснить, в чем мои ошибки? Меня так же интересует, ошибаюсь ли я концептуально, т. е. так в принципе нельзя делать в автоите или все же можно, хоть и, возможно нежелательно: это признак дурного тона и т. д.

Первая проблема, которую я хотел бы обсудить, следующая. Вот я написал скрипт:
Код:
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#include <GUIConstants.au3>
#include <Misc.au3>

Global $GUI_1, $otmena_1, $ok_1, $otmena_2, $ok_2, $radio1, $radio2, $radio3, $vyrav, $abrakadabra

$GUI_0 = GUICreate("0Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов столбцов", 10, 5)
$ok_0 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
GUICtrlCreateGroup("", 200, 128, 92, 32)
$otmena_0 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$stolb = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($stolb, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $stolb)
GUISetState()

Global $a = 0

While 1
$msg = GUIGetMsg()
Switch $msg
   Case $GUI_EVENT_CLOSE
      ExitLoop
   Case $ok_0
      $a = $a-1
      ToolTip ($a, 0, 0)
   Case $otmena_0
      $a = $a+1
      ToolTip ($a, 0, 0)
EndSwitch
WEnd

Он работает так, как и было задумано, все хорошо. Там глобально объявляются переменные, которые я пропишу впоследствии. Но уже при попытке выполнения следующего скрипта
Код:
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#include <GUIConstants.au3>
#include <Misc.au3>

Global $GUI_1, $otmena_1, $ok_1, $otmena_2, $ok_2, $radio1, $radio2, $radio3, $vyrav, $abrakadabra

$GUI_0 = GUICreate("0Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов столбцов", 10, 5)
$ok_0 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
GUICtrlCreateGroup("", 200, 128, 92, 32)
$otmena_0 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$stolb = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($stolb, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $stolb)
GUISetState()

Func Massiv_1()
   GUIDelete($GUI_0)
   $GUI_1 = GUICreate("1Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов строк", 10, 5)
$ok_1 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
$otmena_1 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$strok = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($strok, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $strok)
GUISetState()
   EndFunc

Global $a = 0

While 1
$msg = GUIGetMsg()
Switch $msg
   Case $ok_0
        Massiv_1()
      Case $otmena_0
         $a = $a+1
         ToolTip ($a, 0, 0)
      Case $otmena_1
         $a = $a-1
         ToolTip ($a, 0, 0)
      EndSwitch
WEnd

Начинают происходить вещи, которые я местами могу понять лишь частично, а местами не понимаю и вовсе. А именно: при открытии первого окна число в тултипе начинает бешено убывать на 1. Но, мне кажется, я понимаю, почему это происходит: это из-за объявления $otmena_1 в самом начале. Правильно? Хотя вот сейчас я попробовал закомментировать эту кнопку в гуе 1 - так програ вообще перестала закрываться - тоже вещь для меня совершенно загадочная. Ладно. Допустим, эта кнопка не закомментена. Жму кнопку $ok_1. Число в тултипе останавливается, По нажатию кнопки $otmena_1 начинает на 1 уменьшаться, все ОК. Но... Програ перестает закрываться. А это почему так? Не могли бы вы мне пояснить?
 

Andr

Новичок
Сообщения
5
Репутация
2
Я тоже не понимаю почему это происходит. Таков верхний уровень чёрных ящиков...
Но такое объявление и использование переменной в бесконечном цикле обработки оконных сообщений - не логично.
Лучше перестроить программу.
Хотя может быть подойдёт решение создать кнопку $otmena_1 сразу в невидимой области выходящей за форму.
Не закрывается потому что нет "Case $GUI_EVENT_CLOSE".
Для отладки можно использовать _DebugSetup и _DebugOut.
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
592
Репутация
72
Програ перестает закрываться. А это почему так?
Потому что в первом коды вы написали обработчик закрытия окна, а во втором нет.

А именно: при открытии первого окна число в тултипе начинает бешено убывать на 1.
При старте программы какое значение в $otmena_1 и каким оно станет при нажатии ОК и выполнении функции Massiv_1()?
 
Автор
M

mathem

Новичок
Сообщения
26
Репутация
0
Не закрывается потому что нет "Case $GUI_EVENT_CLOSE".
Потому что в первом коды вы написали обработчик закрытия окна, а во втором нет.
Точно! Я и не обратил внимания: я и не мог этого допустить, потому что делал это через копи-паста. Спасибо большое. С этим разобрались.

При старте программы какое значение в $otmena_1 и каким оно станет при нажатии ОК и выполнении функции Massiv_1()?
Честно говоря, я не знал, что при старте прогры она вообще получает какое-либо значение. Соответственно и про значение после выполнения функции Massiv_1() она получает какое-то значение? Расскажите, пожалуйста.
Для отладки можно использовать _DebugSetup и _DebugOut.
Я как-то пробовал первую функцию, выводил в консоль. Но, честно говоря, инфа там мне мало что дала. Вторая выглядит как-то серьезнее Я попозже с ней покопаюсь. А пока гляньте, пжл. Я изменил код следующим образом:
Код:
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#include <GUIConstants.au3>
#include <Misc.au3>

Global $GUI_1, $otmena_1, $ok_1, $otmena_2, $ok_2, $radio1, $radio2, $radio3, $vyrav, $abrakadabra

$GUI_0 = GUICreate("0Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов столбцов", 10, 5)
$ok_0 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
GUICtrlCreateGroup("", 200, 128, 92, 32)
$otmena_0 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$stolb = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($stolb, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $stolb)
GUISetState()

Func Massiv_1()
   GUIDelete($GUI_0)
   WinWaitClose("0Ввод окружения array")
   $GUI_1 = GUICreate("1Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов строк", 10, 5)
$ok_1 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
$otmena_1 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$strok = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($strok, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $strok)
GUISetState()
   EndFunc

Global $a = 0

While 1
$msg = GUIGetMsg()
Switch $msg
      Case $GUI_EVENT_CLOSE
         ExitLoop
      Case $ok_0
        Massiv_1()
      Case $otmena_0
         $a = $a+1
         ToolTip ($a, 0, 0)
      Case $otmena_1
         $a = $a-1
         ToolTip ($a, 0, 0)
      EndSwitch
WEnd

Так теперь новое чудо. Да, программа стала закрываться из обоих окон. Но... После нажатия кнопки $ok_1 почему-то стало открываться повторно окно "1Ввод окружения array", хотя на эту кнопку ничего и не назначено. И каждый раз, когда нажимаешь в этом окне это кнопку, появляется новое окно "1Ввод окружения array". А вот нажатие этой кнопки в новых окнах, как и должно, ничего не дает. А это что такое??
Лучше перестроить программу.
Как???
 

Prog

Продвинутый
Сообщения
592
Репутация
72
Соответственно и про значение после выполнения функции Massiv_1() она получает какое-то значение?
Да, ведь выполняется строка.
Код:
$otmena_1 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)

После нажатия кнопки $ok_1 почему-то стало открываться повторно окно "1Ввод окружения array"
Как написали код так он и работает.
В функции Massiv_1() открывается новое окно, а где закрывается предыдущее, созданное прошлым вызовом этой же функции?
 
Автор
M

mathem

Новичок
Сообщения
26
Репутация
0
Не обрабатывайте события не существующих окон.
Так я на этом и не настаиваю. Только скажите, пжл, как написать, чтобы было, как надо. И все, этот момент исчерпан.

З. Ы. И объясните, пжл, почему так, чтобы знать на будущее.
 

Oki

Продвинутый
Сообщения
452
Репутация
63
Зачем для выполнения такой задачи вообще нужен графический интерфейс?
Сообщение автоматически объединено:

Было бы неплохо изложить, что требуется, а затем получить адекватное предложение по реализации. У меня по слишком общей формулировке задачи сложилось ощущение, что графический интерфейс излишен, но для грамотного ответа желательно понимать, что ожидается от скрипта. Создать фрагмент LaTeX-кода для матрицы по вводимым с клавиатуры элементам в более простом формате? Или что-то иное?
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
592
Репутация
72
И объясните, пжл, почему так, чтобы знать на будущее.
Закрывая окно $GUI_0, автоматически освобождаются все элементы управления и есть вероятность что идентификатор $ok_1 будет равен $ok_0.
Перенесите строку
Код:
GUIDelete($GUI_0)
с начала функции Massiv_1() в ее конец.
 
Автор
M

mathem

Новичок
Сообщения
26
Репутация
0
Начну по порядку.
Зачем для выполнения такой задачи вообще нужен графический интерфейс?
Сообщение автоматически объединено: Сегодня в 03:57
Было бы неплохо изложить, что требуется, а затем получить адекватное предложение по реализации. У меня по слишком общей формулировке задачи сложилось ощущение, что графический интерфейс излишен, но для грамотного ответа желательно понимать, что ожидается от скрипта. Создать фрагмент LaTeX-кода для матрицы по вводимым с клавиатуры элементам в более простом формате? Или что-то иное?
Да, я хочу автоматизировать процесс создания кода в LaTeX при вводе массива. Зачем мне нужен GUI? Понимаете, массивы нужно вводить с разными множествами индексов строк и столбцов, с разными, так сказать, шаблонами элементов массива. Я уже не говорю о трех различных вариантах горизонтального выравнивания. И вот, чтобы каждый раз не вводить эти множество индексов строк, множество индексов столбцов и шаблон элементов массива, я и хочу наиболее часто встречающиеся значения этих переменных объединять в комбобоксы, а потом просто сочетать их так, как мне нужно. Приведу пример. Вот допустим, множество индексов столбцов я ввел такое:
1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n
, множество индексов строк такое:
1, 2, \hdotsfor, i-1, i, i+1, \hdotsfor, j-1, j, j+1, \hdotsfor, n
, шаблон элементов я выбрал следующим:
Код:
"a_{" & $i & "\, " & $j & "}"

Я пока не говорю про горизонтальное выравнивание, это мелочи. Тогда программа должна будет при каждом, не равном \hdotsfor значении множества индексов строк подставить каждое значение множества столбцов в шаблон элементов и, если оно не равно \ldots, то раскрыть этот шаблон. Если же это значение множества индексов равно \ldots, то ничего не раскрывать, а просто вернуть эту строку (\ldots). Далее, в пределах одной строки эти раскрытые шаблоны и возвращенные строки \ldots объединяем амперсендом, в окончании каждой строки ставим \\ и переходим к следующему значению множества индексов строк. В создаваемом коде это будет соответствовать переходу на новую строку. Но в связи с особенностями того процессора, в котором я в основном набираю LaTeX, мне нужно 2 новые строки. Далее, для этого нового значения из множества строк я делаю в точности то же самое, если только это не \hdotsfor. Если же это \hdotsfor, то к уже созданному тексту, или, возможно, к создаваемой где-то в памяти какой-нибудь переменной должны быть так же добавлены 2 новых строки, приписано \hdotsfor, потом { и }, между этими строками вставлено реальное, то, которое будет на бумаге, число элементов множества столбцов (мы же не знаем, сколько на самом деле элементов в множестве {1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n}. Зато знаем, сколько элементов в этой строке, обозначающей это множество - их 12, не считая запятых и пробелов, если что). В конце этой строки должно также стоять \\. Короче говоря, мне нужно, чтобы при выборе приведенных значений и еще горизонтального выравнивания r в окне процессора было бы выведено следующее:
Код:
\begin{array}{rrrrr rrrrr rr}
a_{1\, 1} & a_{1\, 2} & \ldots & a_{1\, i-1} & a_{1\, i} & a_{1\, i+1} & \ldots & a_{1\, j-1} & a_{1\, j} & a_{1\, j+1} & \ldots & a_{1\, n} \\
a_{2\, 1} & a_{2\, 2} & \ldots & a_{2\, i-1} & a_{2\, i} & a_{2\, i+1} & \ldots & a_{2\, j-1} & a_{2\, j} & a_{2\, j+1} & \ldots & a_{2\, n} \\
\hdotsfor{12}\\
a_{i-1\, 1} & a_{i-1\, 2} & \ldots & a_{i-1\, i-1} & a_{i-1\, i} & a_{i-1\, i+1} & \ldots & a_{i-1\, j-1} & a_{i-1\, j} & a_{i-1\, j+1} & \ldots & a_{i-1\, n} \\
a_{i\, 1} & a_{i\, 2} & \ldots & a_{i\, i-1} & a_{i\, i} & a_{i\, i+1} & \ldots & a_{i\, j-1} & a_{i\, j} & a_{i\, j+1} & \ldots & a_{i\, n} \\
a_{i+1\, 1} & a_{i+1\, 2} & \ldots & a_{i+1\, i-1} & a_{i+1\, i} & a_{i+1\, i+1} & \ldots & a_{i+1\, j-1} & a_{i+1\, j} & a_{i+1\, j+1} & \ldots & a_{i+1\, n} \\
\hdotsfor{12}\\
a_{j-1\, 1} & a_{j-1\, 2} & \ldots & a_{j-1\, i-1} & a_{j-1\, i} & a_{j-1\, i+1} & \ldots & a_{j-1\, j-1} & a_{j-1\, j} & a_{j-1\, j+1} & \ldots & a_{j-1\, n} \\
a_{j\, 1} & a_{j\, 2} & \ldots & a_{j\, i-1} & a_{j\, i} & a_{j\, i+1} & \ldots & a_{j\, j-1} & a_{j\, j} & a_{j\, j+1} & \ldots & a_{j\, n} \\
a_{j+1\, 1} & a_{j+1\, 2} & \ldots & a_{j+1\, i-1} & a_{j+1\, i} & a_{j+1\, i+1} & \ldots & a_{j+1\, j-1} & a_{j+1\, j} & a_{j+1\, j+1} & \ldots & a_{j+1\, n} \\
\hdotsfor{12}\\
a_{n\, 1} & a_{n\, 2} & \ldots & a_{n\, i-1} & a_{n\, i} & a_{n\, i+1} & \ldots & a_{n\, j-1} & a_{n\, j} & a_{n\, j+1} & \ldots & a_{n\, n}
\end{array}
При вводе же, например, множества индексов столбцов таким:
1, 2, 3, 4, 5
, множества индексов строк таким:
1, 2, 3
и шаблона элемента таким:
"\dfrac{\sqrt[3]{\beta_{"& 6*$i-8 & "}}}{h_{" & 18*$j-25 & "}}"
вывод в окно процессора должен быть таким:
код LaTeX:
\begin{array}{ccccc} \dfrac{\sqrt[3]{\beta_{-2}}}{h_{-7}} & \dfrac{\sqrt[3]{\beta_{-2}}}{h_{11}} & \dfrac{\sqrt[3]{\beta_{-2}}}{h_{29}} & \dfrac{\sqrt[3]{\beta_{-2}}}{h_{47}} & \dfrac{\sqrt[3]{\beta_{-2}}}{h_{65}} \\
\dfrac{\sqrt[3]{\beta_{4}}}{h_{-7}} & \dfrac{\sqrt[3]{\beta_{4}}}{h_{11}} & \dfrac{\sqrt[3]{\beta_{4}}}{h_{29}} & \dfrac{\sqrt[3]{\beta_{4}}}{h_{47}} & \dfrac{\sqrt[3]{\beta_{4}}}{h_{65}} \\
\dfrac{\sqrt[3]{\beta_{10}}}{h_{-7}} & \dfrac{\sqrt[3]{\beta_{10}}}{h_{11}} & \dfrac{\sqrt[3]{\beta_{10}}}{h_{29}} & \dfrac{\sqrt[3]{\beta_{10}}}{h_{47}} & \dfrac{\sqrt[3]{\beta_{10}}}{h_{65}} \end{array}
в этом случае вместо $i должен подставляться номер строки, в которой стоит текущий элемент в массиве, а вместо $j - номер столбца. И вычисляться значения выражений. Да, я уже почти написал то, что хочу. К ночи, думаю, будет законченный код. Правда, все будет вводиться уже в одном окне. Мне просто нужно разобраться, что к чему в уже известном непонятном.
Перенесите строку
AutoIt код:
[URL='https://autoit-script.ru/docs/functions/guidelete.htm']GUIDelete[/URL]($GUI_0)
с начала функции Massiv_1() в ее конец.
Да, это помогло, спасибо. Еще бы ясно осознать, почему это помогло. А что делать вот с этим:
при открытии первого окна число в тултипе начинает бешено убывать на 1.
???
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
592
Репутация
72
Еще бы ясно осознать, почему это помогло.
Написал почему
Закрывая окно $GUI_0, автоматически освобождаются все элементы управления и есть вероятность что идентификатор $ok_1 будет равен $ok_0.
Речь про дескриптор, возвращаемый функцией CreateWindowEx.
 

Oki

Продвинутый
Сообщения
452
Репутация
63
Не улавливаю, каков выигрыш от того, что интерфейс графический. Мне кажется, что всю нужную информацию удобнее вводить через обычный текстовый ввод. А ещё более удобно, полагаю, создать собственный текстовый формат файла для вводимой информации и научить скрипт конвертировать из него в LaTeX-код. Добавлено: дальнейший ответ на это сообщение неубедителен, намного удобнее работать с текстовым интерфейсом. Ничто не мешает пользоваться всеми требуемыми выгодами.
 
Последнее редактирование:
Автор
M

mathem

Новичок
Сообщения
26
Репутация
0
Речь про дескриптор, возвращаемый функцией CreateWindowEx.
Понятно, но смутно. А после того, как
Закрывая окно $GUI_0, автоматически освобождаются все элементы управления
элементы управления окна $GUI_0, остаются в оперативке компа, да?
Не улавливаю, каков выигрыш от того, что интерфейс графический.
Еще раз. Чтобы в большинстве случаев не вводить все каждый раз вручную, а выбирать из вариантов, набранных 1 раз к комбобоксах, быть может, с незначительным редактированием.

при открытии первого окна число в тултипе начинает бешено убывать на 1
А что делать вот с этим? Как вы думаете? Вы так и не ответили.
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
при открытии первого окна число в тултипе начинает бешено убывать на 1
Если вы объявляете переменную без присвоения значения, то AutoIt принудительно инициализирует её пустой строкой
Код:
Global $var
ConsoleWrite("'" & $var & "':" & VarGetType($var) & @CRLF) ; '':String

Функция GUIGetMsg возвращает коды событий. Если событий нет - возвращает ноль ($GUI_EVENT_NONE). В операциях сравнения пустая строка интерпретируется нулём, а ноль - пустой строкой. Поэтому у вас и срабатывает Case $otmena_1
Код:
Global $otmena_1
Global $msg = GUIGetMsg()
ConsoleWrite($otmena_1 & ":" & $msg & @CRLF) ; :0
ConsoleWrite(($msg = $otmena_1) & @CRLF) ; True

Следовательно, если вы хотите зарезервировать переменную для контрола, то объявляйте её с присвоением -1. Потому что GUIGetMsg не возвращает такой код (см. GuiConstantsEx.au3)
Код:
Global $GUI_1, $otmena_1 = -1, $ok_1 = -1, ...

И вообще. Если хотите в чём-то детально разобраться - экспериментируйте. Например, этот код показывает, что при удалении GUI переменные остаются и не обнуляются, а окно и контролы отсутствуют
Код:
$GUI_0 = GUICreate("0Ввод окружения array", 300, 170)
GUICtrlCreateLabel("Введите множество индексов столбцов", 10, 5)
$ok_0 = GUICtrlCreateButton("OK",  10, 130, 88, 28)
GUICtrlCreateGroup("", 200, 128, 92, 32)
$otmena_0 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$stolb = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($stolb, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
GUISetState()
Sleep(555)
ConsoleWrite($GUI_0 & ":" & $ok_0 & ":" & $otmena_0 & ":" & $stolb & @CRLF) ; 0x0000000000050684:4:6:7

GUIDelete($GUI_0)
ConsoleWrite($GUI_0 & ":" & $ok_0 & ":" & $otmena_0 & ":" & $stolb & @CRLF) ; 0x0000000000050684:4:6:7
ConsoleWrite(WinGetHandle($GUI_0) & @CRLF) ; 0x0000000000000000
ConsoleWrite(GUICtrlGetHandle($ok_0) & @CRLF) ; 0
ConsoleWrite(ControlGetHandle($GUI_0, "", $otmena_0) & @CRLF) ; 0x0000000000000000

Сообщение автоматически объединено:

См. также:
 
Последнее редактирование:

Prog

Продвинутый
Сообщения
592
Репутация
72
элементы управления окна $GUI_0, остаются в оперативке компа, да?
Нет. Я написал что они освобождаются и их дескрипторы система может использовать для других создаваемых элементов что и происходит.
А что делать вот с этим? Как вы думаете? Вы так и не ответили.
Отвечал уже
При старте программы какое значение в $otmena_1 и каким оно станет при нажатии ОК и выполнении функции Massiv_1()?
Обрабатывайте события только для существующих окон.
При старте программы, окно $GUI_1 не существует. Оно будет создано при вызове функции Massiv_1() что произвойдет при выполнении условия
Код:
Switch $msg
   Case $ok_0
        Massiv_1()
но при этом в цикле обработки событий присутствует $otmena_1 из несуществующего окна.

Сделайте так
Код:
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#include <GUIConstants.au3>
#include <Misc.au3>

Global $GUI_1=0, $otmena_1, $ok_1, $otmena_2, $ok_2, $radio1, $radio2, $radio3, $vyrav, $abrakadabra

$GUI_0 = GUICreate("0Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов столбцов", 10, 5)
$ok_0 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
GUICtrlCreateGroup("", 200, 128, 92, 32)
$otmena_0 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$stolb = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($stolb, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $stolb)
GUISetState()

Func Massiv_1()
    if $GUI_0 Then
        GUIDelete($GUI_0)
        $GUI_0=0
    endif
    $GUI_1 = GUICreate("1Ввод окружения array", 300, 170)                           ;1
    GUICtrlCreateLabel("Введите множество индексов строк", 10, 5)
    $ok_1 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
    $otmena_1 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
    $strok = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
    GUICtrlSetData($strok, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
    ControlFocus("Ввод окружения array", "", $strok)
    GUISetState()
EndFunc

Global $a = 0

While $GUI_0 or $GUI_1
    $msg = GUIGetMsg()

    if $GUI_0 Then
        Switch $msg
          Case $GUI_EVENT_CLOSE
             GUIDelete($GUI_0)
             $GUI_0=0
          Case $ok_0
            Massiv_1()
          Case $otmena_0
             $a = $a+1
             ToolTip ($a, 0, 0)
        EndSwitch
    endif

    if $GUI_1 Then
        Switch $msg
          Case $GUI_EVENT_CLOSE
             GUIDelete($GUI_1)
             $GUI_1=0
          Case $otmena_1
             $a = $a-1
             ToolTip ($a, 0, 0)
        EndSwitch
    endif
WEnd
Не скажу что это самый правильный вариант, но он рабочий.

Если вы объявляете переменную без присвоения значения, то AutoIt принудительно инициализирует её пустой строкой
Нет не пустой строкой. Переменные типа Variant. Если переменная создана но значение не присвоено, у нее нет типа как такового.
Если хотите в чём-то детально разобраться - экспериментируйте.
Без отладчика не так просто по настоящему экспериментировать. Не видно что в переменных, как выполняется код и др.
 
Последнее редактирование:

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
Если переменная создана но значение не присвоено, у нее нет типа как такового.
В AutoIt переменные всегда чем-то инициализированы. Я же показал на примере
Код:
Global $var
$type = VarGetType($var)
ConsoleWrite($type & @CRLF) ; String

А если даже всё так, как вы описали, то нам важно знать только то, что переменная "пустая": ноль или пустая строка. Причём, заметьте, не Null
Код:
Global $s = "", $i = 0, $n = Null
ConsoleWrite(($s = $i) & @CRLF) ; True
ConsoleWrite(($s = $n) & @CRLF) ; False
ConsoleWrite(($i = $n) & @CRLF) ; False

Без отладчика не так просто
Ну вот, началось... :timeout:
 
Автор
M

mathem

Новичок
Сообщения
26
Репутация
0
Функция GUIGetMsg возвращает коды событий. Если событий нет - возвращает ноль ($GUI_EVENT_NONE). В операциях сравнения пустая строка интерпретируется нулём, а ноль - пустой строкой. Поэтому у вас и срабатывает Case $otmena_1
Это же из-за строки
Global Const $BN_CLICKED = 0
в файле ButtonConstants.au3?
Следовательно, если вы хотите зарезервировать переменную для контрола, то объявляйте её с присвоением -1. Потому что GUIGetMsg не возвращает такой код (см. GuiConstantsEx.au3)
Как будто помогло. Но тогда непонятно, почему при запуске скрипта
Код:
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#include <GUIConstants.au3>
#include <Misc.au3>

Global $ok_0, $ok_1 = -1, $otmena_1 = -1 ;$otmena_1=-1, $ok_1 = -1, $otmena_2, $ok_2, $radio1, $radio2, $radio3, $vyrav, $abrakadabra

$GUI_0 = GUICreate("0Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов столбцов", 10, 5)
$ok_0 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
GUICtrlCreateGroup("", 200, 128, 92, 32)
$otmena_0 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$stolb = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($stolb, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $stolb)
GUISetState()

Func Massiv_1()
   ;GUIDelete($GUI_0)
   ;WinWaitClose("0Ввод окружения array")
   $GUI_1 = GUICreate("1Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов строк", 10, 5)
$ok_1 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
$otmena_1 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$strok = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($strok, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $strok)
GUISetState()
  GUIDelete($GUI_0)
   EndFunc

Func Massiv_2()
MsgBox(4096, "Test", "Это открылось сообщение от кнопки ok_2")
EndFunc

Global $a = 0

While 1
$msg = GUIGetMsg()
Switch $msg
      Case $GUI_EVENT_CLOSE
         ExitLoop
      Case $ok_0
        Massiv_1()
      Case $otmena_0
         $a = $a+1
         ToolTip ($a, 0, 0)
      Case $ok_1
         Massiv_2()
      Case $otmena_1
         $a = $a-1
         ToolTip ($a, 0, 0)
      EndSwitch
WEnd

сразу не выполняется Massiv_1(), ведь кнопка $ok_0 точно так же объявляется без присвоения значения.
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
в файле ButtonConstants.au3?
Ну при чём тут ButtonConstants.au3? Я же написал: см. GuiConstantsEx.au3
Функция GUIGetMsg возвращает вот эти коды
Код:
; Events and messages
Global Const $GUI_EVENT_SINGLE = 0 ; (default) Returns a single event.
Global Const $GUI_EVENT_ARRAY = 1 ; returns an array containing the event and extended information.

Global Const $GUI_EVENT_NONE = 0
Global Const $GUI_EVENT_CLOSE = -3
Global Const $GUI_EVENT_MINIMIZE = -4
Global Const $GUI_EVENT_RESTORE = -5
Global Const $GUI_EVENT_MAXIMIZE = -6
Global Const $GUI_EVENT_PRIMARYDOWN = -7
Global Const $GUI_EVENT_PRIMARYUP = -8
Global Const $GUI_EVENT_SECONDARYDOWN = -9
Global Const $GUI_EVENT_SECONDARYUP = -10
Global Const $GUI_EVENT_MOUSEMOVE = -11
Global Const $GUI_EVENT_RESIZED = -12
Global Const $GUI_EVENT_DROPPED = -13
Это даже в справке указано:

ведь кнопка $ok_0 точно так же объявляется без присвоения значения
Скрипт выполняется сверху вниз. Сначала вы объявили "пустую" $ok_0. Затем вы присвоили ей значение через вызов функции GUICtrlCreateButton (значением является порядковый "внутренний" номер контрола, созданного AutoIt). И после этого Switch проверяет значения, возвращаемые GUIGetMsg. Когда она вернёт значение $ok_0, тогда Case и выполнится.
 
Автор
M

mathem

Новичок
Сообщения
26
Репутация
0
Это же из-за строки
Global Const $BN_CLICKED = 0
в файле ButtonConstants.au3?

Как будто помогло. Но тогда непонятно, почему при запуске скрипта
Код:
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#include <GUIConstants.au3>
#include <Misc.au3>

Global $ok_0, $ok_1 = -1, $otmena_1 = -1 ;$otmena_1=-1, $ok_1 = -1, $otmena_2, $ok_2, $radio1, $radio2, $radio3, $vyrav, $abrakadabra

$GUI_0 = GUICreate("0Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов столбцов", 10, 5)
$ok_0 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
GUICtrlCreateGroup("", 200, 128, 92, 32)
$otmena_0 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$stolb = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($stolb, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $stolb)
GUISetState()

Func Massiv_1()
   ;GUIDelete($GUI_0)
   ;WinWaitClose("0Ввод окружения array")
   $GUI_1 = GUICreate("1Ввод окружения array", 300, 170)                           ;1
GUICtrlCreateLabel("Введите множество индексов строк", 10, 5)
$ok_1 = GUICtrlCreateButton("OK",  10, 130, 88, 28, $BS_DEFPUSHBUTTON) ;
$otmena_1 = GUICtrlCreateButton("Cancel", 202, 130, 88, 28)
$strok = GUICtrlCreateCombo('1, 2, \ldots, i-1, i, i+1, \ldots, j-1, j, j+1, \ldots, n', 10, 65, 280, 21)
GUICtrlSetData($strok, '1, 2, \ldots, i-1, i, i+1, \ldots, n-1, n|1, 2, \ldots, k-1, k, k+1, \ldots, n-1, n')
ControlFocus("Ввод окружения array", "", $strok)
GUISetState()
  GUIDelete($GUI_0)
   EndFunc

Func Massiv_2()
MsgBox(4096, "Test", "Это открылось сообщение от кнопки ok_2")
EndFunc

Global $a = 0

While 1
$msg = GUIGetMsg()
Switch $msg
      Case $GUI_EVENT_CLOSE
         ExitLoop
      Case $ok_0
        Massiv_1()
      Case $otmena_0
         $a = $a+1
         ToolTip ($a, 0, 0)
      Case $ok_1
         Massiv_2()
      Case $otmena_1
         $a = $a-1
         ToolTip ($a, 0, 0)
      EndSwitch
WEnd

сразу не выполняется Massiv_1(), ведь кнопка $ok_0 точно так же объявляется без присвоения значения.
Я еще попозже напишу. Я просто пока не могу сформулировать, что хочу сказать.
 
Верх