Что нового

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

Сообщения
137
Репутация
-2
Христос Воскрес!

Такая проблема - при запуске скрипт отрисовывает 3 кнопки и лейбл с картинкой. Тело основного скрипта задействуется самой верхней кнопкой под названием "Старт". Так вот пока эта кнопка не нажата, остальные кнопки работают прекрасно (и завершают работу скрипта (вторая кнопка), и меняют значок на третьей кнопке и двигают всё окно GUI за лейбл). Но если нажать кнопку "Старт" - скрипт запускается нормально, всё что нужно делает, но остальные кнопки не работают. Вроде всё делал как в примерах описано. Подскажите, что может быть не так :

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

Global $Paused

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



$hGui = GUICreate(" ",50,93, -1, -1,$WS_POPUPWINDOW)
GUISetBkColor(0x88AABB)
$Button1 = GUICtrlCreateButton("Старт", 5, 5, 40, 20)
$Button2 = GUICtrlCreateButton("Стоп", 5, 26, 40, 20)
$Button3 = GUICtrlCreateButton("-", 5, 47, 40, 20, $BS_ICON )
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 42, 0)    ;GUICtrlSetImage(-1, "oemlogo.bmp")
GUICtrlCreatePic(@ScriptDir & '\mslogo.jpg', 5, 68, 40, 20, -1, $GUI_WS_EX_PARENTDRAG )
GUISetState(@SW_SHOW)


While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg

        Case $Button1

 TrayTip ("Запуск программы", "Программа работает", 5, 1)

Sleep(1000)

Opt("WinTitleMatchMode", 2)

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

; проверка наличия окна
$hWnd = WinGetHandle(" – Torch") ; "Chrome_RenderWidgetHostHWND1"

; получаем handle элемента
$hControl = ControlGetHandle($hWnd, "","Chrome_RenderWidgetHostHWND1")

While 1

$aPix = _PixelGetArray($X, $Y, $Width, $Height, $Color, $hControl, True)

If $aPix[0][0] Then ControlClick($hWnd, "", $hControl, "left", 1, $aPix[1][0], $aPix[1][1])

WEnd

        Case $Button2

          Quit()

    Case $Button3

		    TrayTip ("Запуск программы", "Программа работает", 5, 1)
            GUICtrlSetImage($Button3, @SystemDir & '\shell32.dll', 22, 0)
       ; Case $Button4
           ; MsgBox(4096, 'Тест', 'Нажата кнопка ', 0, $hGUI); Демонстрация действия при нажатии Button 4

    EndSwitch
WEnd

; -------------------------------
; функция поиска массива пикселей
; $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 OnOff()
   ConsoleWrite("/Paused/")
    $Paused = NOT $Paused
    While $Paused
        sleep(100)
        ToolTip('Script is "Paused"',0,0)
    WEnd
    ToolTip("")
EndFunc     ;==> Paused OnOff

Func Quit()
    Exit
EndFunc   ;==> Quit
 

joiner

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

				$aPix = _PixelGetArray($X, $Y, $Width, $Height, $Color, $hControl, True)

				If $aPix[0][0] Then ControlClick($hWnd, "", $hControl, "left", 1, $aPix[1][0], $aPix[1][1])

			WEnd

вот в этом цикле скрипт и работает.а значит, не реагирует на нажатие кнопок.
 
Автор
D
Сообщения
137
Репутация
-2
Спасибо, а как мне сделать , чтоб в этом цикле скрипт так и продолжал работать и при этом реагировал на все остальные кнопки? Задача всего скрипта: поиск пикселя с заданным цветом в заданном квадрате координат и, при нахождении его, осуществление нажатия клавиши мыши, и всё это в бесконечном цикле.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
использовать WM_COMMAND
описание можно глянуть в русской справке
 
A

Alofa

