Author Topic: Альтернатива привязке - работа с несколькими окнами, решение черного окна, и тп.  (Read 51622 times)

0 Members and 2 Guests are viewing this topic.

m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
Большое спасибо!

Видимо я чего-то не понимаю.

Code: [Select]
#name "New Script"
WAIT(1)

print("Hello:-) world! Проверка: связи*")

$A_hwnd = wndfind("Блокнот") // получаем HWND окна Блокнота

//A_KEYSTRING
SUB(A_KEYSTRING, $A_str, $A_delay, $A_hwnd)
   $A_kbl=GETKBLAYOUT($A_hwnd)
   IF($A_kbl ! 1049)
      setkblayout($A_hwnd, 1049)
   END_IF   
   FOR($A_nstr=1,$A_nstr<STRLEN ($A_str)+1)
      $A_l=STRCUT ($A_str, $A_nstr, 1)
      IF(ARRSIZE ($A_keys_arr) = 0)
         TFREADARR ("keys.txt", $A_keys_arr)
      END_IF   
      FOR($A_a=1,$A_a<ARRSIZE ($A_keys_arr),2)
         IF($A_keys_arr[$A_a] = $A_l)
            $A_key = $A_keys_arr[$A_a-1]
            IF($A_key = 46)
               IF(STRMD5($A_l) ! "5058F1AF8388633F609CADB75A75DC9D")
                  $A_key = 48
               END_IF
            END_IF
            IF((($A_key > 64)&($A_key < 91))|(($A_key > 185)&($A_key < 223)))
               $A_mess = 0x0100
            else
               $A_mess = 0x0102
            END_IF
            IF($A_key > 0)
               postmessage($A_hwnd,$A_mess,$A_key,0)
               waitms($A_delay)
            END_IF
            $A_a=999
         END_IF
      END_CYC
   END_CYC
   IF($A_kbl!GETKBLAYOUT($A_hwnd))
      setkblayout($A_hwnd, $A_kbl)
   END_IF
END_SUB
//-----------------------------------------------------------
$A_press_delay = 30

A_KEYSTRING ("Hello:-) world! Проверка: связи*", 20, $A_hwnd)


Ругается на
IF($A_keys_arr[$A_a] = $A_l)




Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Функция поиска окон по заголовку возвращает hwnd окна, но проблема в том что нам нужно внутреннее окно блокнота, только туда можно вводить текст. Получить его возможно только либо в ручную либо функцией возвращающей hwnd по координате HGET.
А ошибка у тебя выскакивает, как оказалось, из за скобки. Убрал её и все стало нормально

Верный скрипт
Code: (clickermann) [Select]
//A_KEYSTRING
SUB(A_KEYSTRING, $A_str, $A_delay, $A_hwnd)
   $A_kbl=GETKBLAYOUT($A_hwnd)
   IF($A_kbl ! 1049)
      setkblayout($A_hwnd, 1049)
   END_IF   
   FOR($A_nstr=1,$A_nstr<STRLEN ($A_str)+1)
      $A_l=STRCUT ($A_str, $A_nstr, 1)
      IF(ARRSIZE ($A_keys_arr) = 0)
         TFREADARR ("keys.txt", $A_keys_arr)
      END_IF   
      FOR($A_a=1,$A_a<ARRSIZE ($A_keys_arr),2)
         IF($A_keys_arr[$A_a] = $A_l)
            $A_key = $A_keys_arr[$A_a-1]
            IF($A_key = 46)
               IF(STRMD5($A_l) ! "5058F1AF8388633F609CADB75A75DC9D")
                  $A_key = 48
               END_IF
            END_IF
            IF((($A_key > 64)&($A_key < 91))|(($A_key > 185)&($A_key < 223)))
               $A_mess = 0x0100
            else
               $A_mess = 0x0102
            END_IF
            IF($A_key > 0)
               postmessage($A_hwnd,$A_mess,$A_key,0)
               waitms($A_delay)
            END_IF
            $A_a=999
         END_IF
      END_CYC
   END_CYC
   IF($A_kbl!GETKBLAYOUT($A_hwnd))
      setkblayout($A_hwnd, $A_kbl)
   END_IF
END_SUB
//-----------------------------------------------------------
$A_press_delay = 30

