Что нового

[Элементы GUI] Привязка таймера к лейбл и привязка счётчика кликов ControlClick к лейбл

Сообщения
137
Репутация
-2
Добрый день,

Нашёл в справке скрипт с таймером, то есть при запуске скрипта отсчитывается время его работы.Правда, не понимаю откуда берётся вызов функции Timer и как оно привязано к конкретному лейблу,вот сам код из справки:

Код:
; *** Окно демонстрации таймера
#include <GUIConstantsEx.au3>
#include <Date.au3>

Opt("TrayIconDebug", 1)

Global $timer, $Secs, $Mins, $Hour, $Time

_Main()

Func _Main()
	;Создание GUI
	GUICreate("Таймер", 120, 50)
	GUICtrlCreateLabel("00:00:00", 10, 10)
	GUISetState()
	;Старт таймера
	$timer = TimerInit()
	AdlibRegister("Timer", 50)

	While 1
		;FileWriteLine("debug.log",@min & ":" & @sec & " ==> до")
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				Exit
		EndSwitch
		;FileWriteLine("debug.log",@min & ":" & @sec & " ==> после")
	WEnd
EndFunc   ;==>_Main

Func Timer()
	_TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
	Local $sTime = $Time  ; сохраняет текущее время для проверки и избегания мерцания таймера...
	$Time = StringFormat("%02i:%02i:%02i", $Hour, $Mins, $Secs)
	If $sTime <> $Time Then ControlSetText("Таймер", "", "Static1", $Time)
EndFunc   ;==>Timer

А также скрипт с подсчётом количества кликов, сделанных мышкой,правда, не оптимизированный какой-то,хотя, может я и ошибаюсь...вообщем, нашёл его на английском форуме, но не знаю как оптимизировать его и привязать к моему ControlClick:
Код:
#include <WinAPIGdi.au3>
#include <Misc.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>

Global $clicks
$clicks=1

$Form1 = GUICreate("Form1", 251, 134, -1, -1)
$Label1 = GUICtrlCreateLabel("Number = ", 24, 8, 196, 25)
$Button1 = GUICtrlCreateButton("Active", 24, 56, 201, 25, 0)
GUISetState(@SW_SHOW)

While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
_Func1()
EndSwitch
WEnd


Func _Func1()
While 1
If _IsPressed(01) Then
GUICtrlSetData($Label1, "Number = " & $clicks)
EndIf
if _IsPressed(01) Then
$clicks += 1
While _IsPressed(01)
Sleep(1)
WEnd
EndIf
WEnd
EndFunc

Как мне теперь эту радость правильно привязать к моим лейблам?

Код:
#include <WinAPIGdi.au3>
#include <Misc.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>

Global $Paused, $hGui, $Button1, $Button2, $Button3, $hWnd, $hControl, $fTrigger = False
Opt("GUIOnEventMode", 1) ; Включает режим OnEvent

$hGui = GUICreate(" ", 50, 93, -1, -1, $WS_POPUPWINDOW)
GUISetBkColor(0x88AABB)

$Button1 = GUICtrlCreateButton("Start", 5, 5, 40, 20)
GUICtrlSetOnEvent(-1, '_Button1')

$Button2 = GUICtrlCreateButton("Hide", 5, 26, 40, 20)
GUICtrlSetOnEvent(-1, '_Button2')

$Button3 = GUICtrlCreateButton("  	", 5, 47, 40, 20 )
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 42, 0)  
GUICtrlSetOnEvent($Button3, '_Button3')

GUICtrlCreatePic(@ScriptDir & '\msoobe.jpg', 5, 68, 40, 20, -1, $GUI_WS_EX_PARENTDRAG)

GUICtrlCreateLabel('00:00:00', 55, 9, 110, 20); здесь я хочу видеть время работы скрипта, чтоб оно запускалось при нажатии первой кнопки Start вместе с основной функцией
GUICtrlCreateLabel('без текста, статичная рамка', 50, 7, 110, 17, $SS_ETCHEDFRAME)
GUICtrlCreateLabel('Clicks:', 50, 30, 80, 17, $SS_LEFT)
;GUICtrlSetBkColor(-1, 0xfdffae)
GUICtrlCreateLabel('123456', 50, 50, 50, 21, -1, $WS_EX_CLIENTEDGE); а здесь видеть количество кликов, которые сделал скрипт(цифры 123456 - это я смотрел как выглядит 6-ти значное число на экране)
GUICtrlCreateLabel('Gold:', 110, 30, 80, 17, $SS_LEFT)
GUICtrlCreateLabel('123456', 110, 50, 50, 21, -1, $WS_EX_CLIENTEDGE)

