#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=Pictures\TA.ico
#AutoIt3Wrapper_Res_Fileversion=1.1.0.0
#AutoIt3Wrapper_Res_LegalCopyright=Makrut
#AutoIt3Wrapper_Res_Language=1049
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#Region
#AutoIt3Wrapper_Res_Icon_Add=TA.ico
#EndRegion

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <TabConstants.au3>
#Include <Skin.au3>
#include <ModernMenuRaw.au3>
#include "GIFAnimation.au3"
#include <GUIListBox.au3>
#include <ProgressConstants.au3>
#include <EditConstants.au3>
#include "_TCP_filesend.au3"
#Include <GuiEdit.au3>
#include <Crypt.au3>
#include <ComboConstants.au3>
#include <GDIPlus.au3>

#Region AppStarted ;Чтобы программа могла быть запущена только 1 раз.
$pList = ProcessList() ;Записываем в массив все открытые приложения.
$k = 0

For $i = 1 to UBound($pList)-1
	If $pList[$i][0] = "Управляющий.exe" Then $k = $k + 1 ;Если программа уже запущена, записываем это
Next

If $k > 1 then
    Msgbox(0, "", "Teacher Assistant уже запущен", 2)
    Exit
EndIf
#EndRegion

#Region Variables ;Используемые переменные.
Global $students_IP = IniReadSection(@ScriptDir & '\settingsT.ini', 'Students IP')
    If @error Then _SettingsSetup()
Global $address = IniReadSection(@ScriptDir & '\settingsT.ini', 'Address')
    If @error Then _SettingsSetup()
Global $notification = IniReadSection(@ScriptDir & '\settingsT.ini', 'Notification')
	If @error Then _SettingsSetup()
Global $ini_checkbox = IniReadSection(@ScriptDir & '\settingsT.ini', 'CheckBox')
	If @error Then _SettingsSetup()
Global $restart = IniReadSection(@ScriptDir & '\settingsT.ini', 'Restart')
	If @error Then _SettingsSetup()
Global $value_online = IniReadSection(@ScriptDir & '\OnlineS.ini', 'Value')
	If @error Then _SettingsSetup()

Global $left_pos = 96, $top_pos = 14, $check = 0, $value = 0, $button_height = 102, $amt_buttons = 0, $height = 55, $while = 0, $checked = 0, $path, $number, $send, $form_settings_ip, $button_add, $s_online = 0, $sorted = 0, $n = 0, $tcp = 1

Global $CheckBoxes[$students_IP[0][0]], $Label_Names[$students_IP[0][0]], $Label_IP[$students_IP[0][0]], $Button[$students_IP[0][0]], $button_cross[$students_IP[0][0]]
Global $Input_Name[$students_IP[0][0]], $Input_IP[$students_IP[0][0]], $Button_settings[$students_IP[0][0]]

Global $pic_cross = @ScriptDir & "\Pictures\cross.jpg", $pic_about = @ScriptDir & "\Pictures\pic_about.png", $icopng = @ScriptDir & "\Pictures\ico.png", $ico = @ScriptDir & "\Pictures\TA.ico"
Global $pic_pc = @ScriptDir & "\Pictures\pc_online.png", $pic_arrow_down =  @ScriptDir & "\Pictures\arrow_down.png", $pic_arrow_up =  @ScriptDir & "\Pictures\arrow_up.png", $pc_offline = @ScriptDir & "\Pictures\pc_offline.png"
Global $add = @ScriptDir & "\Pictures\add.png", $remove = @ScriptDir & "\Pictures\remove.png", $demonstration = @ScriptDir & "\Pictures\demonstration.png", $refresh = @ScriptDir & "\Pictures\refresh.png"
#EndRegion

Opt("GUIResizeMode", 2 + 32 + 256 + 512)

#Region HotKey ;Привязываем функции к кнопкам.
HotKeySet ("^a", "_AllCheckbox") ;Привязываем выыделение всех чекбоксов к Ctrl + A, для удобства добавлены все варианты.
HotKeySet ("^A", "_AllCheckbox") ;
HotKeySet ("^ф", "_AllCheckbox") ;
HotKeySet ("^Ф", "_AllCheckbox") ;
HotKeySet ("{F5}", "_Restart")
#EndRegion

If $value_online[1][1] = 1 Then
	$s_online = 1
Else ;Если программа запускается впервые (не из-за рестарта).
	IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 0)
	$form_loading = GUICreate("", 251, 251, -1, -1, $WS_DISABLED) ;Анимация загрузки
	$pic_loading = GUICtrlCreatePic (@ScriptDir & "\Pictures\Безымянный.jpg", -1, -1, 300, 300)
	$gif_loading = _GUICtrlCreateGIF(@ScriptDir & "\Pictures\ring-alt.gif", "", 25, 5)
	GUISetState(@SW_SHOW, $form_loading)
	$s_online = 0
EndIf

#Region GUI ;Создание интерфейса.
$form_size = Ceiling($students_IP[0][0]/4)*88 + 88 ;Подсчитываем необходимую высоту формы.
;Так как форма подразумевает ряд из 4 компьютеров, мы выделяем 88 пикселей на каждый ряд, затем добавляем еще 88 для кнопок первого ряда.
Global $form = GUICreate("Teacher Assistant", 745, $form_size, 442, 249)

GUISetIcon($ico) ;
GUICtrlSetImage ($form, $ico) ;Прикручиваем иконку.
TraySetIcon($ico) ;

