Что нового

Есть ли исходник в *.au3 утилиты AutoIt Window Info?

agikon

Знающий
Сообщения
789
Репутация
17
При снятии имени окна командой WinGetTitle иногда не полностью действительное имя окна совпадает с тем какое имя окна считывает WinGetTitle. (часто укорачивает имя)

А вот Autoit Window info всегда правильно показывает имя окна. Так вот я хотел бы понять как реализовано это в Autoit Window Info.

image.jpg
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
agikon [?]
WinGetTitle. (часто укорачивает имя)
Попробуйте получать заголовок окна функцией
Код:
_WinAPI_GetWindowText()
В ней кол-во символов в заголовке может быть до 2048 или посмотрите в сторону
Код:
Opt()
("WinTitleMatchMode")
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
madmasles [?]
WinApi не подходит так как предварительно надо знать дескриптор окна.
А в задаче стоит поиск полного имени окна лишь по заведомо известной его некоторой части, которая точно встречается в его имени.
Например чтобы по слову "Блокнот" определило полное имя окна "Безымянный - Блокнот".

Да это подходит, именно параметр 3.
Код:
Opt("WinTitleMatchMode", 3)

Но опять же не пойму как именно считать имя окна с помощью этой опциональной функции.

Вот так?
Код:
Opt("WinTitleMatchMode", 3)
$title = WinGetTitle("Блокнот","")
MsgBox(64,'','полное имя окна:'&$title&'' , '', '')

Если так, то тоже не всегда правильно определяет.
 

Suppir

Продвинутый
Сообщения
967
Репутация
62
Кстати, советую попробовать программку luSpy:
http://files.mail.ru/861788BDB4CF4398ACEDBFF2E293A11E

На мой взгляд, более информативная, чем AutoIt Window Info. Также позволяет управлять окнами.

Единственное - в этой сборке не работает дерево-список, будет ошибка выскакивать. Проект открытый, на c# написан.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
agikon
Код:
#include <WinAPI.au3>
Opt("WinTitleMatchMode", 2)
$title = _WinAPI_GetWindowText(WinGetHandle("Блокнот"))
MsgBox(64,'','полное имя окна: ' & $title)
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
Suppir
сторонние не проходят так как хочу реализовать этот механизм именно через код autoit в своём скрипте. Но спасибо за совет.

InnI
Вот тестировал и к удивлению и через WinApi _WinAPI_GetWindowText тоже не всегда корректно определяет(урезает), а вот сразу беру Autoit Windows Info и он как часы правильно определяет имя окна всегда. Так что какая-то глобальная ошибка в этом всём зарыта. У меня winXP sp3.

Чуть позже создам аналогичные условия на семёрке и посморю как там будем, и потом
отпишусь.
Но как бы там не было но как уже говорил Autoit Windows Info всегда определяет верно имя окна, даже тогда когда WinApi _WinAPI_GetWindowText показывает не корректно, так что наверно дело не в ОС.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Для начала убедитесь, что WinGetTitle() цепляет тоже самое окно, что и AWI. С помощью AWI определите хэндл окна и передайте его в функцию WinGetTitle(). Если функция через хэндл вернет правильное название, то значит у вас есть другие окна со схожими критериями. В любом случае можно вызвать WinGetHandle() и сравнить хэндл с показаниями AWI.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
agikon [?]
_WinAPI_GetWindowText тоже не всегда корректно определяет(урезает),
если урезает то это скорее из за того, что в функции WinAPI_GetWindowText определен буфер в 4096 символов. Если нужно больше, то увеличте его, перепишите функцию под себя.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Надо чтобы автор темы показал свой пример, длину заголовка, а то разговор получается немого с глухим. WinGetTitle у меня возвращает заголовок, который не умещается на экране.
Да, параметр 3 для WinTitleMatchMode, а то с остальными опять у вас будет длина не та, хотя с длиной всё в порядке, просто режим соответствия позволит захватить больше окон и очерёдность захвата их будет зависеть от Z-порядка.


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

inververs [?]
буфер в 4096 символов. Если нужно больше, то увеличте его
А функция его примет? Они же не зря ограничивают. Если длина заголовка в системе определена лимитом, то там хоть сколько увеличивай, всё равно вернёт лимит установленный системой.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
AZJIO
На msdn ничего не написано про лимиты, мне кажется что 4096 поставили просто так, так как посчитали что врядли где то будет заголовок окна длинее.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
inververs
Возможно, я рассуждаю гепотетически. На всё есть лимит, например в ListView количество пунктов ограничивается 65526. Для пути в системе есть лимит 260 символов и при поддержке юникода 32767 символов.

4096 это целый абзац... для заголовка в одну строку слишком ли много. Вот как выглядит 4096 в юникоде.
Хотя в msdn пишут "maximum number of characters", значит 4096 это число симолов, а не байт, значит ещё в 2 раза больше чем я указал.

