Что нового

[Элементы GUI] Как нарисовать точку в окне GUI и эффективно ее двигать?

Dima1337

Осваивающий
Сообщения
186
Репутация
24
Доброго времени суток.
Возник такой вопрос, как двигать нарисованную точку по окну GUI не стирая и закрашивая а просто меняя координаты?
Ну и собственно как ее нарисовать?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Код:
_WinAPI_DrawLine
_GDIPlus_GraphicsDrawLine

ну и все сопутствующие.
а зачем рисовать? не проще создать Pic, вставить изображение точки и двигать сам контрол Pic?
 
Автор
Dima1337

Dima1337

Осваивающий
Сообщения
186
Репутация
24
joiner сказал(а):
не проще создать Pic, вставить изображение точки и двигать сам контрол Pic?
Разумно, где можно с примерами ознакомится?
 

ra4o

AutoIT Гуру
Сообщения
1,165
Репутация
246
В справке по этим функциям
Код:
GUICtrlCreatePic
и
Код:
GUICtrlSetPos
, а точку можно нарисовать
Код:
GUICtrlSetGraphic
там шикарный пример, точка тоже есть !
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
с элементом pic неплохая идея, но при перетаскивании запаздывание видно. возможно, это не всегда критично. ( в шашки поиграть можно :smile: )
накидал пример (в архиве)
все картинки перетаскиваются мышкой, сохраняя разницу координат
Код:
#include <Icons.au3>
Local $PP = @ScriptDir & '\'
Local $array[6] = [$PP & '1.png', $PP & '2.png', $PP & '3.png', $PP & '4.png', $PP & '5.png', $PP & '6.png']
Local $aInfo, $msg, $msg1, $aInfo1, $WX, $WY, $PC, $pic, $XD, $YD, $WX1 = 100,$WY1
Local $Form1 = GUICreate("Form1", 500, 500, -1, -1), $n = 0
GUISetState()
_GDIPlus_Startup(); в библиотеке Icons.au3 отключены эти функции

For $i = 3 To 5
	$pic = GUICtrlCreatePic('', $WX1, $WY1, 100, 100)
	_SetImage($pic, $array[$i])
	$WX1 += 100
Next

For $i = 1 To 50
	If $n = 3 Then $n = 0
	$pic = GUICtrlCreatePic('', $WX, $WY, 10, 10)
	_SetImage($pic, $array[$n])
	$WX += 10
	$WY += 10
	$n += 1
Next

_GDIPlus_Shutdown()
While 1
	$msg = GUIGetMsg()
	Switch $msg
		Case -7
			$aInfo = GUIGetCursorInfo($Form1)
			If $aInfo[4] Then
				$PC = ControlGetPos($Form1, '', $aInfo[4])
				$XD = $aInfo[0] - $PC[0]
				$YD = $aInfo[1] - $PC[1]
				While 1
					$msg1 = GUIGetMsg()
					Switch $msg1
						Case -11
							$aInfo1 = GUIGetCursorInfo($Form1)
							GUICtrlSetPos($aInfo[4], $aInfo1[0] - $XD, $aInfo1[1] - $YD, $PC[2], $PC[3])
						Case -8
							ExitLoop
						Case -3
							Exit
					EndSwitch
				WEnd
			EndIf
		Case -3
			Exit
	EndSwitch
WEnd
 

Вложения

  • Безымянный.jpg
    Безымянный.jpg
    36 КБ · Просмотры: 26
  • 555.rar
    52 КБ · Просмотры: 17

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
joiner сказал(а):
с элементом pic неплохая идея, но при перетаскивании запаздывание видно. возможно, это не всегда критично. ( в шашки поиграть можно :smile: )
Уберите GUIGetMsg() из второго цикла и на время перетаскивания включите режим "OnEvent" для утилизации сообщений и переполнения очереди.

Код:
While 1
	$msg = GUIGetMsg()
	Switch $msg
		Case -7
			$aInfo = GUIGetCursorInfo($Form1)
			If $aInfo[4] Then
				$ID = $aInfo[4]
				$PC = ControlGetPos($Form1, '', $ID)
				$XD = $aInfo[0] - $PC[0]
				$YD = $aInfo[1] - $PC[1]
				Opt('GUIOnEventMode', 1)
				While $aInfo[2]
					GUICtrlSetPos($ID, $aInfo[0] - $XD, $aInfo[1] - $YD, $PC[2], $PC[3])
					$aInfo = GUIGetCursorInfo($Form1)
				WEnd
				Opt('GUIOnEventMode', 0)
			EndIf
		Case -3
			Exit
	EndSwitch
