Что нового

[Элементы GUI] Элементы убегают от мышки или Делаю пасхалку в свою программу

Erection

Чайник
Сообщения
16
Репутация
0
Пишу программку для знакомых, зашел уже достаточно далеко, поэтому решил засунуть сюда пасхалку. По нажатию специальной кнопки чтобы элементы начинали убегать от мыши... Написал примерно сотню строк, вычистил синтаксис и грубую логику, начались серьезные логические ошибки. Отладчика я так понял нет в Autoit-e... Начал кумекать что и как - на текущем моменте программа валится в вечный цикл, причем даже созданный хоткей для выхода из режима пасхалки не принимает.

Запускаем пасхалку:
Код:
...
 Case $msg = $MenuSurprise
 	  MakeSomeFun()
	  HotKeySet("{ESC}","DealEndFunPlease")
 EndSelect


Останавливаем:
Код:
Func DealEndFunPlease()
   $EndFun=False
EndFunc


Основная функция:

Код:
Func MakeSomeFun()
   AutoItSetOption("MouseCoordMode",0)
   HotKeySet("{ESC}","DealEndFunPlease")
   ;Cоздаем массив элементов формы
   CreateArrayOfElements()
   ;Врубаем наш фан   
   $EndFun=True
   
   While $EndFun
	  
	  ;Получаем координаты курсора
	  $Position=MouseGetPos()  
	  ;Определяем размеры массива элементов в отдельную переменную
	  $ArrayUpperBound=UBound($ElemArray)
	  ;Проверяем все элементы массива
	  For $i=0 To $ArrayUpperBound-1
		 ;Если курсор залезает в пределы элемента
		 ;ToolTip("Укурсора:"&$Position[0]&" $ElemArray[$i][0]: "&$ElemArray[$i][0]&" $ElemArray[$i][2]: "&$ElemArray[$i][2])
		 If $Position[0]>=$ElemArray[$i][0] And $Position[0]<=$ElemArray[$i][2] And $Position[1]>=$ElemArray[$i][1] And $Position[0]<=$ElemArray[$i][3] Then
			
			;Определяем с какой стороны залез курсор 
			;ПозицияХ1 элемента - координата Х верхнего левого угла, ПозицияУ2 элемента - координата У нижнего правого угла элемента
			;Если ПозицияХ курсора - ПозицияХ1 элемента > (Ширина элемента)/2          И   ПозицияУ курсора - ПозицияУ2 элемента < (Длина элемента)/2
			
			
			If $Position[0]-$ElemArray[$i][0]>($ElemArray[$i][2]-$ElemArray[$i][0])/2 And $Position[1]-$ElemArray[$i][3]<($ElemArray[$i][1]-$ElemArray[$i][3])/2 Then
				  ;Залез в IV четверть
				  $CoefX=1
				  $CoefY=-1
			EndIf
			
			If $Position[0]-$ElemArray[$i][0]<($ElemArray[$i][2]-$ElemArray[$i][0])/2 And $Position[1]-$ElemArray[$i][3]>($ElemArray[$i][1]-$ElemArray[$i][3])/2 Then
				  ;Залез вo II четверть
				  $CoefX=-1
				  $CoefY=1
			EndIf
			
			If $Position[0]-$ElemArray[$i][0]<($ElemArray[$i][2]-$ElemArray[$i][0])/2 And $Position[1]-$ElemArray[$i][3]<($ElemArray[$i][1]-$ElemArray[$i][3])/2 Then
				  ;Залез в III четверть
				  $CoefX=-1
				  $CoefY=-1
			EndIf
			
			If $Position[0]-$ElemArray[$i][0]>($ElemArray[$i][2]-$ElemArray[$i][0])/2 And $Position[1]-$ElemArray[$i][3]>($ElemArray[$i][1]-$ElemArray[$i][3])/2 Then
				  ;Залез в I четверть
				  $CoefX=1
				  $CoefY=1
			EndIf
			;Съ*бы*аем от курсора
			;Расчеты
			;Определим новые координаты с которыми будем дальше работать, чтобы не портить текущий массив
			$NewPosX1=$ElemArray[$i][0] 
			$NewPosY1=$ElemArray[$i][2]
			$NewPosX2=$ElemArray[$i][1]
			$NewPosY2=$ElemArray[$i][3]
			
			;Расстояние по Х и по У от курсора до каждого угла - то есть на сколько курсор залез в элемент плюс 20 едениц, чтобы элемент еще и отодвинулся от курсора
			;Левый верхний угол
			If $CoefX=-1 And $CoefY=1 Then
			   $DifferenceX=Abs($Position[0]-$ElemArray[$i][0])+20
			   $DifferenceY=Abs($Position[1]-$ElemArray[$i][1])+20
			   ;Правый верхний угол
			ElseIf $CoefX=1 And $CoefY=1 Then
			   $DifferenceX=Abs($Position[0]-$ElemArray[$i][2])+20
			   $DifferenceY=Abs($Position[1]-$ElemArray[$i][1])+20
			   ;Левый нижний угол
			ElseIf $CoefX=-1 And $CoefY=-1 Then
			   $DifferenceX=Abs($Position[0]-$ElemArray[$i][0])+20
			   $DifferenceY=Abs($Position[1]-$ElemArray[$i][3])+20
			   ;Правый нижний угол
			ElseIf $CoefX=-1 And $CoefY=-1 Then
			   $DifferenceX=Abs($Position[0]-$ElemArray[$i][2])+20
			   $DifferenceY=Abs($Position[1]-$ElemArray[$i][3])+20
			EndIf
			;Определим по какой оси будем двигаться с шагом 1, а по какой оси будем двигаться с дробным шагом. Для увеличения плавности движения, то есть количества интервалов выбрана та ось, по которой расстояние больше
			If $DifferenceX>$DifferenceY Then
			   ;Общее время передвижение элемента не должно превышать 1 секунду
			   $SleepInterval=Round(1000/$DifferenceX)
			Else
			   $SleepInterval=Round(1000/$DifferenceY)
			EndIf
			;Движение
			;Пока наш курсор находится в границах +20 единиц, чтобы элемент как бы отскакивал от курсора на немного
			
			While $Position[0]+20>=$NewPosX1 And $Position[1]+20>=$NewPosY1 And $Position[0]+20<=$NewPosX2 And $Position[1]+20<=$NewPosY2
			   
			   ;Смотрим по какой оси движемся с шагом еденицы, по другой оси дробим шаг
			  
			   If $DifferenceX>$DifferenceY Then
				  ;Делаем новые координаты
				  $NewPosX1=$NewPosX1+$CoefX*1
				  $NewPosY1=$NewPosY1+$CoefY*$DifferenceY/$DifferenceX
				  $NewPosX2=$NewPosX2+$CoefX*1
				  $NewPosY2=$NewPosY2+$CoefY*$DifferenceY/$DifferenceX
				  
				  ;Передвигаем на новую позицию элемент, дробные координаты округляем
				  GUICtrlSetPos($ElemArray[$i][4],$NewPosX1,Round($NewPosY1))
			   Else
				  ;Тоже самое, только для другой оси
				  $NewPosX1=$NewPosX1+$CoefX*$DifferenceX/$DifferenceY
				  $NewPosY1=$NewPosY1+$CoefY*1
				  $NewPosX2=$NewPosX2+$CoefX*$DifferenceX/$DifferenceY
				  $NewPosY2=$NewPosY2+$CoefY*1
				  
				  GUICtrlSetPos($ElemArray[$i][4],Round($NewPosX1),$NewPosY1)
			   EndIf
			   ;Делаем небольшой интервал, чтобы растянуть передвижение на 1 секунду
			   Sleep($SleepInterval)
			   
			WEnd
			
			
		 EndIf
		 
		
	  Next
	  ;Пересоздаем массив элементов на случай если что то сдвинулось в прошлый раз
	  CreateArrayOfElements()
	  ;Частота считывания позиции мыши 
	  Sleep(10)
	
   WEnd
	  
   