GUISetState(@SW_SHOW)
; не понимаю как таймер этот привязать к тому лейблу
$timer = TimerInit()
	AdlibRegister("Timer", 50)

	Func Timer()
    _TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
    Local $sTime = $Time  ; сохраняет текущее время для проверки и избегания мерцания таймера...
    $Time = StringFormat("%02i:%02i:%02i", $Hour, $Mins, $Secs)
    If $sTime <> $Time Then ControlSetText("Таймер", "", "Static1", $Time)
EndFunc   ;==>Timer

While 1
	
	;здесь сам скрипт в цикле

		If $aPix[0][0] And ConsoleWrite('+1') Then ControlClick($hWnd, "", $hControl, "left", 1, $aPix[1][0], $aPix[1][1] + 55)
        ;вот этот клик подсчитать бы
	EndIf

	Sleep(3000)

WEnd
;-------------------------------
Func _Button1() ; основное тело скрипта
    
     GUICtrlSetData($Button1, 'Run')
            TrayTip("Запуск программы", "Программа работает", 5, 1)
    
EndFunc   ;==>_Button1

И ещё одно - как сделать так, чтоб моя GUI сворачивалась в панель задач (там где часы) и её потом снова можно было восстановить:
Код:
Func _Button4()

	      WinSetState($hGui, "", @SW_HIDE)

EndFunc   ;==>_Button4
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Прежде всего обеспечьте работу собственного скрипта, чтобы можно было его запустить и посмотреть, где там ваши "лейблы", и как скрипт работает. Не уверен, что кому-то интересно ковыряться в обрывках чужого нерабочего кода. А примеры... Примеры нужны, чтобы понять принцип, а не чтобы их встраивать.

чтоб моя GUI сворачивалась в панель задач (там где часы)
Обсуждалось не один раз. Пользуйтесь поиском.
 
A

Alofa

Гость
OffTopic:
Dessan однажды наступит момент, когда вам просто перестанут отвечать в ваших темах - это будет закономерным следствием вашего нежелания хоть чего-то попытаться понять самому.

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

Global $hGui, $Button1, $Button2, $Button3, $fTrigger = False ; "$fTrigger" здесь является индикатором включения таймера [смотри функцию "_Button1()"]
Local $iTimerLabel, $iCounterLabel, $iCounter, $iHour = 0, $iMin = 0, $iSec = 0

Opt('GUIOnEventMode', 1) ; Включает режим OnEvent
Opt("TrayMenuMode", 1 + 2) ; Не отображать в трее пункты меню по умолчанию (Script Paused/Exit) и не отмечать галочками при выборе.
Opt("TrayOnEventMode", 1) ; Включает режим TrayOnEventMode.

$hGui = GUICreate('', 200, 93, -1, -1, $WS_POPUPWINDOW)
GUISetBkColor(0x88AABB)

$Button1 = GUICtrlCreateButton('Start', 5, 5, 40, 20)
$Button2 = GUICtrlCreateButton('Hide', 5, 26, 40, 20)
$Button3 = GUICtrlCreateButton(' ', 5, 47, 40, 20)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 42, 0)

GUICtrlCreatePic(@ScriptDir & '\msoobe.jpg', 5, 68, 40, 20, -1, $GUI_WS_EX_PARENTDRAG)

$iTimerLabel = GUICtrlCreateLabel('00:00:00', 55, 9, 107, 15)
GUICtrlCreateLabel('без текста, статичная рамка', 50, 7, 110, 17, $SS_ETCHEDFRAME)
GUICtrlCreateLabel('Clicks:', 50, 30, 80, 17, $SS_LEFT)
$iCounterLabel = GUICtrlCreateLabel('000000', 50, 50, 50, 21, -1, $WS_EX_CLIENTEDGE)
GUICtrlCreateLabel('000000', 110, 50, 50, 21, -1, $WS_EX_CLIENTEDGE)

TrayItemSetOnEvent(TrayCreateItem('Свернуть/Развернуть'), '_Button2')
TrayItemSetOnEvent(TrayCreateItem('Выход'), '_Exit')
GUICtrlSetOnEvent($Button1, '_Button1')
GUICtrlSetOnEvent($Button2, '_Button2')
GUICtrlSetOnEvent($Button3, '_Button3')

GUISetState(@SW_SHOW)

While 1
	;здесь сам скрипт в цикле
;~ 	If $aPix[0][0] And ConsoleWrite('+1') Then
;~ 		ControlClick($hWnd, '', $hControl, 'left', 1, $aPix[1][0], $aPix[1][1] + 55)
		$iCounter += 1 ; Счетчик кликов
		GUICtrlSetData($iCounterLabel, StringFormat('%06d', $iCounter))
;~ 	EndIf
	Sleep(300)
WEnd