$hw = HGET(310,177) // координата окна блокнота (белое пространство)
A_KEYSTRING ("Hello:- world! Проверка: связи*", 20, $hw)

HALT

Вообщето это представлено как библиотека функций. Тебе требуется приложить в ту же папку где лежит скрипт файлы alt_winmode.cms и keys.txt
В своем скрипте пишем в первых строках #include "alt_winmode.cms"

Выглядит так
Code: (clickermann) [Select]
#include "alt_winmode.cms"

$hw = HGET(310,177) // координата окна блокнота (белое пространство)
A_KEYSTRING ("Hello:- world! Проверка: связи*", 0, $hw)
HALT

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Есть другой вариант. В оконном режиме KEYSTRING в точности печатает заданные символы. Можно временно включить оконный режим и напечатать.

Пример
Code: (clickermann) [Select]
SUB(A_KEYSTRING, $str, $a_cx,$a_cy)
   $hw = HGET($a_cx,$a_cy)
   HSET($hw,1)
   KEYSTRING($str)
   HSET($hw,0)
END_SUB


A_KEYSTRING ("Hello:-) world! Проверка: связи*", 310,177)
HALT
« Last Edit: January 12, 2017, 09:04:35 PM by Oraven »

m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
Большое спасибо за развернутый ответ!

Функция поиска окон по заголовку возвращает hwnd окна, но проблема в том что нам нужно внутреннее окно блокнота, только туда можно вводить текст.
Может оно по идее и так, но у меня всё печатает.
То, что hwnd окна и рабочего поля разные я заметил. Но при поиске по окну печать идёт.

Про какую скобку идёт речь?
А, понял, про смайлик в печатаемом тексте. Писал для проверки, мелькнула мысль, что это ай-ай, но отвлекся. Зато возник резонный вопрос — что делать, если скобка таки нужна в тексте? Тот же смайлик. Подозреваю, что и другие знаки (слеши, кавычки и т.п.) так же могут попортить картину.



« Last Edit: January 13, 2017, 11:43:07 AM by m.igel »

m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
Есть другой вариант. В оконном режиме KEYSTRING в точности печатает заданные символы. Можно временно включить оконный режим и напечатать.

Пример
Code: (clickermann) [Select]
A_KEYSTRING ("Hello:-) world! Проверка: связи*", 310,177)

Чота мне эта строчка не нравится.
После текста вроде должна идти задержка и нумер окна.

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Есть другой вариант. В оконном режиме KEYSTRING в точности печатает заданные символы. Можно временно включить оконный режим и напечатать.

Пример
Code: (clickermann) [Select]
A_KEYSTRING ("Hello:-) world! Проверка: связи*", 310,177)

Чота мне эта строчка не нравится.
После текста вроде должна идти задержка и нумер окна.

В моем примере такого нет. Задержка не нужна вовсе. А HWND окна берется по координате. При этом кликер работает в обычном режиме эмуляции.
Возможно еще нужно добавить предварительный клик по полю ввода, для фокуса.

m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
... либо функцией возвращающей hwnd по координате HGET.

Code: (clickermann) [Select]
...
$hw = HGET(310,177) // координата окна блокнота (белое пространство)
A_KEYSTRING ("Hello:- world! Проверка: связи*", 20, $hw)


Насколько я понял, тут мы жестко забиваем координаты точки в текстовом поле блокнота. Он окно может открыться/быть открыто где угодно. Верно ли я мыслю, что тут возможны два варианта.

1. Привязаться к окну (перейти в оконный режим, да?) и там кликнуть по нужному месту опираясь на "оконные" координаты.

2. Найти окно. Переместить его в 0,0. Задать размер, положим 300*200. Взять координату 150,100 (чтоб наверняка попасть).

m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
Есть другой вариант. В оконном режиме KEYSTRING в точности печатает заданные символы. Можно временно включить оконный режим и напечатать.

Пример
Code: (clickermann) [Select]
A_KEYSTRING ("Hello:-) world! Проверка: связи*", 310,177)

Чота мне эта строчка не нравится.
После текста вроде должна идти задержка и нумер окна.

В моем примере такого нет. Задержка не нужна вовсе. А HWND окна берется по координате. При этом кликер работает в обычном режиме эмуляции.
Возможно еще нужно добавить предварительный клик по полю ввода, для фокуса.

