получить текст из заданного окна

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
moshkin
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 03.12.2002 (Вт) 15:01
Откуда: Russia

получить текст из заданного окна

Сообщение moshkin » 29.11.2005 (Вт) 11:36

Ох и форум работает :( ...
Вообще нужно вводить данные (имитировать работу пользователя) в стороннюю программу и читать ответы на эти действия. (это типа автоматизация производства а не хакерство)
Ну, послать нажатие клавиши вроде умею.
А вот как получить текст из заданного приложения?
А то или форум работает не очень, или не пойму.
Нашел только один топик
http://bbs.vbstreets.ru/viewtopic.php?t ... bfda3c6d75
но пока не разобрался в том примере котоый можно скачать - как именно перебрать все открытые приложения? - ну чтобы выбрать нужное?
И как все-таки получить текст из него, потому что даже если я знаю заголовок окна, то там в примере мы получаем текст из текстбокса. А вот к примеру из блокнота как его получить?
Извиняюсь если я бестолковый.

Odrick
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 503
Зарегистрирован: 28.09.2003 (Вс) 2:04

Сообщение Odrick » 29.11.2005 (Вт) 12:05

Ну а чем блокнот принципиально отличается от всего остального? Тебе достаточно найти hWnd нужного окна и контрола. А уж получить оттуда текст есть масса способов. Поиск окна - FindWindow.
То, что для одних константа, для других только переменная...

Odrick
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 503
Зарегистрирован: 28.09.2003 (Вс) 2:04

Сообщение Odrick » 29.11.2005 (Вт) 12:06

Ну а чем блокнот принципиально отличается от всего остального? Тебе достаточно найти hWnd нужного окна и контрола. А уж получить оттуда текст есть масса способов. Поиск окна - FindWindow.
То, что для одних константа, для других только переменная...

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 29.11.2005 (Вт) 12:18

Есть такие программы, как AutoIt и AutoMate. Они это все уже умеют.
Lasciate ogni speranza, voi ch'entrate.

moshkin
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 03.12.2002 (Вт) 15:01
Откуда: Russia

Сообщение moshkin » 29.11.2005 (Вт) 13:03

Про программы такие (типа automate) знаю. Правда не знаю, и сильно сомневаюсь что они могут именно то что мне надо - по расписанию, (а в идеале она будет постоянно работать) брать с сетевого диска данные из файла (*.csv :) причем там еще куча лишних данных ) и вбивать на основе этих данных команды в другую программу, причем дальнейшие действия будут отличаться в зависимости от ответа в той сторонней программе (команда может выполнится или нет, тогад надо будет пропустить а эту повторить спустя время).
Пока не пойму как узнать hWnd нужного контрола. Или как их все перебрать в заданной программе. Торможу наверное.

Odrick
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 503
Зарегистрирован: 28.09.2003 (Вс) 2:04

Сообщение Odrick » 29.11.2005 (Вт) 13:23

FindWindowEx
То, что для одних константа, для других только переменная...

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 29.11.2005 (Вт) 13:31

moshkin писал(а):Про программы такие (типа automate) знаю. Правда не знаю, и сильно сомневаюсь что они могут именно то что мне надо - по расписанию, (а в идеале она будет постоянно работать) брать с сетевого диска данные из файла (*.csv :) причем там еще куча лишних данных ) и вбивать на основе этих данных команды в другую программу, причем дальнейшие действия будут отличаться в зависимости от ответа в той сторонней программе (команда может выполнится или нет, тогад надо будет пропустить а эту повторить спустя время).

Все это она умеет.
А если что, то в ней есть разновидность бейсика, можно запрограммировать все остальное.
Lasciate ogni speranza, voi ch'entrate.

moshkin
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 03.12.2002 (Вт) 15:01
Откуда: Russia

Сообщение moshkin » 29.11.2005 (Вт) 13:37