WEnd
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
тогда до кучи вариант - изображения не выходят за рамки окна
Код:
Local $XDD, $YDD
While 1
	$msg = GUIGetMsg()
	Switch $msg
		Case -7
			$aInfo = GUIGetCursorInfo($Form1)
			If $aInfo[4] Then
				$ID = $aInfo[4]
				$PC = ControlGetPos($Form1, '', $ID)
				$XD = $aInfo[0] - $PC[0]
				$YD = $aInfo[1] - $PC[1]
				Opt('GUIOnEventMode', 1)
				While $aInfo[2]
					GUICtrlSetPos($ID, $XDD, $YDD, $PC[2], $PC[3])
					$aInfo = GUIGetCursorInfo($Form1)
					$XDD = $aInfo[0] - $XD
					$YDD = $aInfo[1] - $YD
					If $XDD <= 0 Then
						$XDD = 0
					ElseIf $XDD >= 500 - $PC[2] Then
						$XDD = 500 - $PC[2]
					EndIf
					If $YDD <= 0 Then
						$YDD = 0
					ElseIf $YDD >= 500 - $PC[3] Then
						$YDD = 500 - $PC[3]
					EndIf
				WEnd
				Opt('GUIOnEventMode', 0)
			EndIf
		Case -3
			Exit
	EndSwitch
WEnd
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
По-хорошему, я бы вообще построил алгоритм на _IsPressed().
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
так?
Код:
While 1
	If _IsPressed('01', $hDLL) Then
		$aInfo = GUIGetCursorInfo($Form1)
		If $aInfo[4] Then
			$ID = $aInfo[4]
			$PC = ControlGetPos($Form1, '', $ID)
			$XD = $aInfo[0] - $PC[0]
			$YD = $aInfo[1] - $PC[1]
			While _IsPressed('01', $hDLL)
				GUICtrlSetPos($ID, $XDD, $YDD, $PC[2], $PC[3])
				$aInfo = GUIGetCursorInfo($Form1)
				$XDD = $aInfo[0] - $XD
				$YDD = $aInfo[1] - $YD
				If $XDD <= 0 Then
					$XDD = 0
				ElseIf $XDD >= 500 - $PC[2] Then
					$XDD = 500 - $PC[2]
				EndIf
				If $YDD <= 0 Then
					$YDD = 0
				ElseIf $YDD >= 500 - $PC[3] Then
					$YDD = 500 - $PC[3]
				EndIf
			WEnd
		EndIf
	EndIf
WEnd
 
Автор
Dima1337

Dima1337

Осваивающий
Сообщения
186
Репутация
24
Такой вот вопрос, как запретить квадратам залезать друг на друга?
Код:
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 615, 437, 192, 124)
GUISetBkColor(0xB4B4B4)
;$Pic1 = GUICtrlCreatePic("", 0, 0, 25, 25)
$Pic2 = GUICtrlCreatePic(@ScriptDir & "\black.jpg", 555, 0, 60, 60)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

AdlibRegister("_gui", 1000)

$once = 0
Global $pic[11] = [], $x[11] = [], $y[11] = []

While 1
	$nMsg = GUIGetMsg()
    Switch $nmsg
        Case -7
            $mouse = GUIGetCursorInfo($Form1)
            If $mouse[4] And $mouse[4] <> $Pic2 Then
                $PC = ControlGetPos($Form1, '', $mouse[4])
                $XD = $mouse[0] - $PC[0]
                $YD = $mouse[1] - $PC[1]
                While 1
                    $msg1 = GUIGetMsg()
                    Switch $msg1
						Case -11
							$mouse1 = GUIGetCursorInfo($Form1)
							$result1 = $mouse1[0] - $XD
							$result2 = $mouse1[1] - $YD
                            $mouse1 = GUIGetCursorInfo($Form1)
                            GUICtrlSetPos($mouse[4], $result1, $result2, $PC[2], $PC[3])
							If $mouse[4] And $mouse1[4] <> $Pic2 Then
								If $result1 > 555 And $result2 < 60 Then GUICtrlDelete($mouse[4])
							EndIf
                        Case -8
                            ExitLoop
                        Case -3
                            Exit
                    EndSwitch
                WEnd
            EndIf
        Case -3
            Exit
    EndSwitch
WEnd

Func cursor()
	$mouse = GUIGetCursorInfo($Form1)
	If $mouse[2] = 1 Then
		GUICtrlSetPos($mouse[4],$mouse[0] - 12,$mouse[1] - 12,25,25)
	EndIf
EndFunc

Func _gui()
	If $once = 0 Then
		For $i = 0 To 10 Step +1
			$x[$i] = Random(0,530,1)
			$y[$i] = Random(0,410,1)
			$Pic[$i] = GUICtrlCreatePic(@ScriptDir & "\test.jpg", $x, $y, 25, 25)
			$once = 1
			ConsoleWrite($i)
		Next
	EndIf
	For $i = 0 To 10 Step +1
		$mouse = GUIGetCursorInfo($Form1)
		If $mouse[4] <> $Pic[$i] Then
			If @error Then ToolTip("Ошибка")
			$RanX = Random(1,10,0)
			$RanY = Random(1,10,0)
			If $RanX + $x[$i] > 530 Then $Ran = -10
			If $RanY + $x[$i] > 410 Then $Ran = -10
			GUICtrlSetPos($Pic[$i], $x[$i] + $RanX, $y[$i] + $RanY, 25, 25)
		EndIf
	Next
EndFunc
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
При создании элементов хранить координаты их сторон (всех четырех сторон каждого элемента). При перемещении элемента проверять текущие координаты его сторон- если эти координаты уже заняты, то ограничивать перемещение. Ну, я это так, навскидку
 
Верх