Я, конечно, прошу прощения, может чего не понял, но...

Есть другой вариант. В оконном режиме KEYSTRING в точности печатает заданные символы. Можно временно включить оконный режим и напечатать.

Пример
Code: (clickermann) [Select]
SUB(A_KEYSTRING, $str, $a_cx,$a_cy)
   $hw = HGET($a_cx,$a_cy)
   HSET($hw,1)
   KEYSTRING($str)
   HSET($hw,0)
END_SUB


A_KEYSTRING ("Hello:-) world! Проверка: связи*", 310,177)
HALT

и

Пишем
A_KEYSTRING("Текст", 10-задержка, hwnd-окна куда пишем)

« Last Edit: January 13, 2017, 12:15:39 PM by m.igel »

m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
Ерунда какая-то!

Попробовал пойти по второму варианту, с включением оконного режима. Чуток подшаманил, вроде должно работать, но — индейская изба! Печать идёт в стиле:
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeelllllllllllllllllllllllllllllllllllllllllllllllllllllloooooooooooooooooooooooo
только залипания ещё больше. Что я сделал не так?

Code: (clickermann) [Select]
// 12.01.2017 6

#name "Запись в notepad"//Имя нашего скрипта

EXECUTE("notepad.exe")//Запускаем программу notepad.exe. Команда EXECUTE равносильна окну "Выполнить" в Виндовс (Win+R).

WNDSTATE(WNDFIND("Блокнот"), 1)//Разворачиваем окно в заголовке которого есть строка "Блокнот". 1 - означает развернуть, 0 - свернуть.

WAITMS(1000)//Ждем чтобы блокнот окончательно запустился. 500 мс достаточно

$hw = wndfind("Блокнот") // получаем HWND окна Блокнота
//print   ($hw)

WNDPOS($hw,10,10)  // помещаем Блокнот в угол экрана
 
HSET($hw,1) // включаем в Блокноте оконный режим
$hw2 = HGET(100,100) // определяем hwnd текстового поля блокнота (как ни странно, 100,100 от угла экрана, а не от окна)
 
HSET($hw2,1) // включаем оконный режим в текстовом поле блокнота
KEYSTRING("Hello:- world! Проверка: связи*", 50) // пишем Привет...
HSET($hw2,0) // снимаем оконный режим.

print   ( $hw )
print   ( $hw2 )

//SUB(A_KEYSTRING, $str, 10,$hw)
//   //$hw = HGET($a_cx,$a_cy)
//      //$hw = wndfind("Безымянный") // (мой изврат) получаем HWND окна notepad
//   HSET($hw,1)
//   KEYSTRING($str)
//   HSET($hw,0)
//END_SUB

////--------------------
//$hwnd1 = wndfind("Clickermann -") // получаем HWND окна кликера
//$hwnd2 = wndfind("Блокнот") // получаем HWND окна Блокнота

//SETKBLAYOUT($hwnd1, 1033) // устанавливаем английскую раскладку для окон
//SETKBLAYOUT($hwnd2, 1033)
//print   ($hwnd1)
//print   ($hwnd2)

////или
////    SETKBLAYOUT($hwnd1, 1049) // устанавливаем русскую раскладку для окон
////    SETKBLAYOUT($hwnd2, 1049)
////--------------------

//FOR($i, $i < 2)//Начало цикла. Цифра 2 означает что цикл повторится 5 раз
//   
//   A_KEYSTRING("Hello:-/ world! Проверка: связи*", 20, $hw)//Вводим текст. 20 означает задержку в 20 мс между вводом каждой буквы
//   
//   KEYPRESS(#ENTER)//Нажимаем Enter чтобы перевести строку. #ENTER - код клавиши Enter
//   
//   print   ($hw)
//   
//END_CYC//Заканчиваем цикл

HALT//Останавливаем скрипт

Установка одинаковых раскладок не помогает.