EndFunc

Функция которая обновляет данные об элементах:
Код:
Func CreateArrayOfElements()
   ;Получаем все данные об элементах
   $Data = _WinAPI_EnumChildWindows($Form)
   ;Создаем глобальный массив размером КоличествоЭлементовФормы*5
   ;В $Data[0][0] хранится количество элементов формы
   Global $ElemArray[$Data[0][0]][5]
   ;Переписываем все данные из массива в свой массив
   For $i=1 To $Data[0][0]-1
	  ;Получаем позицию элемента
	  $PosElem=ControlGetPos("","",$Data[$i][0])
	  ;В пятом элементе храним идентификатор элемента
	  $ElemArray[$i][4]=$Data[$i][0]
	  ;Верхняя левая координата Х
	  $ElemArray[$i][0]=$PosElem[0]	   
	  ;Верхняя левая координата У
	  $ElemArray[$i][1]=$PosElem[1]
	  ;Нижняя правая координата Х
	  $ElemArray[$i][2]=$PosElem[0]+$PosElem[2]
	  ;Нижняя правая координата У
	  $ElemArray[$i][3]=$PosElem[1]+$PosElem[3]
   Next
 EndFunc


Может кто-то подсказать где косяк? Может свежий взгляд и вопросы наведут меня на гениальные идеи или глупые ошибки в коде, может кто то знает как сделать отладчик в этой программе? Пока комментировал для вас код, пару ошибок исправил и кое-что дописал даже :smile:

Сам скрипт


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

После часов отладки тултипами и мсгбоксами подправил кое-какие ошибки, теперь новая проблема - GUICtrlSetPos($ElemArray[$i][4],$NewPosX1,Round($NewPosY1)) не срабатывает... возможно потому что я даю ему ControlID в виде 0x0000000 как его возвращает _WinAPI_EnumChildWindows($Form). Вроде заходит во все циклы и условия, прогоняет их, делает действия, а строки о том что надо двигать элемент управления как будто просто нет! И ошибки не выдает.
 
Верх