Что нового

Нюансы использования window handle

FazZzuR

Новичок
Сообщения
24
Репутация
1
Доброе время суток.

Сегодня с толкнулся с таким поведением при использовании функции WinActivate
Код:
ConsoleWrite(WinActivate(0x002C0858) & @CRLF)
ConsoleWrite(WinActivate("c4classic.ru") & @CRLF)

Первая строчка не отрабатывает и возвращает 0, вторая отрабатывает и выводи в лог те же цифры, что используются в 1 строке(0x002C0858).
Не совсем понимаю почему так. Мне это нужно, потому что программа работает с несколькими окнами, которые меняют название на протяжении работы, поэтому при запуске каждого окна, я сохраняю его handle в временный файл, который живет до закрытия программы. После чего хотел при необходимости обращения к окну, считывать ранее записанный handle. Но столкнулся с тем что не работает оно так.
Кто нибудь подскажет что я делаю не так и почему оно так не работает?
 
A

Alofa

Гость
FazZzuR сказал(а):
... Первая строчка не отрабатывает и возвращает 0, ...
Код:
ConsoleWrite(WinActivate(HWnd(0x002C0858)) & @CRLF)

Но обычно делается так:
Код:
$hWnd = WinActivate("c4classic.ru")
ConsoleWrite($hWnd & @CRLF)


FazZzuR сказал(а):
... вторая отрабатывает и выводи в лог те же цифры, что используются в 1 строке(0x002C0858).
Все правильно, так и должно быть. "ConsoleWrite()" выводит результат работы (возвращаемое значение) функции "WinActivate()".


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

FazZzuR сказал(а):
... я сохраняю его handle в временный файл, который живет до закрытия программы.
Это что-то новое :smile:
Кстати если вы сохраните каждый дескриптор в глобально объявленную переменную, то они тоже будут жить на протяжении всей работы скрипта.
 
Автор
F

FazZzuR

Новичок
Сообщения
24
Репутация
1
Alofa сказал(а):
Все правильно, так и должно быть. "ConsoleWrite()" выводит результат работы (возвращаемое значение) функции "WinActivate()".
Спасибо кэп, я знаю что возвращает эта функция. Но вопрос был вообще не о ней. А о том почему если подставить шестнадцатеричное число хранящееся в переменно руками - WinActivate не работает. В то время как если я подсуну переменную созданную например WinGetHandle(), в которой будет то же самое число, что я вбил вручную или считал с файла - все сработает. Я не понимаю почему так происходит.
Я более чем прекрасно осведомлен о том как это обычно делается.
Глобальная переменная - не вариант, в ввиду того что за каждым окном закрепляется свой собственный экземпляр процесса. И в некоторых ситуациях, процессу которым было запущено одно окно, надо провести пару операций с окном запущенным другим процессом. С окном, которое меняет свое название.

Вот еще более подробный пример того о чем я говорю
Код:
$winHandle = WinGetHandle("c4classic.ru")
ConsoleWrite($winHandle & @CRLF)
ConsoleWrite(WinActivate($winHandle) & @CRLF)
ConsoleWrite(WinActivate(0x000E07D2) & @CRLF)

И вывод работы этого кода
Код:
0x000E07D2
0x000E07D2
0
 

ildar

Осваивающий
Сообщения
252
Репутация
30
А о том почему если подставить шестнадцатеричное число хранящееся в переменно руками - WinActivate не работает.
Он его не понимает.
Код:
ConsoleWrite(WinActivate(HWnd(0x000E07D2)) & @CRLF)
вот так поймет.
Alofa в своем ответе давал пример
 
Автор
F

FazZzuR

Новичок
Сообщения
24
Репутация
1
Оооо, мой косяк. Не заметил этих 4 волшебных буквы Hwnd.

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

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
FazZzuR
У вас все правильно изначально, можно сохранять дескриптор в переменную, 0x000A07D2, но если попадается в дескрипторе E как здесь 0x000E07D2 - то аутоит впадает в панику, и думает что это экспоненциальная запись числа. Багу уже 4 месяца https://www.autoitscript.com/trac/autoit/ticket/3179


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