Если вместо KEYSTRING использовать
KEYPRESS(#1)
KEYPRESS(#2)
KEYPRESS(#3)
то всё прекрасно работает!
« Last Edit: January 13, 2017, 03:17:57 PM by m.igel »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Что я сделал не так?

А ЧЯДНТ? Смотри скрин  :D.


Code: (clickermann) [Select]
$hw2 = HGET(100,100)  // определяем hwnd текстового поля блокнота (как ни странно, 100,100 от угла экрана, а не от окна)
А что здесь странного? HGET команда с глобальными координатами, иначе зачем бы она была нужна.


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Quote
Цифра 2 означает что цикл повторится 5 раз
С этой логикой не поспоришь...

Верный код
Code: (clickermann) [Select]
SUB(A_KEYSTRING, $str, $hwnd)
   HSET($hwnd,1)
   KEYSTRING($str)
   HSET($hwnd,0)
END_SUB

//=============================================

EXECUTE("notepad.exe")//Запускаем программу notepad.exe. Команда EXECUTE равносильна окну "Выполнить" в Виндовс (Win+R).
WAITMS(1000)

$hw = wndfind("Блокнот") // получаем HWND окна Блокнота
WNDGETINFO($hw, $px, $py, $sx, $sy)
$hw = HGET($px+100,$py+100)

FOR($i=0, $i < 2) //Начало цикла. Цифра 2 означает что цикл повторится 2 раза
   
   A_KEYSTRING("Hello:-/ world! Проверка: связи*", $hw)
   WAITMS(50)
   KEYPRESS(#ENTER)
   WAITMS(50)
   
END_CYC

HALT
« Last Edit: January 13, 2017, 03:26:40 PM by Oraven »

Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Code: (clickermann) [Select]
SUB(A_KEYSTRING, $str, $hwnd)Переменные используемые в подпрограмме $str и $hwnd после окончания подпрограммы будут обнулены. Поэтому не стоит использовать переменные с темже именем где то еще.





m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
Что я сделал не так?

А ЧЯДНТ? Смотри скрин  :D.


Code: (clickermann) [Select]
$hw2 = HGET(100,100)  // определяем hwnd текстового поля блокнота (как ни странно, 100,100 от угла экрана, а не от окна)
А что здесь странного? HGET команда с глобальными координатами, иначе зачем бы она была нужна.

Шаман, аднака!
Поставил вместо Hello... просто 5, так он мне аж 53 штуки напечатал. Но ашей гораздо больше.

А вот с глобальными координатами непонятно.
Из хелпа:
"После этого HWND на главной форме меняться уже не будет, он будет отображать рабочий элемент. Так же изменятся координаты, отображаемые в редакторе сценария, поскольку каждое отдельное "окно"-элемент обладает собственной относительной системой координат, где (0,0) находится в левом верхнем углу элемента. Относительная она потому что если передвигать окно по экрану, его "внутренняя" система координат не изменится.
Сам синтаксис сценариев является единым и для обычного режима, и для оконного. "
Поэтому я и решил, что в оконном режиме координаты оконные. Думал, что привязавшись к окну и развернув его до заданных размеров, можно будет тыкать мышкой куда надо. Но не прокатило. пришлось извращаться.

"После этого HWND на главной форме меняться уже не будет..." — вот это момент вообще не понял. Меняется за милую душу когда мышью елозишь.

m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
Quote
Цифра 2 означает что цикл повторится 5 раз
С этой логикой не поспоришь...
С логикой вообще спорить бесполезно!  ;D

Верный код
Code: (clickermann) [Select]
SUB(A_KEYSTRING, $str, $hwnd)
   HSET($hwnd,1)
   KEYSTRING($str)
   HSET($hwnd,0)
END_SUB

//=============================================

EXECUTE("notepad.exe")//Запускаем программу notepad.exe. Команда EXECUTE равносильна окну "Выполнить" в Виндовс (Win+R).
WAITMS(1000)

$hw = wndfind("Блокнот") // получаем HWND окна Блокнота
WNDGETINFO($hw, $px, $py, $sx, $sy)
$hw = HGET($px+100,$py+100)

FOR($i=0, $i < 2) //Начало цикла. Цифра 2 означает что цикл повторится 2 раза
   
   A_KEYSTRING("Hello:-/ world! Проверка: связи*", $hw)
   WAITMS(50)
   KEYPRESS(#ENTER)
   WAITMS(50)
   
END_CYC

HALT


Логичненько.
Верный код это хорошо, спасибо. Но хотелось бы понять откуда вылез этот "дребезг клавиш".

m.igel

  • Освоившийся
  • **
  • Posts: 23
    • View Profile
Похоже проблема на моей стороне...  :(