Этот урок показывает, что создать калькулятор достаточно просто. Возможность сделать его лучше зависит от вашей фантазии, предпочтения способа взаимодействия с интерфейсом программы. В данном примере рассматривается упрощённый алгоритм. Как и в любом скрипте в начале определены #include содержащие необходимые константы для работы функций и объявление переменных. Обычно эта часть скрипта заранее неизвестна и заполняется по мере написания скрипта и зависит от используемых функций.
Сначала создаём GUI и заполняем его необходимыми элементами, указывая размеры и позицию каждого.
$hGui = GUICreate('Calculator', 230, 200)
$Input = GUICtrlCreateInput('', 10, 10, 120, 25, $ES_RIGHT, $WS_EX_STATICEDGE)
Здесь создаётся окно и элемент поле ввода. Так как в скрипте не используется дескриптор окна $hGui, то не обязательно создавать эту переменную и возвращать в неё дескриптор. Но в дальнейшем он всё равно понадобится, чтобы указывать его в качестве дескриптора родительского окна для дочерних окон, например для функции MsgBox(). Аналогично не требуется возвращать идентификатор элемента GUICtrlCreateLabel(), если он используется в качестве информационной надписи.
Для поля ввода используются константы $ES_RIGHT (выравнивание по правому краю) и $WS_EX_STATICEDGE (утопленный вид элемента), которые требуют включить EditConstants.au3 и WindowsConstants.au3 с помощью #include
Далее создаём однотипные кнопки с помощью GUICtrlCreateButton().
Чтобы посмотреть что получилось добавляем GUISetState(), которая заставляет отображать окно и добавляем стандартную конструкцию цикла для GUI. Является ли эта конструкция для вас стандартной зависит от ваших предпочтений.
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Попробую объяснить эту конструкцию, которая может показаться чем то недостижимым пониманию. На самом деле это не так. Оператор While и WEnd являются началом и концом цикла, всё что находится внутри этих операторов будет повторятся несколько раз. Число 1 после While является условием определяющим разрешение циклу выполнить участок кода принадлежащий циклу ещё раз. Если бы это была переменная, то её значение определяло бы поведение цикла при каждом шаге, но в данном случае жёстко указана числовая константа 1, которая заставляет цикл выполнятся бесконечно.
Далее внутри цикла конструкция выбора Switch - EndSwitch. Функция GUIGetMsg() при каждом шаге цикла опрашивает окно, произошло ли событие, например нажата ли какая-нибудь кнопка и возвращает результат в конструкцию Switch. В данной конструкции определена лишь одна кнопка $GUI_EVENT_CLOSE, которая соответствует кнопке закрытию окна, то есть системная кнопка в правом верхнем углу окна. При событии нажатия этой кнопки выполниться, принадлежащий блоку "Case $GUI_EVENT_CLOSE", оператор Exit и окно закроется, программа завершится.
В этом цикле необходимо указать события для остальных кнопок интерфейса. Для кнопок 0-9 события идентичны, выполняют вставку соответствующей цифры в поле ввода. Аналогично и для кнопок математических операторов "/*+-" выполняется такое же событие вставки. Событие для кнопки изменения знака числа выполняет чтение данных из поля ввода; проверяет, является ли левый символ знаком "-" и в соответствии с этим либо удаляет этот символ слева, либо добавляет его.
Событие кнопки "Вычислить" считывает текст в поле ввода, далее с помощью функции Execute() вычисляет математическое выражение и вставляет результат назад в поле ввода, заменяя ранее находящийся в нём математическое выражение.
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Local $hGui, $Input, $iBtnNg, $iBtnPn, $iBtnExe, $tmp
Local $iBtnDiv, $iBtnMul, $iBtnSub, $iBtnAdd
Local $iBtn0, $iBtn1, $iBtn2, $iBtn3, $iBtn4, $iBtn5, $iBtn6, $iBtn7, $iBtn8, $iBtn9
$hGui = GUICreate('Calculator', 230, 200)
$Input = GUICtrlCreateInput('', 10, 10, 120, 25, $ES_RIGHT, $WS_EX_STATICEDGE)
$iBtn7 = GUICtrlCreateButton('7', 10, 40, 30, 29)
$iBtn8 = GUICtrlCreateButton('8', 40, 40, 30, 29)
$iBtn9 = GUICtrlCreateButton('9', 70, 40, 30, 29)
$iBtn4 = GUICtrlCreateButton('4', 10, 70, 30, 29)
$iBtn5 = GUICtrlCreateButton('5', 40, 70, 30, 29)
$iBtn6 = GUICtrlCreateButton('6', 70, 70, 30, 29)
$iBtn1 = GUICtrlCreateButton('1', 10, 100, 30, 29)
$iBtn2 = GUICtrlCreateButton('2', 40, 100, 30, 29)
$iBtn3 = GUICtrlCreateButton('3', 70, 100, 30, 29)
$iBtn0 = GUICtrlCreateButton('0', 10, 130, 30, 29)
$iBtnNg = GUICtrlCreateButton('+/-', 40, 130, 30, 29)
$iBtnPn = GUICtrlCreateButton('.', 70, 130, 30, 29)
$iBtnDiv = GUICtrlCreateButton('/', 100, 40, 30, 29)
$iBtnMul = GUICtrlCreateButton('*', 100, 70, 30, 29)
$iBtnSub = GUICtrlCreateButton('-', 100, 100, 30, 29)
$iBtnAdd = GUICtrlCreateButton('+', 100, 130, 30, 29)
$iBtnExe = GUICtrlCreateButton('Calculate', 10, 160, 120, 29)
GUISetState()
While 1
Switch GUIGetMsg()
Case $iBtn1
GUICtrlSetData($input, '1', 1)
Case $iBtn2
GUICtrlSetData($input, '2', 1)
Case $iBtn3
GUICtrlSetData($input, '3', 1)
Case $iBtn4
GUICtrlSetData($input, '4', 1)
Case $iBtn5
GUICtrlSetData($input, '5', 1)
Case $iBtn6
GUICtrlSetData($input, '6', 1)
Case $iBtn7
GUICtrlSetData($input, '7', 1)
Case $iBtn8
GUICtrlSetData($input, '8', 1)
Case $iBtn9
GUICtrlSetData($input, '9', 1)
Case $iBtn0
GUICtrlSetData($input, '0', 1)
Case $iBtnDiv
GUICtrlSetData($input, '/', 1)
Case $iBtnMul
GUICtrlSetData($input, '*', 1)
Case $iBtnSub
GUICtrlSetData($input, '-', 1)
Case $iBtnAdd
GUICtrlSetData($input, '+', 1)
Case $iBtnNg
$tmp = GUICtrlRead($input)
If StringLeft($tmp, 1) = '-' Then
$tmp = StringTrimLeft($tmp, 1)
GUICtrlSetData($input, $tmp)
Else
GUICtrlSetData($input, '-' & $tmp)
EndIf
Case $iBtnPn
GUICtrlSetData($input, '.', 1)
Case $iBtnExe
$tmp = GUICtrlRead($input)
$tmp = Execute($tmp)
GUICtrlSetData($input, $tmp)
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Конечно же этот пример имеет много недостатков. Например поле ввода позволяет вводить текст. Можно запретить с помощью стиля $ES_READONLY, но тогда это ограничивает пользователей, которые вводят математическое выражение с клавиатуры. Можно при нажатии кнопки "Вычислить" проверить наличие недопустимых символов, а лучше используя WM_COMMAND и событие $EN_CHANGE запретить ввод недопустимых символов.
Размер чисел также ограничен, поэтому рекомендуется использовать библиотеку для работы с большими числами.
Также можно добавить кнопки Backspace, CE, MC, MR, MS, M+ и другие функциональные возможности, добавляя в конструкцию Switch - EndSwitch блок операторов для новой кнопки.