Гость
Dessan сказал(а):
;) :( :blink: зачем мне сообщение
Да действительно зачем? Зачем читать справку, зачем вообще читать. Да фу, это сейчас не модно. :rofl:

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

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

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

$hGui = GUICreate(" ", 50, 93, -1, -1, $WS_POPUPWINDOW)
GUISetBkColor(0x88AABB)
$Button1 = GUICtrlCreateButton("Старт", 5, 5, 40, 20)
$Button2 = GUICtrlCreateButton("Стоп", 5, 26, 40, 20)
$Button3 = GUICtrlCreateButton("-", 5, 47, 40, 20, $BS_ICON)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 42, 0) ;GUICtrlSetImage(-1, "oemlogo.bmp")
GUICtrlCreatePic(@ScriptDir & '\mslogo.jpg', 5, 68, 40, 20, -1, $GUI_WS_EX_PARENTDRAG)

GUICtrlSetOnEvent($Button1, '_Button1')
GUICtrlSetOnEvent($Button2, 'Quit')
GUICtrlSetOnEvent($Button3, '_Button3')

GUISetState(@SW_SHOW)

While Sleep(50)
    If $fTrigger Then
        $aPix = _PixelGetArray(1190, 100, 100, 100, 0xE2A114, $hControl, True)
        If $aPix[0][0] Then ControlClick($hWnd, "", $hControl, "left", 1, $aPix[1][0], $aPix[1][1])
    EndIf
WEnd

Func _Button1()
    $hControl = ''
    Sleep(1000)
    Opt("WinTitleMatchMode", 2)
    ; проверка наличия окна
    $hWnd = WinGetHandle(" – Torch") ; "Chrome_RenderWidgetHostHWND1"
    ; получаем handle элемента
    $hControl = ControlGetHandle($hWnd, "", "Chrome_RenderWidgetHostHWND1")
    If $hControl Then
        $fTrigger = True
		TrayTip("Запуск программы", "Программа работает", 5, 1)
    Else
        MsgBox(16, 'Ошибка!', 'Окно не найдено.')
    EndIf
EndFunc   ;==>_Button1

Func _Button3()
    $fTrigger = False
    TrayTip("Запуск программы", "Программа работает", 5, 1)
    GUICtrlSetImage($Button3, @SystemDir & '\shell32.dll', 22, 0)
    ; Case $Button4
    ; MsgBox(4096, 'Тест', 'Нажата кнопка ', 0, $hGUI); Демонстрация действия при нажатии Button 4
EndFunc   ;==>_Button3


; -------------------------------
; функция поиска массива пикселей
; $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 OnOff()
    ConsoleWrite("/Paused/")
    $Paused = Not $Paused
    While $Paused
        Sleep(100)
        ToolTip('Script is "Paused"', 0, 0)
    WEnd
    ToolTip("")
EndFunc   ;==>OnOff

Func Quit()
    Exit
EndFunc   ;==>Quit


И еще, Dessan вы наверно не подозреваете о существовании "Tidy"?
Перед тем как выкладывать код, сделайте Tidy Autoit Source (это сочетание клавиш "Alt+T" или "Ctrl+T", в зависимости от используемого редактора SciTE).
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Onevent работает почти как getmsg. А с помошью wm_command можно отрабатывать сообщения даже если работает цикл другой функции. В справке есть примеры. На форуме вообще масса примеров .
Dessan, прежде чем " давить лыбу" стоит внимательно читать материал. Все работает исходя из сообщений. Вникай в работу функций, которые копируешь из чужих примеров. Программирование это не фунт изюму съесть
 
Автор
D
Сообщения
137
Репутация
-2
Вот прямо "лыбу давить"! Что за отношение такое презрительное? Здесь никто никому ничего не должен. С такими оборотами лучше б вообще ничего не писали. Для меня WS_Command как для вас QSM, SMS, ISO 9001 или вопрос выбора Регистра. В справке пишется:
WM_COMMAND Сообщение выполняется при клике на элементах окна.
, что скорее всего просто не совсем точный перевод, в своём английском варианте именно такой страницы вообще не нашёл. А пример даже близко не похож на мой скрипт. И справка не панацея, это как учиться отжиматься по книжкам. Можно измерить грудную клетку, рассчитать ширину хвата, определить крайние точки верхнего/нижнего положения, но без практики никакого результата не будет. И именно во время практики возникает большинство вопросов.
Не знал, что скриптовый язык AutoIt - это язык программирования. Прямо, программистом стал я за две недели.

