Пример использования диалоговой функции
Основное взаимодействие с пользователем при инсталляции программы происходит с помощью диалоговых окон которые вы определяете в проекте в инсталляторе CreateInstall. Все диалоговые окна создаются стандартными средствами Windows и имеют стандартные элементы такие как поле редактирования, кнопки, текст, список и т.д. Иногда может возникнуть потребность самостоятельно обрабатывать те или иные события, поступающие от диалоговых элементов. Устанавливать свой обработчик события можно на любой диалог. Мы установим свой обработчик событий на Диалог - Опции. Рассмотрим простейший пример - нужно создать диалог с двумя радиокнопками - с каждой кнопкой связан свой чекбокс и поле ввода. Когда радиокнопка отмечена - соответствующий чекбокс и поле ввода доступны для изменений, когда радиокнопка не отмечена, то ее чекбокс и поле ввода становятся серыми и не могут никак меняться. Также, для примера, добавим на наше диалоговое окно поле ввода пароля, который мы предварительно определим, а все вводимые в этом поле символы будем параллельно отображать в другом элементе. Пользователь может нажать на кнопку Далее только, если укажет правильный пароль и свое имя в поле редактирования под отмеченной радиокнопкой.
В начале нам необходимо добавить команду Диалог - Опции и разместить там нужные нам элементы. Вы можете подробнее прочитать как это делается в статье Как использовать команду Диалог - Установки. В результате у нас должен получится вот такой диалог.
Следует заметить, что здесь представлен уже рабочий вариант.
Сейчас займемся непосредственно определением своей функцией. Первоначально прочитайте статью Как определить свою функцию обработчик диалоговых окон. Мы вынесем весь исходный код в отдельный файл custom.g и подключим его к нашему проекту с помощью команды Исходный код.
External Source Code: Checked Source Code: include : $"$prjpath$\custom-dialog-function\custom.g"
Вы можете найти файл custom.g в поддиректории custom-dialog-function в папке где расположен сам наш проект. Откройте его в любом текстовом редакторе. В начале идут идентификаторы, необходимых нам элементов (смотрите статью Как определить Control ID). Главной функцией у нас является mydlgsetscmdproc, где и обрабатываются все события. Имя этой функции мы должны добавить в нашу команду Диалог - Опции как значение параметра Dfunc.
Во фрагменте ниже мы обрабатываем нажатия на радиокнопки и в функции myenable делаем активными или недоступными соответсвующие элементы. Кроме этого мы вызываем эту же функцию при инициализации диалогового окна ( case $DLGINIT ), поэтому в ней присутствуют дополнительные проверки связанные с полями редактирования и вводом пароля.
case $RADIO1, $RADIO2 { if codedlg == $BN_CLICKED : myenable( wnd ) } ... case $DLGINIT { uint ret = dlgsetscmdproc( wnd, id, ctl, codedlg ) macrox_getstr( "defpsw", defpsw ) myenable( wnd ) return ret }
Также в нашей функции происходит обработка событий от полей редактирования и от поля ввода пароля.
case $EDIT1, $EDIT2 { if codedlg == $EN_SETFOCUS : myfocus( GetDlgItem( wnd, id )) if codedlg == $EN_KILLFOCUS : mychange( GetDlgItem( wnd, id )) } case 0xc8c { if codedlg == $EN_CHANGE : mypsw( wnd ) }
Рассмотрим подробнее функцию mypsw. В ней мы проверяем введенный пароль с правильным паролем переменную defpsw, а также дублируем введенный пароль в другом поле редактирования. Пароль определен в общей переменной скрипта "defpsw" и присваивается строковой переменной defpsw при инициализации диалога $DLGINIT. Если введенный пароль правильный, то мы делаем активной кнопку Далее.
func mypsw( uint wnd ) { str psw win_gettext( GetDlgItem( wnd, 0xc8c ), psw ) win_enable( GetDlgItem( wnd, $IDC_NEXT ), psw == defpsw ) win_settext( GetDlgItem( wnd, 0xc8e ), psw ) }
В заключении рассмотрим дополнительную обработку при нажатии кнопки Далее. Для усложнения задачи мы проверим, что бы пользователь обязательно указал имя в активном поле редактирования, которое находится под отмеченной радиокнопкой. В idedit мы получаем идентификатор поля редактирования и в переменную curname записываем указанное пользователем значение. Если оно равно значению по умолчанию или пустое, то мы выводим предупреждающее сообщение и отменяем переход к следующему этапу.
case $IDC_NEXT { uint idedit first = wcheck_get( GetDlgItem( wnd, $RADIO1 )) str curname idedit = GetDlgItem( wnd, ?( first, $EDIT1, $EDIT2 )) win_gettext( idedit, curname ) if curname == macrox_get( "default_text" ) || !*curname { msg_warning( "#warningmsg#", "#lcaption#" ) SetFocus( idedit ) return 0 } }
Вы можете скачать проект и файл с исходным кодом в файле custom.g и посмотреть как это работает на практике. Объем дополнительного кода небольшой и понятен даже для начинающего программиста. В данном примере мы обрабатываем только основные события, которые могут вам потребоваться в ваших проектах, но подобным образом можно обрабатывать и другие события приходящие от диалоговых элементов. Также вы можете смотреть обработчики по умолчанию для всех диалоговых окон в поддиректории CreateInstall\cmds\sources в файлах с именами dlg*.g.
Скачать пример custom-dialog-function.ci