For $i = 1 To $students_IP[0][0] ;Создание динамических элементов GUI
    If $s_online = 0 Then ;Если программа запускается впервые (не из-за рестарта).
		If Ping($students_IP[$i][1], 100) <> 0 Then  ;Если компьютер онлайн.
			IniWrite(@ScriptDir & '\OnlineS.ini', "Students Online", $students_IP[$i][0], $students_IP[$i][1])  ;Записываем IP в специальный файл.
			$Button[$i - 1] = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $pic_pc, $demonstration, $demonstration, $pic_pc, $pic_pc, 1)
		Else ;Для выключенных компьютеров иконка другая.
			$Button[$i - 1] = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $pc_offline, $pc_offline, $pc_offline, $pc_offline, $pc_offline, 1)
		EndIf
	Else  ;Если запуск произошел после рестарта.
		Global $students_online = IniReadSection(@ScriptDir & '\OnlineS.ini', 'Students Online')
		If ($students_online <> 1) Then ;Если есть хотя бы один включенный компьютер.
			_Sort($i) ;Функция определяет, относится ли кнопка к онлайн компьютеру. Если да, делаеи иконку онлайн.
			If $sorted = 1 Then
				$Button[$i - 1] = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $pic_pc, $demonstration, $demonstration, $pic_pc, $pic_pc, 1) ;Создание кнопок в виде окнок компьютеров.
			Else
				$Button[$i - 1] = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $pc_offline, $pc_offline, $pc_offline, $pc_offline, $pc_offline, 1)
			EndIf
		Else
			$Button[$i - 1] = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $pc_offline, $pc_offline, $pc_offline, $pc_offline, $pc_offline, 1)
		EndIf
	EndIf

#cs
Деление на "из-за рестарта" и "не из-за" необходимо, тк при пинге компьютеров тратится большое количество времени. Если учесть, что рестарт идет после добавления и удаления айпи (вероятно, десятки действий),
То нет возможности Выделять столько времени на загрузку. Поэтому был создан файл, в котором записаны все онлайн компьютеры, если был рестарт, то файл заменяет функцию "Пинг".
#ce

	Global $sorted = 0

	$Label_Names[$i - 1] = GUICtrlCreateLabel($students_IP[$i][0], $left_pos, $top_pos, 90, 23) ;Имя компьютера.
    GUICtrlSetFont(-1, 11, 400, 0, "Times New Roman")
	$Label_IP[$i - 1] = GUICtrlCreateLabel($students_IP[$i][1], $left_pos, $top_pos+23, 100, 23) ;IP.
    GUICtrlSetFont(-1, 11, 400, 0, "Times New Roman")
	$CheckBoxes[$i - 1] = GUICtrlCreateCheckbox("", $left_pos, $top_pos+46, 20, 20) ;Чекбоксы.
	GUICtrlSetState (-1, $GUI_CHECKED)

	$left_pos += 178
	$value += 1

	If (Mod($value, 4) = 0) And $i <> $students_IP[0][0] Then ;Когда количество компьютеров превышает 4, переходим на новый ряд (см. скриншоты).
		$top_pos += 88 ;
	    $left_pos = 96 ; Восстанавливаем значения по умолчанию.
		$button_height += 88 ;
	EndIf
Next

#Region Menu ;Создание меню
$menu_file = GUICtrlCreateMenu("Файл")
$menu_settings = GUICtrlCreateMenu("Настройки")
$menu_help = GUICtrlCreateMenu("Помощь")

$menu_file_restart = _GUICtrlCreateODMenuItem("Обновить", $menu_file)
_GUICtrlCreateODMenuItem("", $menu_file) ;создаёт разделительную линию
$menu_file_exit = _GUICtrlCreateODMenuItem("Выход", $menu_file)

$menu_settings_open = _GUICtrlCreateODMenuItem("Открыть настройки", $menu_settings)
_GUICtrlCreateODMenuItem("", $menu_settings) ;создаёт разделительную линию
$menu_settings_file = _GUICtrlCreateODMenuItem("Открыть файл настройки", $menu_settings)
$menu_settings_student = _GUICtrlCreateODMenuItem("Открыть настройки ученика", $menu_settings)

$menu_help_help = _GUICtrlCreateODMenuItem("Помощь", $menu_help)
_GUICtrlCreateODMenuItem("", $menu_help) ;создаёт разделительную линию
$menu_help_about = _GUICtrlCreateODMenuItem("О программе", $menu_help)
#EndRegion

#Region Buttons ;Создание кнопок.
Global $shutdown = GUICtrlCreateButton("Выключить", 24, $button_height, 94, 40)
Global $reboot = GUICtrlCreateButton("Перезагрузить", 125, $button_height, 94, 40, $BS_MULTILINE)
Global $logout = GUICtrlCreateButton("Выйти из системы", 226, $button_height, 94, 40, $BS_MULTILINE)
Global $message = GUICtrlCreateButton("Отправить сообщение", 327, $button_height, 94, 40, $BS_MULTILINE)
Global $web_show = GUICtrlCreateButton("Открыть веб-станицу", 428, $button_height, 94, 40, $BS_MULTILINE)
Global $system_info = GUICtrlCreateButton('Получение сист. информации', 529, $button_height, 94, 40, $BS_MULTILINE)
Global $arrow_down = _Skin_AddButton(650, $button_height-4, 48, 48, $pic_arrow_down, $pic_arrow_down, $pic_arrow_down, $pic_arrow_down, $pic_arrow_down, 1)

Global $screen = GUICtrlCreateButton("Смотреть скриншот экрана", 24, $button_height+47, 94, 40, $BS_MULTILINE)
GUICtrlSetState ($screen, $GUI_HIDE)

Global $audio_start = GUICtrlCreateButton("Воспроизвести файл", 125, $button_height+47, 94, 40, $BS_MULTILINE)
GUICtrlSetState ($audio_start, $GUI_HIDE)

Global $audio_listen = GUICtrlCreateButton("Записать файл", 226, $button_height+47, 94, 40, $BS_MULTILINE)
GUICtrlSetState ($audio_listen, $GUI_HIDE)

Global $program_start = GUICtrlCreateButton("Запустить программу", 327, $button_height+47, 94, 40, $BS_MULTILINE)
GUICtrlSetState ($program_start, $GUI_HIDE)

Global $file_send = GUICtrlCreateButton("Отправить файл", 428, $button_height+47, 94, 40, $BS_MULTILINE)
GUICtrlSetState ($file_send, $GUI_HIDE)