Так вот сразу ни фига не понятно - к примеру тот же блокнот.
Ну имя окна я пока задал. А как называется окно в блокноте которе содержит текст? Вообще понятно что надо перебрать все дочерние объекты. Но как... Ссылка в хелпе идет на GlobalAddAtom но с ним пока не понятно.
Честно говоря, от короткого примера по перебору всех запущенных программ и перебору всех объектов в заданной программе очень не отказался. ;)
(хотя это и наглость)
Пока писал Alibek ответил - не знал, что там такое есть. Но вообще то хотелось бы свое, конечно. Надежнее, ну и интереснее. И заслуга перед Родиной, опять таки. Наверное если не разберусь с чтением текста из чухого окна, то уж тогда буду пробовать с AutoMate. Спасибо за совет.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.12.2005 (Чт) 13:51

moshkin писал(а):Так вот сразу ни фига не понятно - к примеру тот же блокнот.
Ну имя окна я пока задал. А как называется окно в блокноте которе содержит текст?

Класс называется Edit.
Изображение

moshkin
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 03.12.2002 (Вт) 15:01
Откуда: Russia

Сообщение moshkin » 01.12.2005 (Чт) 14:16

2 Темыч : Спасибо. Пока форум был не доступен методом "шевели мозгами", чтением примеров и поиска в инете как-то класс определили. Теперь пытаемся получить текст который там есть. Если брать из текстбокса - легко. А из блокнота так не получается. Нашел, вероятно, ваш топик
(...From: "A. Skrobov" <tyomitch@r66.ru>...)
там пытаются читать из бокнота с помощью
SendMessage FindTextHWnd, WM_GETTEXT, winTextLength, WinText
но пока не получается. Ничего не понятно. :(

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.12.2005 (Чт) 16:02

...вероятно, мой топик. А откуда это? :-)


Покажи весь код: по одной строчке не смогу сказать, что у тебя не так.
Изображение

moshkin
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 03.12.2002 (Вт) 15:01
Откуда: Russia

Сообщение moshkin » 01.12.2005 (Чт) 17:02

2 tyomitch:
:) яндекс. Поиск дает ссылку на
http://www.vbrussian.com/CONF/view_sele ... sgID=30483
тема "Hе могу взять текст из чужого окна"
даты с 6/29/2004 1:04:27 PM по 6/26/2004 3:23:50 AM
Кроме Вас еще Ruslan Demidow и Минаев Игорь.

Код:
hHandle1 = FindWindow(vbNullString, "Áåçûìÿííûé - Áëîêíîò")
' кракозябры это "безымянный - блокнот"
hHandle2 = apiGetWindow(hHandle1, GW_CHILD)
winTextLength = SendMessage(hHandle2, WM_GETTEXTLENGTH, 0&, 0&)
SendMessage hHandle2, WM_GETTEXT, ByVal winTextLength, WinText
не ругается но в wintext ничего нет.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.12.2005 (Чт) 20:22

Понятно. Это RU.VISUAL.BASIC. Первоисточник тут: http://groups.google.com/group/fido7.ru ... b486a23ca9

про твой код: WinText - это текстбокс?
там должна быть стринговая переменная.
Изображение

moshkin
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 03.12.2002 (Вт) 15:01
Откуда: Russia

Сообщение moshkin » 13.12.2005 (Вт) 11:15