; --------------------------------------------------------------------------------
Func _UpdateTimerLabel()
	$iSec += 1
	If $iSec = 60 Then
		$iSec = 0
		$iMin += 1
	EndIf
	If $iMin = 60 Then
		$iMin = 0
		$iHour += 1
	EndIf
	GUICtrlSetData($iTimerLabel, StringFormat('%02d:%02d:%02d', $iHour, $iMin, $iSec))
EndFunc   ;==>_UpdateTimerLabel

Func _Button1()
	If $fTrigger Then
		GUICtrlSetData($Button1, 'Run')
		AdlibUnRegister('_UpdateTimerLabel')
	Else
		GUICtrlSetData($Button1, 'STOP')
		TrayTip('Запуск программы', 'Программа работает', 5, 1)
		AdlibRegister('_UpdateTimerLabel', 1000) ; ИЛИ смотри функцию '_Timer_SetTimer()'
	EndIf
	$fTrigger = Not $fTrigger
EndFunc   ;==>_Button1

Func _Button2()
	Local $iState = WinGetState($hGui)
	; Если окно отображается, то...
	(BitAND($iState, 2)) ? GUISetState(@SW_HIDE) : GUISetState(@SW_SHOW)
EndFunc   ;==>_Button2

Func _Button3()
EndFunc   ;==>_Button3

Func _Exit()
	Exit
EndFunc   ;==>_Exit
 
Автор
D
Сообщения
137
Репутация
-2
InnI

Вы правы: видимо, я почему-то решил,что стал гуру autoit и смогу отредактировать свой скрипт прямо в редакторе сайта без ущерба функциональности. Однако, после поста Alofa,у меня уже появились совсем другие вопросы и приведение кода к рабочему виду пока что не актуально. Спасибо за участие в моём autoit образовании и внимание к вопросу.

Alofa

Я сначала хотел начать спорить, но не стану. Хотябы, потому что данный форум держится на горстке фанатов, которые понимают, как это работает и что нужно,чтоб это работало. В моём понимании,вы относитесь к этим людям. Это первое. Второе, знаете, если человеку долго говорить, что он бездарность, лентяй и вообще идиот - он может смириться и перестать заниматься вещами за которые его так клеймят. Зачем вы сознательно вешаете ярлыки мне на ник? Вы же видите,что я и на форумах поискал что-то похожее и в справку заглянул. А как я должен иначе заниматься пониманием autoit если я не буду задавать вопросы?И как я буду знать, что изучать если я не знаю как называется та функция, которая мне нужна?Или я должен догадаться, что функция, которая отвечает за трей называется TrayMenuMode, а к ней нужно прописать TrayItemSetOnEvent.И сразу,мало того, что про TrayItemSetOnEvent я узнал из вашего скрипта, так вы ещё и даёте его в виде
Код:
TrayItemSetOnEvent(TrayCreateItem('Выход'), '_Exit')
, хотя в той же справке эта функция в виде
Код:
TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
. Вы это узнали явно не из справки - возможно кто-то подсказал, а может где-то подсмотрели. Вы на этом форуме каждый день и, уверен, ваша сфера деятельности связана с программированием или сетями+вы читаете все посты, что позволяет каждый день повышать своё самообразование и изучать новые функции. К сожалению, я не связан с программированием и у меня нет возможности читать здесь каждый пост от таких же как я,которые приходят с единичной проблемой, находят решение и остальное их мало волнует. У меня также нет вашей возможности вникать в их проблемы и пробовать их решить, проверять код и т.д. Я захожу на форум раз в месяц, например. Писать скрипты каждый день у меня тоже нет никакой необходимости, поэтому многое из того, что прочитано было, забывается. Более того,в данном моём случае, мне даже легче учиться на своих кодах и именно своих ошибках.Я проникся интересом к скриптам,хотя оно мне в моей деятельности и не нужно вообщем-то. Даже этот скрипт,который стал предметом моего поста, кроме как рабочего познавательного примера, мне никакой пользы не принесёт. Он для игры, в которую я даже не буду играть, потому что у меня нет на это времени. Но это не значит, что я тут сижу и морочу людям голову, мне просто интересен сам процесс работы скриптов, своего рода обман,подложность присутствия оператора. Я уже целый роман тут наваял непонятно зачем...Короче говоря,тот код, который вы мне прислали - моё второе знакомство с autoit, поэтому говорить о моём нежелании что-то изучить и понять здесь просто неуместно. Я хочу изучить, понять и радуюсь как школьник, когда всё работает.
Касательно же вашего скрипта -
Код:
Func _Button2()
    Local $iState = WinGetState($hGui)
    ; Если окно отображается, то...
 (BitAND($iState, 2)) ? GUISetState(@SW_HIDE) : GUISetState(@SW_SHOW) ; выдаёт error: Statement cannot be just an expression
EndFunc   ;==>_Button2