Global $rdp = GUICtrlCreateButton("Подключение к рабочему столу", 529, $button_height+47, 94, 40, $BS_MULTILINE)
GUICtrlSetState ($rdp, $GUI_HIDE)

Global $block = GUICtrlCreateButton("Заблокировать экран", 630, $button_height+47, 94, 40, $BS_MULTILINE)
GUICtrlSetState ($block, $GUI_HIDE)

Global $arrow_up = _Skin_AddButton(650, $button_height-4, 48, 48, $pic_arrow_up, $pic_arrow_up, $pic_arrow_up, $pic_arrow_up, $pic_arrow_up, 1)
GUICtrlSetState ($arrow_up, $GUI_HIDE)
#EndRegion

GUISetState(@SW_SHOW, $form)
If $value_online[1][1] = 0 Then
	GUIDelete($form_loading)
EndIf
#EndRegion

While 1
	_Skin_Helper($form)
	If $restart[1][1] = 1 Then ;Если программа запустилась при помощи рестарта (при добавлении или удалении ip), то сразу открываются настройки ip.
		Global $nMsg = $menu_settings_open
	ElseIf $restart[1][1] = 0 Then
		Global $nMsg = GUIGetMsg()
	EndIf

	Switch $nMsg

		Case $GUI_EVENT_CLOSE, $menu_file_exit
			IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 0) ;Указываем, что рестарта не было.
			IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 0) ;
			Global $students_online = IniReadSection(@ScriptDir & '\OnlineS.ini', 'Students Online')
			If $students_online <> 1 Then
				For $i = 1 To $students_online[0][0]
					IniDelete(@ScriptDir & '\OnlineS.ini', 'Students Online', $students_online[$i][0]) ;Очищаем список включенных компьютеров.
				Next
			EndIf
			Exit

		Case $arrow_down
			$form_size = Ceiling($students_IP[0][0]/4)*88 + 88
			WinMove($form, "Teacher Assistant", Default, Default, 751, $form_size + 71) ;При нажатии на стрелочку откроются новые функции.
			GUICtrlSetState ($screen, $GUI_SHOW)
			GUICtrlSetState ($audio_start, $GUI_SHOW)
			GUICtrlSetState ($audio_listen, $GUI_SHOW)
			GUICtrlSetState ($program_start, $GUI_SHOW)
			GUICtrlSetState ($file_send, $GUI_SHOW)
			GUICtrlSetState ($rdp, $GUI_SHOW)
			GUICtrlSetState ($arrow_up, $GUI_SHOW)
			GUICtrlSetState ($block, $GUI_SHOW)
			GUICtrlSetState ($arrow_down, $GUI_HIDE) ;Смотрящую вниз заменяет смотрящая вверх.

		Case $arrow_up ;Операция, обратная предыдущей
		    $form_size = Ceiling($students_IP[0][0]/4)*88 + 88
			WinMove($form, "Teacher Assistant", Default, Default, 751, $form_size + 29)
			GUICtrlSetState ($screen, $GUI_HIDE)
			GUICtrlSetState ($audio_start, $GUI_HIDE)
			GUICtrlSetState ($audio_listen,$GUI_HIDE)
			GUICtrlSetState ($program_start, $GUI_HIDE)
			GUICtrlSetState ($file_send, $GUI_HIDE)
			GUICtrlSetState ($rdp, $GUI_HIDE)
			GUICtrlSetState ($arrow_up, $GUI_HIDE)
			GUICtrlSetState ($block, $GUI_HIDE)
			GUICtrlSetState ($arrow_down, $GUI_SHOW)

		Case $menu_file_restart ;Рестарт программы.
			_Restart()

		Case $shutdown ;Выключить компьютер.
			_SendCommand('#sdn')

		Case $logout ;Выйти из системы.
			_SendCommand('#lgt')

		Case $audio_start ;Воспроизведение аудиофайла.
			_SendCommand('#pbk')

		Case $audio_listen ;Запись аудиофайла.
			_SendCommand('#rcd')

		Case $reboot ;Перезагрузка компьютера.
			_SendCommand('#rbt')

		Case $menu_settings_student ;Открыть настройки ученика.
			_SendCommand('#sts')

		Case $block ;Заблокировать экран.
			_SendCommand('#bck')

		Case $screen ;Скриншот экрана.
			$number = 0
			For $i = 0 to $students_IP[0][0]-1
				If GuiCtrlRead($CheckBoxes[$i]) = $GUI_CHECKED Then $number += 1 ;Отслеживаем количество выделенных компьютеров.
			Next

			If $number = 0 Or $number > 1 Then
				MsgBox(0, "Уведомление", "Выбрано более одного компьютера или не выбрано ни одного вовсе.", 0, $form)
			Else
				_SendCommand('#scr')
				If $tcp <> 0 Then
					Sleep(1000)
					_GDIPlus_Startup()
						$hImage = _GDIPlus_BitmapCreateFromFile($address[2][1] & "Screenshot1.jpg")
						$size = _GDIPlus_ImageGetDimension($hImage)
						_GDIPlus_ImageDispose($hImage)
					_GDIPlus_ShutDown()

					$form_screen = GUICreate("Скриншот", $size[0], $size[1])
					$pic = GUICtrlCreatePic($address[2][1] & "Screenshot1.jpg", -1, -1, 0, 0)
					GUICtrlSetState(-1, $GUI_DISABLE)
					$button_refresh = _Skin_AddButton(($size[0] - 80), ($size[1] + 20 - $size[1]), 64, 64, $refresh, $refresh, $refresh, $refresh, $refresh, 1)
					GUISetState(@SW_SHOW, $form_screen)

					GUISetIcon($ico) ;
					GUICtrlSetImage ($form_screen, $ico) ;Прикручиваем иконку.

					While 1
						_Skin_Helper($form_screen)
						$nMsg = GUIGetMsg()
						Switch $nMsg
							Case $GUI_EVENT_CLOSE
								IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 0) ;Указываем, что при следующем старте программы открывать настройки не надо.
								IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 1)
								_Restart()

							Case $button_refresh
								_SendCommand('#scr')
								Sleep(500)
								GUICtrlDelete($button_refresh)
								GUICtrlSetImage($pic, $address[2][1] & "Screenshot1.jpg")
								$button_refresh = _Skin_AddButton(($size[0] - 80), ($size[1] + 20 - $size[1]), 64, 64, $refresh, $refresh, $refresh, $refresh, $refresh, 1)
						EndSwitch
					WEnd
				EndIf
			EndIf

		Case $system_info ;Получить системную информацию компьютера.
			_SendCommand('#inf')
			MsgBox(0, 'Уведомление', 'Файл создается и будет доступен в ближайшее время.')

		Case $message ;Отправить сообщение.
			Global $text = InputBox("Окно ввода", "Введите ваше сообщение:", "", "", -1, -1, Default, Default, 0, $form)
			If $text <> "" Then _SendCommand('#msg', $text)

		Case $program_start ;Запуск программы.
			Global $text = FileOpenDialog("", @WindowsDir, "Приложения (*.exe)") ;Выбрать программу для запуска.
			If $text <> "" Then _SendCommand('#lnh', $text)

		Case $web_show ;Открыть веб-страницу.
			Global $text = InputBox("Окно ввода", "Введите адрес веб-страницы. Необходимая страница будет открыта в Google Chrome.", "", "", -1, -1, Default, Default, 0, $form)
			If $text <> "" Then _SendCommand('#wpg', $text)

		Case $file_send ;Отправить файл.
			For $i = 1 to $students_IP[0][0]
				If GuiCtrlRead($CheckBoxes[$i - 1]) = $GUI_CHECKED Then
					$checked = 1
				EndIf
			Next
			If $checked = 0 Then
				MsgBox(0, 'Уведомление', 'Не выбрано ни одного компьютера')
			Else
				Global $file = FileOpenDialog("", "", "all(*.*)")
				If $file <> "" Then
					$check = 1
					$string = StringLen($file) ;Определяем длину пути к файлу.

					For $i = 1 to $string
						$chr = StringRight($file, $i) ;Поочередно справа смотрим каждый символ.
						If Asc($chr) = 92 Then ;Если это слэш.
							$text = StringTrimLeft($chr, 1) ;Оставляем только название файла.
							ExitLoop
						EndIf
					Next

					$form_send_file = GUICreate("Teacher Assistant", 450, 313, 393, 321)
					$edit_ip = GUICtrlCreateEdit("IP компьютеров:" & @CRLF, 15, 15, 150, 227, $ES_READONLY)
					$edit_log = GUICtrlCreateEdit("Лог" & @CRLF, 180, 41, 250, 201, $ES_AUTOVSCROLL + $WS_VSCROLL + $ES_NOHIDESEL + $ES_WANTRETURN)
					$label_file = GUICtrlCreateLabel("Файл: " & $text, 178, 15, 241, 24)
					$progressbar = GUICtrlCreateProgress(16, 264, 337, 33)
					$button_send = GUICtrlCreateButton("Отправить", 364, 263, 69, 35)

					GUICtrlSendMsg($edit_ip, $EM_LIMITTEXT, -1, 0)
					GUICtrlSendMsg($edit_log, $EM_LIMITTEXT, -1, 0)
					GUICtrlSetFont($label_file, 13, 400, 0, "MS Sans Serif")

					GUISetState(@SW_DISABLE, $form)
					GUISetState(@SW_SHOW, $form_send_file)
					GUICtrlSetData($edit_ip, @CRLF, 1)

					GUISetIcon($ico) ;
					GUICtrlSetImage ($form_send_file, $ico) ;Прикручиваем иконку.

					For $i = 1 To $students_IP[0][0] ;Заполняем поле IP компьютеров.
						If GuiCtrlRead($CheckBoxes[$i - 1]) = $GUI_CHECKED Then
							GUICtrlSetData($edit_ip, $students_IP[$i][1] & @CRLF, 1)
						EndIf
					Next

					While $check = 1
						$nMsg = GUIGetMsg()
						Switch $nMsg
							Case $GUI_EVENT_CLOSE
								IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 0) ;Указываем, что при следующем старте программы открывать настройки не надо.
								IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 1)
								_Restart()

							Case $button_send
								For $i = 1 to $students_IP[0][0]
									If GuiCtrlRead($CheckBoxes[$i - 1]) = $GUI_CHECKED Then
										_SendFile($students_IP[$i][1]) ;Передача файла.
									EndIf
								Next
						EndSwitch
					WEnd
				EndIf
			EndIf
		Case $rdp
			$number = 0
			For $i = 0 to $students_IP[0][0]-1
				If GuiCtrlRead($CheckBoxes[$i]) = $GUI_CHECKED Then $number += 1 ;Отслеживаем количество выделенных компьютеров.
			Next

			If $number = 0 Or $number > 1 Then
				MsgBox(0, "Уведомление", "Одновременно можно подключиться только к одному сеансу. Пожалуйста, выберите один компьютер, затем повторите попытку снова.", 0, $form)
			Else
				For $i = 0 to $students_IP[0][0]-1
					If GuiCtrlRead($CheckBoxes[$i]) = $GUI_CHECKED Then $number = $i ;Если выделен один компьютер.
				Next
				Run("mstsc.exe /v:" & $students_IP[$number + 1][1]) ;Отправляем на выделенный IP команду Windows.
			EndIf

		Case $Button[0] To $Button[$value - 1]
			Global $number = 0
			Global $demonstration = @ScriptDir & '\Demonstration.ini'
			Global $file = IniRead($demonstration, "", "file", 5) ;Файл скриншота
			Global $uptime = IniRead($demonstration, "", "uptime", 0.1) ;Частота обновления в сек.
			For $i = 1 To $value ;В указанный диапазон также попадают значения других кнопок. Исключаем их.
				if $nMsg = 2 + 5*$i Then
					$number = 1
				EndIf
			Next

		If $number = 0 Then
				IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 0)
				IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 1)
				Global $tcp = 1, $while = 1
				$form_demonstration_settings = GUICreate("Настройки", 210, 239, 367, 293)

				$combo_screen = GUICtrlCreateCombo("800*600", 15, 35, 177, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))

				$input_uptime = GUICtrlCreateInput($uptime, 16, 90, 177, 21)
				$input_demonstration_net = GUICtrlCreateInput($file, 16, 145, 150, 21)

				$label_screen = GUICtrlCreateLabel("Разрешение изображения", 15, 15, 138, 17)
				$label_uptime = GUICtrlCreateLabel("Частота кадров", 15, 70, 85, 17)
				$label_demonstration_net = GUICtrlCreateLabel("Путь к сетевому диску", 15, 125, 120, 17)

				$button_file_select = GUICtrlCreateButton("...", 168, 144, 26, 23)
				$button_demonstration_exit = GUICtrlCreateButton("Выйти", 16, 182, 85, 41)
				$button_demonstration_start = GUICtrlCreateButton("Старт", 110, 182, 85, 41)

				GUICtrlSetData($combo_screen, "1024*768|1280*1024")
				GUISetState(@SW_SHOW, $form_demonstration_settings)

				GUISetIcon($ico) ;
				GUICtrlSetImage ($form_demonstration_settings, $ico) ;Прикручиваем иконку.

					While $while = 1
						$nMsg = GUIGetMsg()
						Switch $nMsg

							Case $GUI_EVENT_CLOSE
								IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 0) ;Указываем, что при следующем старте программы открывать настройки не надо.
								IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 1)
								_Restart()

							Case $button_file_select
								$file = FileSelectFolder('Выбрать путь', @HomeDrive, 1)
								If @error <> 1 then GUICtrlSetData($input_demonstration_net, $file)

							Case $button_demonstration_start
								_SendCommand('#cpr')
								IniWrite($demonstration, "", "uptime", GUICtrlRead($input_uptime)) ;Сохраняет указанные настройки для их дальнейшего использования.
								IniWrite($demonstration, "", "screen_size", GUICtrlRead($combo_screen)) ;Сохраняет указанные настройки для их дальнейшего использования.
								Global $screen_size = IniReadSection(@ScriptDir & '\Demonstration.ini', '')
								$check = 1
								;Операция, аналогичная той, когда от адреса отделялось название файла. Здесь разрешение экрана расшифровывается на два значения (800х600 на 800 и 600)
								$string = StringLen($screen_size[2][1])
								For $i = 1 to $string
									$chr = StringRight($screen_size[2][1], $i)
									If Asc($chr) = 42 Then
										$height = StringTrimLeft($chr, 1)
										$width = StringTrimRight($screen_size[2][1], StringLen($height) + 1)
										ExitLoop
									EndIf
								Next
								Sleep(500)
								Global $form_demonstration = GUICreate("Демонстрация экрана", $width, $height)
								Global $Pic = GUICtrlCreatePic($File & "Screenshot1.jpg", -1, -1, $width, $height) ;Файл может записываться в данный момент и быть недоступным.
								If @error Then $Pic = GUICtrlCreatePic($File & "Screenshot2.jpg", -1, -1, $width, $height)

								GUISetState(@SW_SHOW, $form_demonstration)
								GUISetState(@SW_HIDE, $form_demonstration_settings)
								GUISetState(@SW_HIDE, $form)

								GUISetIcon($ico) ;
								GUICtrlSetImage ($form_demonstration, $ico) ;Прикручиваем иконку.

								While $check = 1
									$nMsg = GUIGetMsg()
									Switch $nMsg
										Case $GUI_EVENT_CLOSE
											IniWrite($address[2][1] & "screen.ini", "screen", "screen", 0)
											_ImageDelete()
											IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 0) ;Указываем, что при следующем старте программы открывать настройки не надо.
											IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 1)
											_Restart()
									EndSwitch
								_UPdate()
								sleep(20)
								WEnd
						EndSwitch
					WEnd
			EndIf

		Case $menu_help_about
			$check = 1

			$form_about = GUICreate("О программе", 297, 153, 637, 371)
			$button_pic_about = _Skin_AddButton(10, 10, 128, 128, $icopng, $icopng, $icopng, $icopng, $icopng, 1)

			$Label1 = GUICtrlCreateLabel("Teacher Assistant", 148, 10, 139, 27)
			$Label2 = GUICtrlCreateLabel("Автор: Макрутин", 148, 49, 140, 27)
			$Label3 = GUICtrlCreateLabel("Константин", 148, 72, 95, 27)
			$Label4 = GUICtrlCreateLabel("Version 1.1", 148, 111, 92, 27)

			GUICtrlSetFont($Label1, 14, 400, 0, "calibri")
			GUICtrlSetFont($Label2, 14, 400, 0, "calibri")
			GUICtrlSetFont($Label3, 14, 400, 0, "calibri")
			GUICtrlSetFont($Label4, 14, 400, 0, "calibri")

			GUISetState(@SW_SHOW)

			GUISetIcon($ico) ;
			GUICtrlSetImage ($form_about, $ico) ;Прикручиваем иконку.

			While $check = 1
				_Skin_Helper($form_about)
				$nMsg = GUIGetMsg()
				Switch $nMsg

					Case $GUI_EVENT_CLOSE
						GUISetState(@SW_HIDE, $form_about)
						GUISetState(@SW_SHOW, $form)
						$check = 0
				EndSwitch
			WEnd

		Case $menu_settings_file
			Run(@ComSpec & " /c " & @ScriptDir & '\settingsT.ini', "", @SW_HIDE)

		Case $menu_settings_open
			$check = 1 ;Переменная, которая отвечает за главный цикл.

			$form_settings_main = GUICreate("Настройки", 370, 199, 426, 384)

			$text_net = GUICtrlCreateLabel("Адрес сетевого диска", 15, 10, 148, 23)
			$text_port = GUICtrlCreateLabel('Порт', 15, 65, 37, 23)

			$input_net = GUICtrlCreateInput($address[1][1], 15, 30, 145, 21)
			$input_port = GUICtrlCreateInput($address[2][1], 15, 85, 186, 21)

			$hide_pc = GUICtrlCreateCheckbox("Скрыть выключенные ПК", 220, 14, 135, 26, BitOR($GUI_SS_DEFAULT_CHECKBOX,$BS_MULTILINE))
			$hide_notifications = GUICtrlCreateCheckbox("Скрыть подсказки", 220, 69, 98, 26, BitOR($GUI_SS_DEFAULT_CHECKBOX,$BS_MULTILINE))

			$button_settings_exit = GUICtrlCreateButton("Назад", 14, 140, 111, 43)
			$button_settings_save = GUICtrlCreateButton("Сохранить", 129, 140, 111, 43)
			$button_settings_ip = GUICtrlCreateButton("Перейти к IP", 244, 140, 111, 43)
			$button_settings_open = GUICtrlCreateButton("...", 163, 29, 38, 23)

			GUICtrlSetFont($text_net, 10, 400, 0, "MS Sans Serif")
			GUICtrlSetFont($text_port, 10, 400, 0, "MS Sans Serif")
			GUICtrlSetFont($hide_pc, 10, 400, 0, "MS Sans Serif")
			GUICtrlSetFont($hide_notifications, 10, 400, 0, "MS Sans Serif")

			If $ini_checkbox[1][1] = 1 Then
				GUICtrlSetState ($hide_pc, $GUI_CHECKED)
			Else
				GUICtrlSetState ($hide_pc, $GUI_UNCHECKED)
			EndIf

			If $ini_checkbox[2][1] = 1 Then
				GUICtrlSetState ($hide_notifications, $GUI_CHECKED)
			Else
				GUICtrlSetState ($hide_notifications, $GUI_UNCHECKED)
			EndIf

			GUISetState(@SW_HIDE, $form)
			GUISetState(@SW_SHOW, $form_settings_main)

			GUISetIcon($ico) ;
			GUICtrlSetImage($form_settings_main, $ico) ;Прикручиваем иконку.

			While $check = 1
				If $restart[1][1] = 1 Then ;Если программа запустилась при помощи рестарта (при добавлении или удалении ip, то сразу открываются настройки ip).
					Global $nMsg = $button_settings_ip
				ElseIf $restart[1][1] = 0 Then
					Global $nMsg = GUIGetMsg()
				EndIf
				Switch $nMsg

					Case $GUI_EVENT_CLOSE, $button_settings_exit
						IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 0) ;Указываем, что при следующем старте программы открывать настройки не надо.
						IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 1)
						$check = 0
						_Restart()

					Case $button_settings_save
						_Save(2)

					Case $button_settings_open
						$file = FileSelectFolder('Выбрать путь', @HomeDrive, 1)
						If @error <> 1 then GUICtrlSetData ($input_net, $file)

					Case $button_settings_ip
						$1 = GUISetState(@SW_SHOW, $form_settings_ip) ;Проверяем, были ли уже отрисованы элементы. Если да, то пропускаем этот шаг.
						If $1 = 0 Then _CreateElements()

						$ini_checkbox = IniReadSection(@ScriptDir & '\settingsT.ini', 'CheckBox')
						$while = 1 ;Переменная, отвечающая за цикл.
						$students_IP = IniReadSection(@ScriptDir & '\settingsT.ini', 'Students IP')

						GUISetState(@SW_SHOW, $form_settings_ip)
						GUISetState(@SW_DISABLE, $form_settings_main)

						If $ini_checkbox[2][1] = 0 Then ;Если уведомления можно показывать, а также программа не была перезапущена из-за добавления или удаления ip, показываем уведомление.
							If $notification[1][1] = 1 Then TrayTip ('Уведомление', 'Пожалуйста, не изменяйте названия на уже существующие. Номера компьютеров должны идти строго по возрастающей.', Default, 2)
						EndIf

						While $while = 1
						_Skin_Helper($form_settings_ip)
						$nMsg = GUIGetMsg()
						Switch $nMsg
							Case $GUI_EVENT_CLOSE
								_Save(1)
								IniWrite(@ScriptDir & '\settingsT.ini', 'Notification', 'Notification', 1) ;Указываем, что уведомление о рамках снова можно показывать (оно показывается 1 раз)
								GUISetState(@SW_HIDE, $form_settings_ip)
								GUISetState(@SW_ENABLE, $form_settings_main)
								WinActivate($form_settings_main) ;После команды @SW_ENABLE программа не является активным окном.
								IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 0) ;Указываем, что при следующем старте программы открывать настройки не надо.
								$restart = IniReadSection(@ScriptDir & '\settingsT.ini', 'Restart')
								$while = 0

							Case $button_add
								_Save(1)
								$name = StringTrimLeft($students_IP[$value][0], 10) ;Определяем номер компьютера.
								$text = InputBox('Окно ввода', 'Введите новый адрес:', "", "", -1, -1, Default, Default, 0, $form_settings_ip)

								If $text <> "" Then
									IniWrite(@ScriptDir & '\settingsT.ini', "Students IP", "Компьютер " & $name + 1, $text)
									If Ping($text) <> 0 Then
										IniWrite(@ScriptDir & '\OnlineS.ini', "Students Online", "Компьютер " & $name + 1, $text)
									EndIf
									IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', "value", 1) ;Указываем, что при следующем старте программы надо открыть настройки.
									IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 1)
									_Restart()
								EndIf

							Case $Button_settings[0] To $Button_settings[$value - 1] ;Выделяем диапозон, в котором находятся все иконки компьютеров.
								_Save(1)
								Global $number = 0
								For $i = 0 To $value-1
									If $nMsg = (49 + 4*$value) Then ;В этот диапазон могут попадать другие элементы (строки ввода). Подстраховываемся и убеждаемся, что было нажато то, что нам нужно.
										$number = 1
									EndIf
								Next
								If $number = 0 Then
									If $value = 1 Then
										MsgBox(0, "Уведомление", "Нельзя удалять последний IP-адрес. Вы всегда можете изменить IP без удаления.", 0, $form_settings_ip)
									EndIf
								Else
									For $i = 0 to $students_IP[0][0]-1
										If $Button_settings[$i] = $nMsg Then  $number = $i ;Определяем порядковый номер нажатой кнопки.
									Next
									$students_online = IniReadSection(@ScriptDir & '\OnlineS.ini', 'Students Online')
									If ($students_online <> 1) Then
										For $i = 1 To $students_online[0][0]
											If $students_online[$i][0] = $students_IP[$number + 1][0] Then
												IniDelete(@ScriptDir & '\OnlineS.ini', "Students Online", $students_online[$i][0])
											EndIf
										Next
									EndIf
									IniDelete (@ScriptDir & '\settingsT.ini', "Students IP", $students_IP[$number + 1][0])
									IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', "value", 1)
									IniWrite(@ScriptDir & '\OnlineS.ini', 'Value', "value", 1)
									_Restart()
								EndIf
						EndSwitch
					WEnd
				EndSwitch
			WEnd
	EndSwitch
