Что нового

[Элементы GUI] работа с существующим, а не создаваемым ListBox

Neldezheil

B like Bee
Сообщения
27
Репутация
3
Возникла необходимость автоматизировать работу с элементом, известным как ListBox (на форме отображается, как список с полосой прокрутки).
Сам из себя данный элемент отображает массив строк, доступ к которым осуществляется через индексы данного массива.

Проблема в том, что данный список расположен html странице в окне обозревателя. (к сожалению, ссылку на страницу дать не могу, т.к. он находится в локальной корпоративной сети).

Вот пример из мануалов, немного переделанный, но по-прежнему не рабочий (форму создает, но при клике на элемент в списке вываливается ошибкой)
Код:
#include <GUIConstants.au3>
#include <GuiListBox.au3> ; изначально в примере указана библиотека_ _GuiList.au3, но в инклудах ее нет, поэтому заменил на сущесвующую

Opt ('MustDeclareVars', 1)

Dim $msg, $ret
Dim $listbox, $button, $label

GUICreate("ListBox Count Item(s) Demo", 400, 250, -1, -1) ;создание формы

$listbox = GUICtrlCreateList("", 125, 40, 180, 120) ;создание элемента ListBox_ _через присвоение переменной $listbox функции создания элемента на форме
GUICtrlSetData($listbox, "test1|test2|test3|") ;наполнение ListBox элементами
$button = GUICtrlCreateButton("Count Items", 150, 160, 120, 40) ;создание кнопки
$label = GUICtrlCreateLabel("# of Items", 150, 210, 120) ; создание надписи

GUISetState() ;функция, которая возвращает содержимое элемента и его индекс
While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $button
            $ret = _GUICtrlListCount ($listbox)
            If ($ret == $LB_ERR) Then
                MsgBox(16, "Error", "Unknown error from _GUICtrlListCount")
            Else
                GUICtrlSetData($label, "# of Items: " & $ret)
            EndIf
    EndSelect
WEnd


Насколько я понимаю, для обработки существующего списка нужно вытащить его handle, вытащить его через AutoIT Window Info не совес получается, ибо не могу придумать, как именно вернуть handle и не понимаю, что в итоге оказывается в переменной $listbox из примера. Вывод содержимого переменной в консоль не особо помогает, т.к. возвращается значение "3". По идее, это ControlID, но при обращении к нему через функцию _GuiCtrlListBox_GetCount возвращается 0, т.е. список как бы пустой.

Вот скрин Window Info с инфой по контролу
http://narod.ru/disk/20414766000/3.JPG.html
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Neldezheil [?]
По идее, это ControlID, но при обращении к нему через функцию _GuiCtrlListBox_GetCount возвращается 0, т.е. список как бы пустой.

Нормально работает :
Код:
$ret = _GUICtrlListBox_GetCount ($listbox); возвращает :3 элемента

а не _GUICtrlListCount ($listbox); код устаревшей версии AutoIt
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
с функцией разобрался, но проблема в присвоении переменной $listbox указателя на существующий список, отображаемый на веб-странице
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Neldezheil [?]
Вот скрин Window Info с инфой по контролу

Для этого окна попробуй :
Код:
;Судя по скрину :
$hWnd='0x00040BA8'; Handle всего окна
$sClass='[CLASS:Internet Explorer_TridentListBox;Instance:1]'
$hList=ControlGetHandle($hWnd, '', $sClass); Получить Handle ListBox'a
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
Спасибо, разобрался.
Т.к. это обозреватель, то handle окна меняется даже при обновлении страницы и в переменную $hWnd я заношу не handle из AutoIt Window Info, а title окна, т.к. в моем случае он не меняется.

Использование конструкции
Код:
$sClass='[CLASS:Internet Explorer_TridentListBox;Instance:1]'