После создания темы я натолкнулся на эту страницу autoit-script.ru/index.php?topic=357.0. Вроде всё просто и понятно, сделал идентично - работала только одна кнопка, хоть я свой скрипт и в функцию брал и ссылку на функцию делал...

Вон, Alofa, написал, что я эталон лени, но ему можно - человек прислал код, причём полностью рабочий.
Alofa, спасибо огромное, единственное, что я убрал - это всплывающий traytip в коже бесконечного цикла, а то вся нижняя панель экрана мигала, а traytip бесконечно вызывался.

По поводу Tidy я,действительно, слышу впервые. В папке SciTE у меня такого нет. Есть ли на форуме ссылка, которой можно доверять, чтоб скачать всё необходимое? Из справки ссылка не открылась у меня.

Кстати, к самой справке у меня тоже есть вопросы. На днях поищу тему, где пишут о возможных неточностях.
 
A

Alofa

Гость
Dessan сказал(а):
... По поводу Tidy я,действительно, слышу впервые. В папке SciTE у меня такого нет. Есть ли на форуме ссылка, которой можно доверять, чтоб скачать всё необходимое? Из справки ссылка не открылась у меня.
Установите Полную версию SciTE с ОфСайта и пользуйте (Пункт "Tidy Autoit Source" в меню "Tools" или сочетания клавиш).


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

Dessan сказал(а):
... а то вся нижняя панель экрана мигала, а traytip бесконечно вызывался.
Исправил.
 
Автор
D
Сообщения
137
Репутация
-2
Alofa сказал(а):
Установите Полную версию SciTE с ОфСайта и пользуйте (Пункт "Tidy Autoit Source" в меню "Tools" или сочетания клавиш).
Спасибо огромное, отлично работает и подгоняет весь скрипт под один шаблон

Такую мелочь как удалить одну строчку даже я в состоянии сделать, но всё равно Спасибо! :smile:

Ещё и часть скрипта оптимизировал...Браво!Спасибо!

Код:
Func _Button1()
    $hControl = ' ' ; А что эта строка делает? В чём её функциональный смысл?
    Sleep(1000)
    Opt("WinTitleMatchMode", 2)
    ; проверка наличия окна
    $hWnd = WinGetHandle(" – Torch") ; "Chrome_RenderWidgetHostHWND1"
    ; получаем handle элемента
    $hControl = ControlGetHandle($hWnd, "", "Chrome_RenderWidgetHostHWND1")
    If $hControl Then
        $fTrigger = True
        TrayTip("Запуск программы", "Программа работает", 5, 1)
    Else
        MsgBox(16, 'Ошибка!', 'Окно не найдено.')
    EndIf
EndFunc   ;==>_Button1


$hControl = ' ' ; А что эта строка делает? В чём её функциональный смысл?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Dessan [?]
Здесь никто никому ничего не должен
это ключевое определение добровольных форумов. главное помнить об этом.
о том, что я знаю или не знаю не тебе судить. но то, что ты ленишься изучить справочный материал, это видно.
по поводу "прислал рабочий код". есть тема "стол заказов", типа, сделайте все за меня. там было бы актуально. а так, никто никому ничего не должен. я подсказал куда копать. и указал, что нужно читать русскую справку (есть на форуме), там показаны примеры как работать с сообщениями

Не знал, что скриптовый язык AutoIt - это язык программирования.
исходя из того, что можно создать самостоятельную программу, то да. на форуме есть примеры достаточно эффективных программ на AutoIT
 
Автор
D
Сообщения
137
Репутация
-2
Ты ничего не понял, а потом сделал неверный вывод, прочитай мой пост ещё раз. Меня твоя жлобская формулировка возмутила.
А WM_Command может быть и решение, но не самое простое для моего уровня.

В любом случае, вопрос решён, обсуждать нам здесь нечего
 
Верх