Что нового

рисование отрезка с меняющейся длиной поверх окна

yuran2

Хочу все уметь
Сообщения
38
Репутация
0
Версия AutoIt: 3.3.6.1

Описание: :blink:
а) Нужно поверх активного окна рисовать отрезок(прямую) соединяющий две произвольно перемещающиеся точки в активном окне(программы)
б) рядом с отрезком значение расстояния между этими точками в условных единицах

Примечания: точки например зеленая и красная , единицы см,
 
Автор
Y

yuran2

Хочу все уметь
Сообщения
38
Репутация
0
вот скрипт работает но не затирает старые линии при движении точек(рисуется веер) . ? как нарисованные линии стереть
Код:
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#Include <GUIConstantsEx.au3>
#Include <WinAPIEx.au3>
global  $u 

HotKeySet("{ESC}", "Terminate") ; отмена програмы

Func Terminate()  ;  если кнопочка esc нажата вход из программы
	Exit 0
EndFunc 


$hGUI = GUICreate('', 900, 900, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetBkColor(0xABABAB)
_WinAPI_SetLayeredWindowAttributes($hGUI, 0xABABAB, 0, $LWA_COLORKEY)
GUIRegisterMsg($WM_PAINT, 'WM_PAINT')
GUIRegisterMsg($WM_SIZE, 'WM_SIZE')
GUISetState(@SW_SHOWNOACTIVATE)
_GDIPlus_Startup ()


$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
$hPen = _GDIPlus_PenCreate ()

Do
Sleep(50)


$coord = PixelSearch( 15, 70, 706,650, 0xFF0000,10 ) ; ищем координаты яркокрасного 
If  not @error Then
    $a = $coord[0] ;координата х 
	$b = $coord[1] ;координата у 
	

endif

$coordu = PixelSearch( 15, 70, 706,650, 0x00FF00,10 ) ; ищем координаты яркозеленого 
If  not @error Then
    $c = $coordu[0] ;координата х 
	$d = $coordu[1] ;координата у 
	

endif

_GDIPlus_PenSetColor($hPen, 0xFFFF0000)
_GDIPlus_GraphicsDrawLine ($hGraphic, $a+5,$b+5, $c+5,$d+5, $hPen)
;WinMove($hGUI, '', $a+5,$b+5)
Sleep(50)

	Until $a<0
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
Размер отрезка выводится в пикселях (округлено до 3-го знака)
Стирание линии сделал просто: поверх старой рисуется новая с теми же координатами, цветом который "вытравлен" _WinAPI_SetLayeredWindowAttributes; вроде работает :smile:
Паузы между этапами рисования добавил для наглядности.
GUICtrlCreateLabel можно создать один с фиксированными координатами, а внутри функции менять его текст через GUICtrlSetData.
Код:
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPIEx.au3>

HotKeySet("{ESC}", "Terminate")

$hGUI = GUICreate('', 900, 900, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetBkColor(0xABABAB)
GUISetState()
_WinAPI_SetLayeredWindowAttributes($hGUI, 0xABABAB, 0, $LWA_COLORKEY)
_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

$iX1 = 10
$iY1 = 10
$iX2 = 400
$iY2 = 400
_DrawLine($iX1, $iY1, $iX2, $iY2)

Func _DrawLine($iStartX, $iStartY, $iEndX, $iEndY)
	$iLineLength = Sqrt(($iStartX - $iEndX) ^ 2 + ($iStartY - $iEndY) ^ 2) ; длина отрезка по теореме Пифагора :D
	$hLabel = GUICtrlCreateLabel(Round($iLineLength, 3) & ' pixel(s)', $iStartX + 10, $iStartY + 10, 100, 17) ; элемент для отображения длины отрезка
	GUICtrlSetColor($hLabel, 0xFFFF00) ; цвет текста
	$hPenBlueThin = _GDIPlus_PenCreate(0xFF0000FF) ; ручка для синей линии
	$hPenRedBold = _GDIPlus_PenCreate(0xFFFF0000, 2) ; ручка для красной точки
	$hPenGreenBold = _GDIPlus_PenCreate(0xFF00FF00, 2) ; ручка для зеленой точки
	$hEraser = _GDIPlus_PenCreate(0xFFABABAB, 2) ; стирающая ручка

	_GDIPlus_GraphicsDrawEllipse($hGraphic, $iX1 - 2, $iY1 - 2, 4, 4, $hPenRedBold) ; точка СТАРТ
	Sleep(2000)
	_GDIPlus_GraphicsDrawEllipse($hGraphic, $iX2 - 2, $iY2 - 2, 4, 4, $hPenGreenBold) ; точка ФИНИШ
	Sleep(2000)
	_GDIPlus_GraphicsDrawLine($hGraphic, $iX1, $iY1, $iX2, $iY2, $hPenBlueThin) ; линия отрезка
	Sleep(2000)
	_GDIPlus_GraphicsDrawEllipse($hGraphic, $iX1 - 2, $iY1 - 2, 4, 4, $hEraser) ; затираем СТАРТ
	_GDIPlus_GraphicsDrawEllipse($hGraphic, $iX2 - 2, $iY2 - 2, 4, 4, $hEraser) ; затираем ФИНИШ
	_GDIPlus_GraphicsDrawLine($hGraphic, $iX1, $iY1, $iX2, $iY2, $hEraser) ; затираем отрезок
	GUICtrlDelete($hLabel) ; удаляем элемент с текстом
	Sleep(2000)
	; удаление ручек
	_GDIPlus_PenDispose($hPenBlueThin)
	_GDIPlus_PenDispose($hPenRedBold)
	_GDIPlus_PenDispose($hPenGreenBold)
	_GDIPlus_PenDispose($hEraser)
EndFunc   ;==>_DrawLine

_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

Func Terminate()
	Exit
EndFunc   ;==>Terminate
 
Автор
Y

yuran2

Хочу все уметь
Сообщения
38
Репутация
0
Redline
теперь если меняю координаты точки СТАРТ и точка ФИНИШ не могу избавится от мигания
отрезка
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
yuran2 [?]
теперь если меняю координаты точки СТАРТ и точка ФИНИШ не могу избавится от мигания отрезка
Я как обычно поспешил :wall_brake: Забыл сменить имена переменных внутри функции, из-за этого координаты отрезка не менялись (отрезок рисовался один и тот же).
Сделал разделение функции на рисование и стирание (_DrawLine & _EraseLine), чтобы была возможность оставить отрезок (координаты должны совпадать, иначе эффекта не будет!)
Вывод длины отрезка тоже сделал графически:
Код:
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPIEx.au3>

HotKeySet('{ESC}', 'Terminate')

$hGUI = GUICreate('', 900, 900, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST))
GUISetBkColor(0xABABAB)
GUISetState()
_WinAPI_SetLayeredWindowAttributes($hGUI, 0xABABAB, 0, $LWA_COLORKEY)
_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hPenBlueThin = _GDIPlus_PenCreate(0xFF0000FF) ; ручка для синей линии
$hPenRedBold = _GDIPlus_PenCreate(0xFFFF0000, 2) ; ручка для красной точки
$hPenGreenBold = _GDIPlus_PenCreate(0xFF00FF00, 2) ; ручка для зеленой точки
$hEraser = _GDIPlus_PenCreate(0xFFABABAB, 2) ; стирающая ручка
$hBrushYellow = _GDIPlus_BrushCreateSolid(0xFFFFFF00) ; желтая кисть
$hBrushEraser = _GDIPlus_BrushCreateSolid(0xFFABABAB) ; стирающая кисть
$hFormat = _GDIPlus_StringFormatCreate() ; формат текста
$hFamily = _GDIPlus_FontFamilyCreate('Tahoma') ; шрифт текста
$hFont = _GDIPlus_FontCreate($hFamily, 10) ; размер шрифта

_DrawLine(10, 10, 400, 400) ; рисуем
Sleep(1500)
_EraseLine(10, 10, 400, 400) ; стираем
_DrawLine(90, 200, 600, 200)
Sleep(1500)
_EraseLine(90, 200, 600, 200)
_DrawLine(400, 10, 50, 600)
Sleep(1500)
_EraseLine(400, 10, 50, 600)
_DrawLine(100, 300, 50, 800)
Sleep(1500)
_EraseLine(100, 300, 50, 800)

Func _DrawLine($iStartX, $iStartY, $iEndX, $iEndY)
	$iLineLength = Sqrt(($iStartX - $iEndX) ^ 2 + ($iStartY - $iEndY) ^ 2) ; длина отрезка по теореме Пифагора :D
	$tLayout = _GDIPlus_RectFCreate($iStartX + 10, $iStartY + 10, 0, 0) ; координаты для надписи с длиной отрезка
	_GDIPlus_GraphicsDrawStringEx($hGraphic, Round($iLineLength, 3) & ' pixel(s)', $hFont, $tLayout, $hFormat, $hBrushYellow) ; вывод надписи с длиной отрезка
	_GDIPlus_GraphicsDrawEllipse($hGraphic, $iStartX - 2, $iStartY - 2, 4, 4, $hPenRedBold) ; точка СТАРТ
	_GDIPlus_GraphicsDrawEllipse($hGraphic, $iEndX - 2, $iEndY - 2, 4, 4, $hPenGreenBold) ; точка ФИНИШ
	_GDIPlus_GraphicsDrawLine($hGraphic, $iStartX, $iStartY, $iEndX, $iEndY, $hPenBlueThin) ; линия отрезка
EndFunc   ;==>_DrawLine

Func _EraseLine($iStartX, $iStartY, $iEndX, $iEndY)
	$iLineLength = Sqrt(($iStartX - $iEndX) ^ 2 + ($iStartY - $iEndY) ^ 2) ; длина отрезка по теореме Пифагора :D
	$tLayout = _GDIPlus_RectFCreate($iStartX + 10, $iStartY + 10, 0, 0) ; координаты для надписи с длиной отрезка
	_GDIPlus_GraphicsDrawStringEx($hGraphic, Round($iLineLength, 3) & ' pixel(s)', $hFont, $tLayout, $hFormat, $hBrushEraser) ; затираем надпись с длиной отрезка
	_GDIPlus_GraphicsDrawEllipse($hGraphic, $iStartX - 2, $iStartY - 2, 4, 4, $hEraser) ; затираем СТАРТ
	_GDIPlus_GraphicsDrawEllipse($hGraphic, $iEndX - 2, $iEndY - 2, 4, 4, $hEraser) ; затираем ФИНИШ
	_GDIPlus_GraphicsDrawLine($hGraphic, $iStartX, $iStartY, $iEndX, $iEndY, $hEraser) ; затираем отрезок
EndFunc   ;==>_EraseLine

; удаление ресурсов
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrushEraser)
_GDIPlus_BrushDispose($hBrushYellow)
_GDIPlus_PenDispose($hPenBlueThin)
_GDIPlus_PenDispose($hPenRedBold)
_GDIPlus_PenDispose($hPenGreenBold)
_GDIPlus_PenDispose($hEraser)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()