WEnd

Func SendTCP($students_IP, $dannie) ;Добавим функцию отправки сообщения на ПК ученика, принимает 2 параметра - 1-й - ip, 2-й - текст сообщения.
	TCPStartup() ;Инициировать использование службы TCP.
		$port=400
		$socket = TCPConnect($students_IP, $port) ;Указыываем ОС создать сокет, подключенный к указанному адресу.
		TCPSend($socket, $dannie) ;Отправляем данные на сервер.
		If @error <> 0 Then
			Msgbox(0, "Уведомление", "Не удалось отправить данные на сервер " & $students_IP, 0, $form)
			Global $tcp = 0
		Else
			Global $tcp = 1
		EndIf
		TCPCloseSocket($socket) ;Закрываем сокет.
    TCPShutdown() ;Завершить использование службы TCP.
EndFunc

Func _AllCheckbox()
	If $check = 0 Then ;По умолчанию переменная равна нулю, то есть галочка в чекбоксе не стоит.
	    For $i = 1 To $students_IP[0][0] ;Загружаем значение переменной.
			GUICtrlSetState ($CheckBoxes[$i - 1], $GUI_CHECKED) ;Ставим галочку на чекбокс этой переменной.
	    Next ;Повторяем.
		$check = 1 ;Когда все галочки поставлены, записываем в переменную 1 - это значит, что на главном чекбоксе сейчас галочка.
	ElseIf $check = 1 Then ;Операция, обратная предыдущей. Нужна, чтобы снимать галочки.
		For $i = 1 To $students_IP[0][0]
			GUICtrlSetState ($CheckBoxes[$i - 1], $GUI_UNCHECKED)
		Next
        $check = 0
	EndIf