WinText стринговая..., но в ней пусто.:(

Вот код:

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long

Private Sub Command2_Click()

Dim i As Integer
Dim winTextLength As Long
Dim WinText As String

hHandle1 = FindWindow(vbNullString, "Безымянный-Блокнот")

hHandle2 = apiGetWindow(hHandle1, 5)

MyStr1 = String(GetWindowTextLength(hHandle2) + 1, Chr$(0))

StrClassName = fGetCaption(hHandle2)
txtText.Text = CStr(hHandle2) & " " & StrClassName & " " & MyStr1

Do
hHandle2 = apiGetWindow(hHandle2, 2)

MyStr1 = String(GetWindowTextLength(hHandle2) + 1, Chr$(0))

GetWindowText hHandle2, MyStr1, Len(MyStr1)

StrClassName = fGetCaption(hHandle2)
winTextLength = SendMessage(hHandle2, WM_GETTEXTLENGTH, &O0, &O0)
SendMessage hHandle2, WM_GETTEXT, ByVal winTextLength, ByVal WinText
txtText.Text = txtText.Text & vbCrLf & CStr(hHandle2) & " " & StrClassName & " " & WinText

Loop Until hHandle2 = 0&
End Sub

И все равно в WinText пусто - Что делать?

Юстас
Бывалый
Бывалый
 
Сообщения: 200
Зарегистрирован: 24.10.2003 (Пт) 5:05

Сообщение Юстас » 13.12.2005 (Вт) 13:31

Что делать? Для начала заменить "Безымянный-Блокнот" на "Безымянный - Блокнот", и желательно с ByVal
И неплохо было бы проверять, какие значения возвращают api-функции. Это помогает локализовать ошибку.

moshkin
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 03.12.2002 (Вт) 15:01
Откуда: Russia

Сообщение moshkin » 13.12.2005 (Вт) 13:48

"Безымянный - Блокнот" было в программе правильно, просто при копировании были проблемы с кодировкой и текст был введен вручную

a = SendMessage(hHandle2, WM_GETTEXT, ByVal winTextLength, ByVal WinText)

возвращает значение 0
А что должно быть, или мы что-то не так делаем?

Юстас
Бывалый
Бывалый
 
Сообщения: 200
Зарегистрирован: 24.10.2003 (Пт) 5:05

Сообщение Юстас » 13.12.2005 (Вт) 14:12

Вы что-то делаете не так. На WM_GETTEXT возвращается длина текста без учёта завершающего нуля.

Вот так текст получается в переменную winText:

Код: Выделить всё
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" _
                                    (ByVal lpClassName As String, _
                                    ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _
                                    (ByVal hWnd1 As Long, _
                                    ByVal hWnd2 As Long, _
                                    ByVal lpsz1 As String, _
                                    ByVal lpsz2 As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
                                    (ByVal hwnd As Long, _
                                    ByVal wMsg As Long, _
                                    ByVal wParam As Long, _
                                    ByVal lParam As String) As Long

Private Const WM_GETTEXT As Long = &HD
Private Const WM_GETTEXTLENGTH As Long = &HE


Private Sub Form_Load()
    Dim WinText As String, textLen As Long
    Dim hNotepad As Long, hChild As Long
    hNotepad = FindWindow(vbNullString, ByVal "Безымянный - Блокнот")
    If (hNotepad) Then
        hChild = FindWindowEx(hNotepad, 0, ByVal "edit", vbNullString)
        If (hChild) Then
            textLen = SendMessage(hChild, WM_GETTEXTLENGTH, 0, 0)
            If (textLen) Then
                WinText = String(textLen, Chr$(0))
                Call SendMessage(hChild, WM_GETTEXT, textLen, ByVal WinText)
                MsgBox WinText
                Exit Sub
            Else
                MsgBox "В блокноте нет текста"
            End If
        Else
            MsgBox "Чайлдов не обнаружено"
        End If
    Else
        MsgBox "Блокнот не найден"
    End If

End Sub

moshkin
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 03.12.2002 (Вт) 15:01
Откуда: Russia

Сообщение moshkin » 13.12.2005 (Вт) 14:43

Большое спасибо! Работает. Будем разбираться почему :).
Вот так бы сразу - кусочек кода и уже кое-что понятно.
(
Большие перерывы во времени создания постов из-за проблем на работе - переезд, поломки компов и проч - это я к тому что тема не заглохла, я все равно буду в этом разбираться
)
Всем спасибо!


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 37

    TopList