Func Terminate()
	Exit
EndFunc   ;==>Terminate
PS: если эти функции рисуют отрезки в реальном времени (берут координаты по PixelSearch), то надо добавить небольшие паузы между поисками - мерцания будут не так заметны, кроме того это снизит нагрузку на процессор.
А еще лучше сохранять старые координаты для проверки, чтобы избежать повторных рисований одних и тех же отрезков. Т.е. если изменений координат нет - ничего не рисуем, изменения есть - стираем и рисуем новый отрезок.


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

Стирание отрезка можно заменить полной очисткой области рисования, если устроит:
Код:
Func _Erase()
	_GDIPlus_GraphicsClear($hGraphic, 0xFFABABAB)
EndFunc
 
Автор
Y

yuran2

Хочу все уметь
Сообщения
38
Репутация
0
спасибо Redline :smile: вопрос решен.
 

984611

Новичок
Сообщения
1
Репутация
0
#Include <WinAPIEx.au3> Приложение без данного файла не запускается, где его можно достать?


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

Нашёл, установил, но выдаёт ошибку, причём на все Приведённые в теме скрипты
 

Redline

AutoIT Гуру
Сообщения
506
Репутация
375
984611
Допишите
#include <WindowsConstants.au3>
Похоже год назад эта константа входила в GUIConstantsEx.au3
Примеры подправлю.

Кстати, в новой версии AutoIt при стирании подписей у отрезков, остаются артефакты букв, как лечить мне неизвестно.
 
Верх