Да, и спасибо за код, узнал для себя много нового

А счётчик кликов что-то считает, но точно не клики
 
A

Alofa

Гость
Dessan сказал(а):
... Вы на этом форуме каждый день и, уверен, ваша сфера деятельности связана с программированием или сетями...
Неа, лично я днем гайки кручу. На перекурах захожу сюда с гуглофона (иногда).

Dessan сказал(а):
Касательно же вашего скрипта...
Это сокращенная запись следующего выражения:
Код:
If BitAND($iState, 2) Then
   GUISetState(@SW_HIDE)
Else 
   GUISetState(@SW_SHOW)
Endif

*Подробнее*.
Можете еще попробовать так (не проверял):
Код:
Func _Button2()
    Local $Flag, $iState = WinGetState($hGui)
    ; Если окно отображается, то...
   $Flag = (BitAND($iState, 2) ? @SW_HIDE : @SW_SHOW)
   GUISetState($Flag)
EndFunc

Dessan сказал(а):
... А счётчик кликов что-то считает, но точно не клики
А что считать-то, если считать-то нечего?
Разкомментируйте строки.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Alofa
Подобная конструкция
Код:
(BitAND($iState, 2)) ? GUISetState(@SW_HIDE) : GUISetState(@SW_SHOW)
работает в AutoIt, но не нравится Au3Check: ticket #3200. Поэтому и появляется "Statement cannot be just an expression".
 
A

Alofa

Гость

StarEdik

Новичок
Сообщения
365
Репутация
4
Посмотрите примеры
От madmasles
http://autoit-script.ru/index.php?topic=6030.msg42793#msg42793

и от InnI
http://autoit-script.ru/index.php?topic=17686.msg107600#msg107600

простой скрипт составленный из этих же примеров
Код:
#include <Misc.au3>
#include <TrayConstants.au3>
#include <GUIConstantsEx.au3>
#include <Date.au3>
#include <Misc.au3>
HotKeySet('{Esc}', '_Exit'); Выход из программы по кнопке Esc

Opt("TrayMenuMode", 1)

Global $timer, $Secs, $Mins, $Hour, $Time
$Form1 = GUICreate("Таймер - Выход ESC", 220, 70)
GUICtrlCreateLabel("00:00:00", 10, 10)
$Label1 = GUICtrlCreateLabel("ЛКМ - количество нажатий: ", 10, 30)
$Label2 = GUICtrlCreateLabel("0", 170, 30)
GUISetState(@SW_HIDE)
WinSetOnTop($Form1, '', 1) ;  "Always On Top"
$timer = TimerInit()
AdlibRegister("Timer", 1000)

$iCount = 0
$iCountOld = 0

While 1
	If _IsPressed(01) Then
		While _IsPressed(01)
			Sleep(10)
		WEnd
		$iCount += 1
	EndIf
	Sleep(10)
	If $iCountOld <> $iCount Then
		$iCountOld = $iCount
		; Варианты отображения
		;TrayTip('Контроль кликов', @CRLF & 'Левая Кнопка Мыши' & @CRLF & 'количество нажатий: ' & $iCountOld, 5, 17)
		ToolTip(@CRLF & '  Левая Кнопка Мыши' & @CRLF & '  количество нажатий: ' & $iCountOld & '  ', 10, 10)

		GUICtrlSetData($Label2, $iCountOld)
	EndIf
	Switch TrayGetMsg()
		Case $TRAY_EVENT_PRIMARYDOWN
			GUISetState(@SW_SHOWNORMAL)
	EndSwitch
	Switch GUIGetMsg()
		Case $GUI_EVENT_MINIMIZE
			GUISetState(@SW_HIDE)
	EndSwitch
WEnd

Func Timer()
	_TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
	Local $sTime = $Time
	$Time = StringFormat("%02i:%02i:%02i", $Hour, $Mins, $Secs)
	If $sTime <> $Time Then ControlSetText("Таймер", "", "Static1", $Time)
EndFunc   ;==>Timer


Func _Exit()
	Exit
EndFunc   ;==>_Exit
 
Автор
D
Сообщения
137
Репутация
-2
Alofa сказал(а):
Это сокращенная запись следующего выражения:
Код:
Func _Button2()
    Local $iState = WinGetState($hGui)
If BitAND($iState, 2) Then
   GUISetState(@SW_HIDE)
Else 
   GUISetState(@SW_SHOW)
Endif
EndFunc

Вот так мне более понятно на данном этапе и работает прекрасно
Можете еще попробовать так (не проверял):
Код:
Func _Button2()
    Local $Flag, $iState = WinGetState($hGui)
    ; Если окно отображается, то...
   $Flag = (BitAND($iState, 2) ? @SW_HIDE : @SW_SHOW)
   GUISetState($Flag)
EndFunc