И еще есть момент, когда вы читаете 0x000A07D2 из файла, ( а как вы его читаете не показали) то, скорее всего, он прочитан как строка, и поэтому вы вместо WinActivate(0x000A07D2) делаете WinActivate('0x000A07D2') - с этим тоже будут недоразумения. И поэтому - все что касается дескрипторов - делайте через Hwnd, но об этом уже сказали.
 
Автор
F

FazZzuR

Новичок
Сообщения
24
Репутация
1
inververs, спасибо за доступное объяснение. Насчет строки я и сам подумал и даже проверил. Буквально пару дней назад создавал топик в котором не мог разобраться почему If 'False' срабатывает. До этого работал только с php и там строковый false преобразуется в булев false, здесь же с преобразованием строк дела несколько иначе, я после того случая хорошо усвоил. Ибо после того как я смотрел на срабатывающий при 'False' If - мой мозг знатно успел поплавиться, пока я не загуглил преобразование типов autoit :rofl:
 
A

Alofa

Гость
Сам всегда пользовал "HWnd()" в таких случаях не задумываясь.
А теперь решил поэкспериментировать и вот вам здрасьте...
НЕ могу добиться бага описанного в этой теме. :stars:
На AutoIt v3.3.12.0 все работает и так: :shok:
Код:
ConsoleWrite(WinActivate(0x002E044A) & @CRLF)
 
Автор
F

FazZzuR

Новичок
Сообщения
24
Репутация
1
Alofa, У меня v3.3.14.2, window 10 x64

Предпложение на то что проблема в букве E которая воспринимается как экспоненциальная запись числа - не совсем верно. В самом первом посте моей темы, handle не содержит никаких "E". Я так понял он в принципе не работает если ему передать параметром просто шестнадцатеричное число, а только если передавать переменные полученные специальными функциями. Видимо это не совсем обычные переменные и содержат они что-то еще.
Жаль что исходников autoit нет, глянуть что там hwnd() делает с числом то.
 
Автор
F

FazZzuR

Новичок
Сообщения
24
Репутация
1
inververs, Ну теперь точно тему можно закрывать. Попробовал еще такую конструкцию
Код:
WinActivate(Ptr(0x001907D2))

Работает.
Ответом на мой вопрос является - надо передавать не просто переменную с числом, а переменную указатель.

P.S. Как я понял это число - адрес в памяти где хранится нечто позволяющее установить окно?
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
FazZzuR [?]
P.S. Как я понял это число - адрес в памяти где хранится нечто позволяющее установить окно?
Что PTR, что HWND без разницы, это все 32 или 64 указатель, но HWND удобнее пользоваться, сразу понятно, что это указывает на окно.
Правильнее что бы ConsoleWrite(VarGetType(WinGetHandle('[ACTIVE]')) & @CRLF) возвращала hwnd, но видимо, нету такого типа.

адрес в памяти где хранится нечто позволяющее установить окно?
Нет, это не адрес в памяти - считаете это уникальным номером окна.

FazZzuR [?]
Так не правильно делать. HWND(число) - еще проверяет, что число - правильный идентификатор окна, а PTR - нет.
Сделаете например так:
0x002704C1 - такого окна у меня нету. Тогда Hwnd вернет 0x00000000, а Ptr - 0x002704C1
Код:
ConsoleWrite(HWnd(0x002704C1) & @CRLF)
ConsoleWrite(Ptr(0x002704C1) & @CRLF)
 

InnI

AutoIT Гуру
Сообщения
4,982
Репутация
1,460
FazZzuR
Видимо это не совсем обычные переменные и содержат они что-то еще.
В справке "Заголовки и текст окон (расширенные)" указано: "Важно заметить, дескриптор окна не рассматривается, как число или строка - это уникальный тип данных." Просто поверьте в это, используйте hWnd() для указания типа, и не парьтесь.

Есть ещё, например, нюансы файловых "дескрипторов", которые на самом деле всего лишь порядковый номер каких-то внутренних данных AutoIt
Код:
$f1 = FileOpen(@ScriptName)
$f2 = FileOpen(@ScriptName)
$f3 = FileOpen(@ScriptName)
ConsoleWrite($f1 &":"& $f2 &":"& $f3 & @CRLF)
Элементы GUI также хранятся по каким-то, одному AutoIt понятным, порядковым номерам. И т.д.

Жаль что исходников autoit нет, глянуть что там hwnd() делает с числом то.
поиск исходного кода языка autoit
 
Верх