EndFunc

Func _SendCommand($dannie, $info = "")
	For $i=0 to $students_IP[0][0]-1
		If GuiCtrlRead($CheckBoxes[$i]) = $GUI_CHECKED Then ;Проверяем, стоит ли галочка у очередного ПК, если стоит, то.
			$checked = 1
			If $info <> "" Then
				SendTCP($students_IP[$i+1][1], $dannie & $info)
			ElseIf $info = 0 Then
				SendTCP($students_IP[$i+1][1], $dannie)
			EndIf
		EndIf
	Next
	If $checked = 0 Then
		MsgBox(0, "Уведомление", "Не выбрано ни одного компьютера.", 0, $form)
	EndIf
	$checked = 0
EndFunc

Func _SettingsSetup()
	$create = MsgBox(0x4, "Уведомление", "На компьютере отсутствует или недоступен файл с настройкми. Создать новый?")
	If $create = 7 Then
			Exit
	ElseIf $create = 6 Then
		$setup_settings = _WinAPI_CreateFile(@ScriptDir & "\settingsT.ini", 1)
		If $setup_settings <> 0 Then
			_WinAPI_CloseHandle($setup_settings)
			IniWriteSection(@ScriptDir & "\settingsT.ini", "Address", "port=400" & @LF & "net=Z:\" & @LF)
		    IniWriteSection(@ScriptDir & "\settingsT.ini", "Restart", "value=0" & @LF)
			IniWriteSection(@ScriptDir & "\settingsT.ini", "CheckBox", "Pc=1" & @LF & "Notifications=1" & @LF)
			IniWriteSection(@ScriptDir & "\settingsT.ini", "Notification", "Notification=0" & @LF)
			IniWriteSection(@ScriptDir & "\settingsT.ini", "Students IP", "Компьютер 1=128.0.0.1" & @LF)
			Global $students_IP = IniReadSection(@ScriptDir & '\settingsT.ini', 'Students IP')
			Global $address = IniReadSection(@ScriptDir & '\settingsT.ini', 'Address')
		ElseIf $setup_settings = 0 Then
			MsgBox(0x5, "Уведомление", "Ошибка при создании файла. Проверьте права пользователя и повторите попытку.")
			Exit
		EndIf
	EndIf
EndFunc

Func _Restart()
	If @Compiled Then
		Run(@ScriptFullPath)
	Else
		$hProc = @AutoItExe & ' "' & @ScriptFullpath & '"'
		Run($hProc)
	EndIf
	IniWrite(@ScriptDir & '\settingsT.ini', 'Notification', 'Notification', 0)
	Exit
EndFunc

Func _Save($information)
	If $information = 1 Then ;Сохранение ip.
		Global $number = 0
		IniDelete (@ScriptDir & '\settingsT.ini', "Students IP")
		For $i = 1 To $students_IP[0][0]
			$text_ip = GUICtrlRead($Input_IP[$i - 1])
			$text_name = GUICtrlRead($Input_Name[$i - 1])
			$ini_read = IniRead(@ScriptDir & '\settingsT.ini', "Students IP", $text_name, 1)
			If $ini_read <> 1 Then
				MsgBox(0, 'Уведомление', 'Объект с номером ' & StringTrimLeft($text_name, 10) & ' уже существует.')
			EndIf
			IniWrite (@ScriptDir & '\settingsT.ini', "Students IP", $text_name, $text_ip)
			If @error = 1 Then MsgBox(0, 'Уведомление', 'Строка "' & $text_name & '" Не сохранена.', 0, $form_settings_ip)
		Next
	ElseIf $information = 2 Then ;Сохранение основных настроек.
		IniWrite(@ScriptDir & '\settingsT.ini', 'Address', 'port', GUICtrlRead($input_port))
		IniWrite(@ScriptDir & '\settingsT.ini', 'Address', 'net', GUICtrlRead($input_net))
		IniWrite(@ScriptDir & '\settingsT.ini', 'Restart', 'value', 1)
		ToolTip("Сохранено")
		Sleep(700)
		ToolTip("")
		If GUICtrlRead($hide_pc) = $GUI_CHECKED Then
			IniWrite(@ScriptDir & '\settingsT.ini', 'CheckBox', 'Pc', 1)
		ElseIf GUICtrlRead($hide_pc) = $GUI_UNCHECKED Then
			IniWrite(@ScriptDir & '\settingsT.ini', 'CheckBox', 'Pc', 0)
		EndIf
		If GUICtrlRead($hide_notifications) = $GUI_CHECKED Then
			IniWrite(@ScriptDir & '\settingsT.ini', 'CheckBox', 'Notifications', 1)
		ElseIf GUICtrlRead($hide_notifications) = $GUI_UNCHECKED Then
			IniWrite(@ScriptDir & '\settingsT.ini', 'CheckBox', 'Notifications', 0)
		EndIf
	EndIf
EndFunc

Func _CreateElements()
	$value = 0
	$left_pos = 96
	$top_pos = 14
	$form_size = Ceiling(($students_IP[0][0] + 1)/4)*88 ;Подсчитываем необходимую длину формы, учитывая кнопку +.
	Global $form_settings_ip = GUICreate("Настройки IP", 745, $form_size, 442, 249)
	Global $students_online = IniReadSection(@ScriptDir & '\OnlineS.ini', 'Students Online')

	GUISetIcon($ico) ;
	GUICtrlSetImage ($form_settings_ip, $ico) ;Прикручиваем иконку.

	For $i = 1 To $students_IP[0][0] ;Создание динамических элементов GUI
		If ($students_online <> 1) Then
			_Sort($i)
			If $sorted = 1 Then
				$Button_settings[$i - 1] = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $pic_pc, $remove, $remove, $pic_pc, $pic_pc, 1) ;Создание кнопок в виде окнок компьютеров.
			Else
					$Button_settings[$i - 1] = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $pc_offline, $remove, $remove, $pc_offline, $pc_offline, 1)
			EndIf
		Else
				$Button_settings[$i - 1] = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $pc_offline, $remove, $remove, $pc_offline, $pc_offline, 1)
		EndIf

		Global $sorted = 0

		$Input_Name[$i - 1] = GUICtrlCreateInput($students_IP[$i][0], $left_pos, $top_pos, 90, 21) ;Имя компьютера.
		$Input_IP[$i - 1] = GUICtrlCreateInput($students_IP[$i][1], $left_pos, $top_pos+23, 90, 21) ;IP.

		$left_pos += 178
		$value += 1

		If (Mod($value, 4) = 0) Then ;Когда количество иконок превышает 4, переходим на новый ряд (см. скриншоты).
			$top_pos += 88
			Global $left_pos = 96
		EndIf
	Next

	Global $button_add = _Skin_AddButton($left_pos-72, $top_pos, 64, 64, $add, $add, $add, $add, $add, 1)