00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Какое-то ограничение на длину заголовка окна, естественно, есть, но это относится к самому окну. В любом случае, GetWindowText() вернет полное название окна, если таковое имеется. Попробывал определить предел... У меня на Windows 7 заголовок перестает устанавливаться (AutoIt окно), если длина строки превышает 522236 символов, включая символ завершения.
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
AZJIO [?]
Надо чтобы автор темы показал свой пример, длину заголовка
обычные заголовки, с 10-20 символами, ни о каких заголовках сверх длинными именами речь не идёт.
Вся эта история начинается в браузерах, когда открываете много вкладок, то в некий момент времени происходит какой-то сбой (скорее-всего в браузерах, или в ОС) и WinGetTitle и WinAPI_GetWindowText возвращают укороченые имена, а вернее ту часть имени которая является искомой частью, например ищем по слову "Mozilla" $title = WinGetTitle("Mozilla","") , то переменная $title и возвращает одно это слово "Mozilla" , а не всё имя окна, а полное имя окна например такое "Mozilla Firefox - форум Autoit".
Но тут же сразу беру Autoit Window Info и имя окна считывает правильно.
определение имени окна делаю в самом простом варианте, вот как мне здесь подсказали, то есть лишь хочу прочитать полное имя окна по искомому слову.

Я раньше думал что глюк распостраняется на все способы снятия имени аутоитовские , и сторонние, но ведь Autoit Window Info всегда правильно показывает, даже тогда когда WinGetTitle и WinAPI_GetWindowText показывают некоректно. От в чём вопрос. Оказывается именно функции аутоита не всегда корректно считывают, хотя сам глюк скорее всего возникает в браузерах или в ОС.
Но повторяю Autoit Window Info считывает имя окна всегда правильно, даже когда наблюдается этот глюк в WinGetTitle и WinAPI_GetWindowText.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
agikon

Посмотрите что выводит мой вариант.
Код:
#Include <Array.au3>
#Include <WinAPIEx.au3>


$aList = ProcessList( "opera.exe" )
For $Idx = 1 To $aList[0][0] Step 1
	$aWins = _WinAPI_EnumProcessWindows( $aList[$Idx][1] )
	If Not @Error Then
		For $WinIdx = 1 To $aWins[0][0] Step 1
			$sTitle = _WinAPI_GetWindowText( $aWins[$WinIdx][0] )
			; ---
			ConsoleWrite( ">> Found new window <<" & @LF )
			ConsoleWrite( "Handle: " & $aWins[$WinIdx][0] & @LF )
			ConsoleWrite( "WinClass: " & $aWins[$WinIdx][1] & @LF )
			ConsoleWrite( "WinTitle: " & $sTitle & @LF )
			ConsoleWrite( "Process: " & $aList[$Idx][0] & "(" & $aList[$Idx][1] & ")" & @LF )
			ConsoleWrite( ">> End new window <<" & @LF )
		Next
	EndIf
Next
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
firex
Ваш код определяет нормально, даже тогда когда появляется так званый глюк.
Но он же определяет по процессу, а не по искомому слову заголовка окна.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
agikon
Проблема то получается не в том что возвращает неправильно, а в том чей заголовок он возвращает.

Вот для пробы пример. Как будет ошибка, то запустить скрипт и в активировать окно. Если глюка нет, то нет смысла искать его там, где его нет.
Код:
Sleep(3000)
; Возвращает заголовок окна, в данном случае активного
$sText = WinGetTitle("[ACTIVE]")
MsgBox(0, "Полное название/заголовок активного окна", $sText)


Код ваш не представлен. Если пример выдаёт нормально, то надо искать истинную причину в алгоритме и не в функции AutoIt3.
 

InnI

AutoIT Гуру
Сообщения
4,912
Репутация
1,429
agikon, попробуйте эти утилиты
http://autoit-script.ru/index.php?topic=4579.0
http://autoit-script.ru/index.php?topic=14400.0
Правильно ли они определяют заголовки?
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
agikon
А что мешает пройтись по всем процессам?

Код:
$aList = ProcessList()
For $Idx = 1 To $aList[0][0] Step 1
    $aWins = _WinAPI_EnumProcessWindows( $aList[$Idx][1] )
    If Not @Error Then
        For $WinIdx = 1 To $aWins[0][0] Step 1
            $sTitle = _WinAPI_GetWindowText( $aWins[$WinIdx][0] )
			If StringInStr( $sTitle, "Блокнот" ) Then
				ConsoleWrite( ">> Found new window <<" & @LF )
				ConsoleWrite( "Handle: " & $aWins[$WinIdx][0] & @LF )
				ConsoleWrite( "WinClass: " & $aWins[$WinIdx][1] & @LF )
				ConsoleWrite( "WinTitle: " & $sTitle & @LF )
				ConsoleWrite( "Process: " & $aList[$Idx][0] & "(" & $aList[$Idx][1] & ")" & @LF )
				ConsoleWrite( ">> End new window <<" & @LF )
			EndIf
        Next
    EndIf
Next
 
Автор
A

agikon

Знающий
Сообщения
789
Репутация
17
firex [?]
А что мешает пройтись по всем процессам?
класс!
спасибо это действительно хорошая идея!




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

AZJIO [?]
Вот для пробы пример. Как будет ошибка, то запустить скрипт и в активировать окно. Если глюка нет, то нет смысла искать его там, где его нет.
Вы правы.
Когда окно активно этот код нормально определяет. даже тогда когда WinGetTitle по искомому слову, и по _WinAPI_GetWindowText не определяет даже когда окно активно.

Получается почему-то WinGetTitle по искомому слову, и _WinAPI_GetWindowText не могут найти окно, даже когда оно активно. то есть проблема не в WinGetTitle и не в _WinAPI_GetWindowText, а в том что почему-то они просто его не могут найти.
 
Верх