заменил на указание значения из ClassnameNN.
Handle элемента возвращает корректно теперь.
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
Продолжаем мучения по спискам:
Код:
$Count = _GUICtrlListBox_GetCount($hList) ;число элементов в списке
$Element = _GUICtrlListBox_GetText($hList, $i) ;значение элемента списка с индесом I
$Selected = _GUICtrlListBox_GetSelItems($hList) ;возвращение индекса выбранного элемента (кликнутого мышью)
ConsoleWrite("handle списка: " & $HList & @CRLF)
ConsoleWrite("число элементов в списке: " & $Count & @CRLF)
ConsoleWrite("текст в элементе №" & $i & ": " & $Element & @CRLF)
ConsoleWrite("индекс выбранного элемента: " & $Selected & @CRLF)


Результат выполнения из консоли с вопросами

handle списка: 0x0035054A все верно
число элементов в списке: 216 все верно
текст в элементе №4: ?U?? возвращает вместо верного значения, как пофиксить?
индекс выбранного элемента: - ничего не возвращает, даж ошибку :(
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Neldezheil [?]
текст в элементе №4: ?U?? возвращает вместо верного значения, как пофиксить?

Число знаков совпадает ?
Возможно там русский текст в другой кодировке. Скорее всего.



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

_GUICtrlListBox_GetSelItems должен вывести массив значений

Проверь наличие отмеченных : _GUICtrlListBox_GetSelCount($hWnd)
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
Число знаков 14. Текст латиницей идет.
При этом вызов функции
Код:
$SLength = _GUICtrlListBox_GetTextLen($hList, $i)
ConsoleWrite("длина текста в элементе" & $i & ": " & $SLength & @CRLF)

возвращает верную длину текста в элементе
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
А если читать текст в эл-тах с другим номером ,что возвращает ?Кол-во знаков. есть какая-то закономерность ?
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
Сделал вывод содержимого элементов в цикле и как таковой закономерности не вижу, т.к. элементы с разными первыми символами в значении начинаются одинаково:
текст в элементе №0: ?
длина текста в элементе0: 0
текст в элементе №1: ?U
длина текста в элементе1: 18
текст в элементе №2: ?U??
длина текста в элементе2: 13
текст в элементе №3: ?U
длина текста в элементе3: 19
текст в элементе №4: ?U??
длина текста в элементе4: 14
текст в элементе №5: ?U
длина текста в элементе5: 9
текст в элементе №6: ?U??
длина текста в элементе6: 13

единственное, что корректно читается - это длина строки


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

Больше всего удивил вывод содержимого элемента с индексом 165:
текст в элементе №165: ??evice\HarddiskVolume1

Такое ощущение, что вместо вывода содержимого, выводится содержимое некоторого кеша :shok:
 

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Остается только экспериментировать.
А если попытаться прочитать текст другой ф-ей?
Код:
_GUICtrlListBox_SetSel($hList, 4)
_GUICtrlListBox_GetSelItemsText($hList)
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
Элемент в списке с заданным индексом выбирает, но
Код:
_GUICtrlListBox_GetSelItemsText($hList)
возвращает просто True независимо от указанного индекса, которым мы выбираем строку
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Neldezheil [?]
возвращает просто True независимо от указанного индекса, которым мы выбираем строку

Эта функция возвращает не TRUE, а массив из выделенных элементов, читай внимательно справку.



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

Neldezheil [?]
Больше всего удивил вывод содержимого элемента с индексом 165:текст в элементе №165: ??evice\HarddiskVolume1

Это потому, что элемента "№165" не существует. Почему? Элементы нумеруются начиная с 0, т.е. от 0 до _GUICtrlListBox_GetCount($hList) - 1.
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
Эта функция возвращает не TRUE, а массив из выделенных элементов, читай внимательно справку.
насколько я могу понять, то даже для случая, когда выбран 1 элемент, ссылаться на его значение нужно помимо указания переменной, указанием еще и индекса к данной переменной?
т.е., например, в цикле выбираем нужное количество элементов, в том же цикле считываем текст из выбранных, а затем, по индексу нужного элемента, получаем содержимое...

Это потому, что элемента "№165" не существует. Почему? Элементы нумеруются начиная с 0, т.е. от 0 до _GUICtrlListBox_GetCount($hList) - 1.

Это я знаю и не актуально, т.к. всего в списке 216 элементов и они имеют индексы от 0 до 215 включительно
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Neldezheil [?]
т.е., ты имеешь в виду, что выводить в консоль текст выбранного элемента нужно в цикле от 0 до длина строки и мне будет счастье?

:wacko:

Причем здесь длина строки? От 0 до значения в нулевом элементе массива. Если в списке можно выделить только один элемент, то [0] будет содержать всегда 1 (если конечно элемент выбран).



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

Neldezheil [?]
насколько я могу понять, то даже для случая, когда выбран 1 элемент, ссылаться на его значение нужно помимо указания переменной, указанием еще и индекса к данной переменной?т.е., например, в цикле выбираем нужное количество элементов, в том же цикле считываем текст из выбранных, а затем, по индексу нужного элемента, получаем содержимое...

:wacko: :blink: :-\

Извини, но я ничего не понял из этого.
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
по факту:
Код:
Dim $Element[1], $i
$i = 1 ;задаем индекс элемента в списке (беру 2й элемент, т.к. 1й пустой или в нем " ")
$Select = _GUICtrlListBox_SetSel($hList, $i) ; выбираем данный элемент
$Element[0] = _GUICtrlListBox_GetSelItemsText($hList) ; нулевому элементу массива $Element присваиваем значение содержимого элемента списка с индексом $i
ConsoleWrite("текст в элементе №" & $i+1 & ": " & $Element[0] & @CRLF); выводим в консоль


в данном случае в консоль возвращается текст:

текст в элементе №2:

т.е. в 1й элемент массива $Element значение не считывается, несмотря на то, что выбор указанного элемента в списке происходит...


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

заодно вопрос: есть ли решение данной проблемы:
Код:
$i = 1;задаем индекс элемента в списке
$SLength = _GUICtrlListBox_GetTextLen($hList, $i);узнаем длину текста элемента списка по индексу
$SText = _GUICtrlListBox_GetText($hList, $i);считываем его текст по индексу
ConsoleWrite("длина текста в элементе" & $i+1 & ": " & $SLength & @CRLF);выводим в консоль длину
ConsoleWrite("текст в элементе №" & $i+1 & ": " & $SText & @CRLF);выводим в консоль текст элемента списка


В итоге в консоль корректо выводится длина, но вот содержимое не корректно:
длина текста в элементе2: 18
текст в элементе №2: ??

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Ты заглядывал в справку? _GUICtrlListBox_GetSelItemsText() возвращает массив, который содержит текст всех выделенных в списке элементов. В нулевом элементе массива ([0]) содержится количество выделенных в списке элементов, или другими словами размерность массива - 1.

Код:
For $i = 1 To $aText[0]


Касаемо твоего кода:

Код:
Dim $Element[1], $i
$i = 1
_GUICtrlListBox_SetSel($hList, $i)
$Element = _GUICtrlListBox_GetSelItemsText($hList)
ConsoleWrite("текст в элементе №" & ($i + 1) & ": " & $Element[1] & @CRLF)



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

Neldezheil [?]
Текст в элементе списка написан латиницей... возможно, что-то с кодировками. все было проще, если бы _GuiCtrlListBox_GetText возвращала корректное содержимое элемента списка...

Какая версия AutoIt?
 
Автор
N

Neldezheil

B like Bee
Сообщения
27
Репутация
3
Yashied сказал(а):
Ты заглядывал в справку? _GUICtrlListBox_GetSelItemsText() возвращает массив, который содержит текст всех выделенных в списке элементов. В нулевом элементе массива ([0]) содержится количество выделенных в списке элементов, или другими словами размерность массива - 1.

Код:
For $i = 1 To $aText[0]


Касаемо твоего кода:

Код:
Dim $Element[1], $i
$i = 1
_GUICtrlListBox_SetSel($hList, $i)
$Element = _GUICtrlListBox_GetSelItemsText($hList)
ConsoleWrite("текст в элементе №" & ($i + 1) & ": " & $Element[1] & @CRLF)

до этого допер, но все равно актуальна проблема с выводом содержимого элемента...
в данном случае в консоль выводится
текст в элементе №2: ?u
хотя содержимое элемента несколько отличается от этого..

использую AutoIt v3.3.6.1
 
Верх