EndFunc

Func _Sort($sort)
	For $j = 1 To $students_online[0][0]
		If $students_IP[$sort][1] = $students_online[$j][1] Then
			Global $sorted = 1
		EndIf
	Next
EndFunc

Func _LogWrite($text)
	$preset = @HOUR & ':' & @MIN & ':' & @SEC & ': '
	_GUICtrlEdit_BeginUpdate($edit_log)
	_GUICtrlEdit_AppendText($edit_log, $preset & $text & @CRLF)
	_GUICtrlEdit_LineScroll($edit_log, 0, _GUICtrlEdit_GetLineCount($edit_log))
	_GUICtrlEdit_EndUpdate($edit_log)
EndFunc

Func _SendFile($ip)
	_LogWrite("Создаю сокет " & $ip & ":" & $address[1][1])
	TCPStartup()
	$iListenSocket = TCPConnect($ip, $address[1][1])
	TCPSend($iListenSocket, '#act')
	_TCP_filetransfer_send($iListenSocket, $file, 100000, 1048576, 'FILETRANSFER_callback')
	If @error Then
		_LogWrite('Ошибка: ' & @error & ' ' & @extended)
		_LogWrite('Файл не передан')
	Else
		_LogWrite('Файл передан')
	EndIf
	TCPCloseSocket($iListenSocket)
	TCPShutdown()
EndFunc

Func _UPdate() ;обоновляет картинку
		If $n = 0 Then
			GUICtrlSetImage($pic, $File & "Screenshot1.jpg")
			$n = 1
		ElseIf $n = 1 Then
			GUICtrlSetImage($pic, $File & "Screenshot2.jpg")
			$n = 0
		EndIf
EndFunc

Func _ImageDelete()
	FileDelete($File & "Screenshot1.jpg")
	FileDelete($File & "Screenshot2.jpg")
EndFunc