И так работает, но я не понимаю механику этого процесса, а в развёрнутом виде я представляю себе что-то типа этого:
Код:
Func _Button2()
    Local $Flag
	$iState = WinGetState($hGui)
    ; Если окно отображается, то...
  If $Flag = BitAND($iState, 2) Then
   GUISetState(@SW_HIDE)
Else
   GUISetState(@SW_SHOW)
Endif
   GUISetState($Flag)
EndFunc
И это моё "что-то" сворачивает, но не разворачивает
Dessan сказал(а):
... А счётчик кликов что-то считает, но точно не клики
А считать начинает сразу после прорисовки GUI, я даже на старт не нажимаю


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

StarEdik сказал(а):
Посмотрите примеры
От madmasles
http://autoit-script.ru/index.php?topic=6030.msg42793#msg42793

и от InnI
http://autoit-script.ru/index.php?topic=17686.msg107600#msg107600

простой скрипт составленный из этих же примеров
Код:
#include <Misc.au3>
#include <TrayConstants.au3>
#include <GUIConstantsEx.au3>
#include <Date.au3>
#include <Misc.au3>
HotKeySet('{Esc}', '_Exit'); Выход из программы по кнопке Esc

Opt("TrayMenuMode", 1)

Global $timer, $Secs, $Mins, $Hour, $Time
$Form1 = GUICreate("Таймер - Выход ESC", 220, 70)
GUICtrlCreateLabel("00:00:00", 10, 10)
$Label1 = GUICtrlCreateLabel("ЛКМ - количество нажатий: ", 10, 30)
$Label2 = GUICtrlCreateLabel("0", 170, 30)
GUISetState(@SW_HIDE)
WinSetOnTop($Form1, '', 1) ;  "Always On Top"
$timer = TimerInit()
AdlibRegister("Timer", 1000)

$iCount = 0
$iCountOld = 0

While 1
	If _IsPressed(01) Then
		While _IsPressed(01)
			Sleep(10)
		WEnd
		$iCount += 1
	EndIf
	Sleep(10)
	If $iCountOld <> $iCount Then
		$iCountOld = $iCount
		; Варианты отображения
		;TrayTip('Контроль кликов', @CRLF & 'Левая Кнопка Мыши' & @CRLF & 'количество нажатий: ' & $iCountOld, 5, 17)
		ToolTip(@CRLF & '  Левая Кнопка Мыши' & @CRLF & '  количество нажатий: ' & $iCountOld & '  ', 10, 10)

		GUICtrlSetData($Label2, $iCountOld)
	EndIf
	Switch TrayGetMsg()
		Case $TRAY_EVENT_PRIMARYDOWN
			GUISetState(@SW_SHOWNORMAL)
	EndSwitch
	Switch GUIGetMsg()
		Case $GUI_EVENT_MINIMIZE
			GUISetState(@SW_HIDE)
	EndSwitch
WEnd

Func Timer()
	_TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
	Local $sTime = $Time
	$Time = StringFormat("%02i:%02i:%02i", $Hour, $Mins, $Secs)
	If $sTime <> $Time Then ControlSetText("Таймер", "", "Static1", $Time)
EndFunc   ;==>Timer


Func _Exit()
	Exit
EndFunc   ;==>_Exit
StarEdik, спасибо огромное!Где вы вчера были...
 
Автор
D
Сообщения
137
Репутация
-2
Мне нужна ваша помощь. Задал я нужный мне цвет пикселя и скрипт ищет все пиксели с этим цветом в указанной области экрана и исправно на них кликает. После клика, пиксель этот пропадает и появляется через 5 минут снова на том же месте (если область экрана не двигать). Каждый свой клик помечает текстом "+1" и записывает в консоль с координатами своего клика. Даже считает количество сделанных кликов и записывает их в лейбл (добился этого случайным образом удаляя/приписывая/изменяя несколько готовых скриптов с счётчиком кликов из справки и из тем на форуме,правда,так и не понял всю логику процесса). Проблема в том, что когда он найдёт и покликает на все пиксели с нужным мне цветом, в консоль клики записываться перестают (как и должно быть), а в лейбле всё равно идёт дальнейший отсчёт кликов с постоянным интервалом...Что оно там отсчитывает - понятия не имею, где-то у меня ошибка и я не могу её найти никак.

Чтоб наглядно понять как именно он кликает,я решил упростить задачу, открыл Paint и поставил произвольно 3 чёрные точки (цвет 0x000000). Думал скрипт мне найдёт их и кликнет на их месте другим цветом,а я посмотрю как именно это происходит. Вместо этого, он находит крайнюю левую точку (или крайнюю правую), кликает на неё, а остальные точки искать отказывается.Если же, не останавливая его работы, эту точку закрасить иным цветом, скрипт сразу берёт крайнюю следующую чёрную точку и также на ней зацикливается. Вообщем, вообще завёл меня в тупик. Вот скрипт с поиском точек в Paint и кликом на них (для проверки нужно задать Advanced (Class) и поставить несколько точек в Paint), посмотрите, пожалуйста:

Код:
#include <WinAPIGdi.au3>
#include <Misc.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <Date.au3>

Global $Paused, $hGui, $Button1, $Button2, $Button3, $Button4, $hWnd, $hControl, $fTrigger
Local $iTimerLabel, $iClicksLabel, $iCounter = 0, $iDay = 0, $iHour = 0, $iMin = 0, $iSec = 0, $iCount = 0, $iClick = 0, $iCountOld = 0

Opt("GUIOnEventMode", 1) ; Включает режим OnEvent
Opt("TrayMenuMode", 1 + 2) ; Не отображать в трее пункты меню по умолчанию (Script Paused/Exit) и не отмечать галочками при выборе.
Opt("TrayOnEventMode", 1) ; Включает режим TrayOnEventMode 


HotKeySet('{Esc}', '_Quit') ; полный выход из скрипта по Esc
HotKeySet('{Pause}', '_OnOff') ; включение-отключение через Pause

$hGui = GUICreate(" ", 170, 93, -1, -1, $WS_POPUPWINDOW)
GUISetBkColor(0x88AABB)

$Button1 = GUICtrlCreateButton("Start", 5, 5, 40, 20)
GUICtrlSetOnEvent(-1, '_Button1')

$Button2 = GUICtrlCreateButton("Hide", 5, 26, 40, 20)
GUICtrlSetOnEvent(-1, '_Button2')

$Button3 = GUICtrlCreateButton("	", 5, 47, 40, 20)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 42, 0)
GUICtrlSetOnEvent($Button3, '_Button3')

$Button4 = GUICtrlCreateButton("Minimize Window", 50, 70, 110, 20)
GUICtrlSetOnEvent(-1, '_Button4')

GUICtrlCreatePic(@ScriptDir & '\msoobe.jpg', 5, 68, 40, 20, -1, $GUI_WS_EX_PARENTDRAG)



$iTimerLabel = GUICtrlCreateLabel('0:00:00:00', 55, 9, 110, 20)
GUICtrlCreateLabel('без текста, статичная рамка', 50, 7, 110, 17, $SS_ETCHEDFRAME)
GUICtrlCreateLabel('Clicks:', 50, 30, 80, 17, $SS_LEFT)

$iClicksLabel = GUICtrlCreateLabel('0', 50, 50, 50, 21, -1, $WS_EX_CLIENTEDGE)
GUICtrlCreateLabel('Gold:', 110, 30, 80, 17, $SS_LEFT)
GUICtrlCreateLabel('123456', 110, 50, 50, 21, -1, $WS_EX_CLIENTEDGE)


TrayItemSetOnEvent(TrayCreateItem('Information'), '_Info')
TrayItemSetOnEvent(TrayCreateItem('Restore Window'), '_Restore')

TrayCreateItem("")

TrayItemSetOnEvent(TrayCreateItem('Выход'), '_Quit')

TraySetClick(64)

GUISetState(@SW_SHOW)



$X = 100
$Y = 100
; ширина и высота области поиска
$Width = 1200
$Height = 750
; иcкомый цвет пикселя
$Color = 0x000000

;Local $hWnd = WinGetHandle("Безымянный - Paint")
;$hControl = ControlGetHandle($hWnd, "", "[CLASS:Afx:00000000FFA10000:8; INSTANCE:1]")



While 1

	If $fTrigger Then
		Sleep(3000)
		Opt("WinTitleMatchMode", 2)
		Local $hWnd = WinGetHandle("Безымянный - Paint")
		If @error Then Exit MsgBox(0, "Ошибка", "Не найдено окно программы")
		$hControl = ControlGetHandle($hWnd, "", "[CLASS:Afx:00000000FFA10000:8; INSTANCE:1]")
		If Not $hControl Then Exit MsgBox(4096, 'Сообщение', 'Окно закрыто или свёрнуто!')
		Sleep(400)
		; ищем первый подходящий пиксель
		$aPix = _PixelGetArray($X, $Y, $Width, $Height, $Color, $hControl, True)
		; кликаем по координ

		If $aPix[0][0] And ConsoleWrite("+1" & ':' & $aPix[1][0] & 'x' & $aPix[1][1] & '; ') Then $iClick = ControlClick($hWnd, "", $hControl, "left", 1, $aPix[1][0], $aPix[1][1] + 55)

	EndIf

	If $iClick Then

		$iCount += 1
		; Else
		;TrayTip ('', '$iCount += 1 в трее =' & $iCount, 5, 17)

	EndIf
	Sleep(10)
	If $iCountOld < $iCount Then
		$iCountOld = $iCount

		GUICtrlSetData($iClicksLabel, StringFormat('%01d', $iCountOld))
	EndIf

WEnd


;-------------------------------
Func _Button1()

	$fTrigger = Not $fTrigger
	If $fTrigger Then
		GUICtrlSetData($Button1, 'Run')
		TrayTip("Запуск программы", "Программа работает", 5, 1)
		AdlibRegister('_UpdateTimerLabel', 1000)


	Else
		GUICtrlSetData($Button1, 'Pause')
		TrayTip('Запуск программы', 'Программа работает', 5, 1)
		AdlibUnRegister('_UpdateTimerLabel')
	EndIf


	Sleep(500)


EndFunc   ;==>_Button1

;-------------------------------
Func _Button2()

	TrayTip("Прячем программу", "Замена иконки", 5, 1)
	WinMove($hWnd, "", 1365, 10, 1190, 640, 20)
	GUICtrlSetData($Button2, 'Hidden')
	GUICtrlSetImage($Button3, @SystemDir & '\shell32.dll', 239, 0)
	GUICtrlSetData($Button3, 'Show')
EndFunc   ;==>_Button2

;-------------------------------
Func _Button3()

	TrayTip("Back the Window", "Замена иконки", 5, 1)
	WinMove($hWnd, "", 10, 10, 1190, 640, 20)

	GUICtrlSetData($Button2, 'Hide')
	GUICtrlSetData($Button3, 'Hi')

	GUICtrlSetImage($Button3, @SystemDir & '\shell32.dll', 167, 0)


EndFunc   ;==>_Button3

;-------------------------------
Func _Button4()

	TrayTip("Minimized", "	", 5, 1)

	GUISetState(@SW_HIDE)


EndFunc   ;==>_Button4


; -------------------------------
; функция поиска массива пикселей
; $i_X, $i_Y - координаты левого верхнего угла области поиска
; $i_Width, $i_Height - ширина и высота области поиска
; $i_Color - искомый цвет пикселя
; $h_Wnd - дескриптор окна или элемента, относительно которого осуществляется поиск (0 - на всём экране)
; $f_FirstOnly - если True, то завершает поиск после нахождения первого пикселя
Func _PixelGetArray($i_X, $i_Y, $i_Width, $i_Height, $i_Color, $h_Wnd, $f_FirstOnly = True)
	Local $i_Size = $i_Width * $i_Height, $a_Pixels[$i_Size + 1][2] = [[0]], $h_DC, $h_MemDC, $h_Bitmap, $t_Bits, $i_Index
	$h_DC = _WinAPI_GetDC($h_Wnd)
	$h_MemDC = _WinAPI_CreateCompatibleDC($h_DC)
	$h_Bitmap = _WinAPI_CreateCompatibleBitmap($h_DC, $i_Width, $i_Height)
	_WinAPI_SelectObject($h_MemDC, $h_Bitmap)
	_WinAPI_BitBlt($h_MemDC, 0, 0, $i_Width, $i_Height, $h_DC, $i_X, $i_Y, 0x00CC0020) ; $SRCCOPY
	_WinAPI_DeleteDC($h_MemDC)
	_WinAPI_ReleaseDC($h_Wnd, $h_DC)
	$t_Bits = DllStructCreate('dword[' & $i_Size & ']')
	$p_Bits = DllStructGetPtr($t_Bits)
	_WinAPI_GetBitmapBits($h_Bitmap, 4 * $i_Size, $p_Bits)
	_WinAPI_DeleteObject($h_Bitmap)
	For $i = 0 To $i_Height - 1
		For $j = 0 To $i_Width - 1
			$i_Index += 1
			If BitAND(DllStructGetData($t_Bits, 1, $i_Index), 0x00FFFFFF) = $i_Color Then
				$a_Pixels[0][0] += 1
				$a_Pixels[$a_Pixels[0][0]][0] = $j + $i_X
				$a_Pixels[$a_Pixels[0][0]][1] = $i + $i_Y
				If $f_FirstOnly Then ExitLoop 2
			EndIf
		Next
	Next
	ReDim $a_Pixels[$a_Pixels[0][0] + 1][2]
	Return $a_Pixels
EndFunc   ;==>_PixelGetArray

Func _UpdateTimerLabel()
	$iSec += 1
	If $iSec = 60 Then
		$iSec = 0
		$iMin += 1
	EndIf
	If $iMin = 60 Then
		$iMin = 0
		$iHour += 1
	EndIf
	If $iHour = 24 Then
		$iHour = 0
		$iDay += 1
	EndIf
	GUICtrlSetData($iTimerLabel, StringFormat('%01d:%02d:%02d:%02d', $iDay, $iHour, $iMin, $iSec))
EndFunc   ;==>_UpdateTimerLabel

Func _OnOff()
	ConsoleWrite("/Paused/")
	$Paused = Not $Paused

	While $Paused

		Sleep(100)
		ToolTip('Script is "Paused"', 0, 0)

	WEnd
	ToolTip('')
EndFunc   ;==>_OnOff

Func _Restore()
	GUISetState(@SW_SHOW)
EndFunc   ;==>_Restore

Func _Info()
	MsgBox(4096, "Info", "Some Text")
EndFunc   ;==>_Info

Func _Quit()
	Exit
EndFunc   ;==>_Quit
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Dessan
остальные точки искать отказывается
Там же по-русски указано
Код:
; $f_FirstOnly - если True, то завершает поиск после нахождения первого пикселя

Код:
...
While 1
    If $fTrigger Then
        Sleep(3000)
        Opt("WinTitleMatchMode", 2)
        Local $hWnd = WinGetHandle("- Paint")
        If @error Then Exit MsgBox(0, "Ошибка", "Не найдено окно программы")
        $hControl = ControlGetHandle($hWnd, "", "[REGEXPCLASS:Afx:; INSTANCE:1]")
        If Not $hControl Then Exit MsgBox(4096, 'Сообщение', 'Окно закрыто или свёрнуто!')
        Sleep(400)
        ; ищем все пиксели
        $aPix = _PixelGetArray($X, $Y, $Width, $Height, $Color, $hControl, False)
        ; кликаем по координ
        For $i = 1 To $aPix[0][0]
            ConsoleWrite("+1" & ':' & $aPix[$i][0] & 'x' & $aPix[$i][1] & '; ')
            $iClick += ControlClick($hWnd, "", $hControl, "left", 1, $aPix[$i][0], $aPix[$i][1])
            GUICtrlSetData($iClicksLabel, StringFormat('%01d', $iClick))
        Next
    EndIf
WEnd
...
 
Автор
D
Сообщения
137
Репутация
-2
В том то и дело, что в игре этот же скрипт с параметром "True" отрабатывает клики на все пиксели, в Paint зацикливается на одном конкретном пикселе. Этот параметр я уже менял True/False и в самом условии скрипта и в самой функции. Хотя, я больше чем уверен, что именно здесь моя ошибка и я её сам найду. Меня больше интересует как правильно сделать привязку кликов к счётчику, потому что я не понимаю, почему он продолжает считать, когда на экране уже нет иконок для кликов по ним. Также я запускал вашу же функцию, которая находит координаты всех пикселей указанного цвета в указанной области экрана и проверял нет ли чего-то дополнительного на что можно кликнуть скрипту и ничего лишнего не нашёл. Причём в консоль он клики и координаты записывает правильно, а вот счётчик подводит сильно.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
Dessan
в игре этот же скрипт с параметром "True" отрабатывает клики на все пиксели
Единственное объяснение этому, это то, что при каждом вызове функции предыдущий пиксель уже другого цвета.

почему он продолжает считать, когда на экране уже нет иконок для кликов по ним
Не понимаю, про какие иконки вы говорите. Но применительно к Paint - ситуация может быть такая. Если вы запрашиваете область поиска больше, чем размер элемента, то всё, что выходит за пределы, будет чёрного цвета и скрипт будет этот чёрный находить и кликать. Но клики, естественно, будут за пределами контрола.

в консоль он клики и координаты записывает правильно, а вот счётчик подводит сильно
Потому что в вашем скрипте $iClick не обнуляется. Достаточно одного клика, чтобы условие
Код:
If $iClick Then
всегда выполнялось (любое число, отличное от нуля, это True). Следовательно, условие
Код:
If $iCountOld < $iCount Then
тоже будет выполнено и Label будет обновлён.
 
Автор
D
Сообщения
137
Репутация
-2
Прежде всего спасибо большое - работает :thanks:. Единственное что - изначально нажимало на все необходимые пиксели сразу (а их 17 пока что), и, видимо, с такой скоростью, что пока эффект от нажатия прорисовывался, то скрипт успевал нажать на каждый пиксель 2-3 раза. Я поставил Sleep (2000) перед $iClick и всё стало как нужно. Осталось понять как работают эти массивы. Причём, если в теории, всё не так сложно выглядит, на практике я не понимаю что значит For $i = 1 To $aPix[0][0], если $aPix[0][0] = 1, то есть от 1 до 1 :stars:
Единственное объяснение этому, это то, что при каждом вызове функции предыдущий пиксель уже другого цвета.
Тут всё ещё проще-в игре после нахождения цвета пикселя и нажатия на него...он исчезает, то есть, после вызова функции, предыдущий пиксель просто не существует. В Paint же всё статично)
 
Верх