Как работать с "чужой" прогой не вручную.

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

Как работать с "чужой" прогой не вручную.

Сообщение GDK » 23.10.2008 (Чт) 18:19

Ну, вопрос длинный. Хочется автоматизировать работу с программой, которой пользуюсь только с помощью клавиатуры и мыши.
Есть: 1. Работающая программа в готовом виде(скомпилирована запускается EXE-шником).
2. На каком яз. написана - не знаю.
3. COM - скорее всего не поддерживает. Как проверить - не знаю. В её хелпе ничё не нашёл про это.
4. Написана для использования в Windows (не DOS-овское приложение)
5. Планирую работать при помощи эмуляций мышиных кликов и эмул. нажатия клав-ры(как эмулировать разберусь).
6. Уже получилось считать данные из элементов управления, напоминающих Label и TextBox.
7. 8) Мозги & желание + :) Умение работать в VB6/VBA + :wink: Некоторые навыки при работе с API - :oops: Плохое знание типов API, Каша в башке по поводу процессов, потоков, сообщений Windows.

Не знаю: 1. как считать инф. из элементов, напоминающих ListBox и ComboBox. - Даже не представляю как.
2. как найти hwnd элементов расположенных в окне программы. - Планирую идентифицировать эл. управления по их расположению относительно главного окна программы или! Начитался что можно определить имя оконного класса по hwnd. Значит можно один раз узнать это имя, а при следующих запусках просто пользоваться им и находить по нему hwnd элем упр. Но! При следующем запуске программы имя оконного класса, например ListBox-a, будет таким же как и при первом запуске? Как перебрать все окна определённого оконного класса.
3. Можно ли запустить программу как дочернее окно своей программы.
4. Можно ли не прибегая к эмуляции нажатий клавы и мыши управлять состоянием эл. упр. зная их hwnd.

Самый главный вопрос - 1. Никто не пробовал сделать что - либо подобное?

dr.MIG
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1441
Зарегистрирован: 18.12.2004 (Сб) 9:53
Откуда: г.Ярославль

Re: Как работать с "чужой" прогой не вручную.

Сообщение dr.MIG » 23.10.2008 (Чт) 19:53

1. См. в сторону SendMessage, CB_GETLBTEXT и т.п.
2. EnumChildWindows. Имя класса останется таким же.
3. Да, SetParent.
4. Можно, SendMessage.
Salus populi suprema lex

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Re: Как работать с "чужой" прогой не вручную.

Сообщение Proxy » 23.10.2008 (Чт) 21:16

Это всё извращенство. Зачем это понадобилось? Посмотри как артмани работает.
Follow the white rabbit.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как работать с "чужой" прогой не вручную.

Сообщение iGrok » 23.10.2008 (Чт) 22:03

Proxy писал(а):Это всё извращенство. Зачем это понадобилось? Посмотри как артмани работает.

Proxy, вот это уже реально флуд. Если уж и советовать что по теме в этом духе - так это nnCron.
Но если уж человек сам захотел разобраться в таких вещах - пусть лучше разберётся. Для него это явно не будет лишним.

А при чём тут артмани - я вообще не понимаю.
label:
cli
jmp label

mZone
Новичок
Новичок
 
Сообщения: 36
Зарегистрирован: 07.02.2007 (Ср) 9:17

Re: Как работать с "чужой" прогой не вручную.

Сообщение mZone » 24.10.2008 (Пт) 8:41

GDK писал(а):1. Никто не пробовал сделать что - либо подобное?

Я пробовал :) И даже успешно получалось 8) Стучи в личку, если что

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 24.10.2008 (Пт) 13:18

Почитал немного из справки по nnCron. Понравилось и скорее всего пригодится. Только вот непонятно что значит "запускать произвольные программы как сервисы". Это как дочерние окна что ли или что то большее?

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

Re: Как работать с "чужой" прогой не вручную.

Сообщение alibek » 24.10.2008 (Пт) 13:29

Нет, это сервисы Windows. Которые, в частности, работают до входа пользователя в систему.
Lasciate ogni speranza, voi ch'entrate.

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 24.10.2008 (Пт) 16:11

Мда :? Придётся делать свою прогу, а nnCron может быть получится использовать из под неё.
Не против если я тут бубу продолжать тему - в смысле писать о результатах и может быть задавать вопросы по API, которые необходимо будет применять для решения задачи? Думаю будет интересно многим т.к. мало инф. на эту тему.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как работать с "чужой" прогой не вручную.

Сообщение iGrok » 24.10.2008 (Пт) 19:25

GDK писал(а):Не против если я тут бубу продолжать тему - в смысле писать о результатах и может быть задавать вопросы по API, которые необходимо будет применять для решения задачи? Думаю будет интересно многим т.к. мало инф. на эту тему.

Для этого и существует этот форум.. )
label:
cli
jmp label

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Как работать с "чужой" прогой не вручную.

Сообщение GDK » 17.11.2008 (Пн) 17:03

Ну, половина дела сделана. Получилось управлять ComboBox-ми, TrackBar-ми, менюхой. Удалось закрывать приложение, хотя оно выдает диалоговые окна. Полосы прокрутки пока не трогал, но скорее всего, получить над ними контроль тоже получится без особых проблемм. TrackBar-ми и менюхой получилось управлять при помощи сообщений.
Вопросы с которыми сам вряд ли разберусь быстро (нужна помощь):
1. Как отключать кнопки системного меню? (Получилось затемнить кнопку "Закрыть" но сути как это происходит - не понял. С остальными кнопками - также сделать не получается и в имеющейся литературе по этому поводу ничё не нарыл).
2. Решил сделать для управления элементами чужой программой - классы.
Наткнулся на вопрос: Как сделать типа Application.TrackBars(1).position=222, где Application-объект главного окна приложения; TrackBars(1)-объект трекбара; position-св-во трекбара. Написать класс для Application-не проблема, TrackBar-тоже не проблема, написать св-во для класса тоже не проблема, а вот именно реализовать обращение Application.TrackBars(1).position=222 - Никак не разберусь.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как работать с "чужой" прогой не вручную.

Сообщение iGrok » 17.11.2008 (Пн) 18:26

GDK писал(а):Наткнулся на вопрос: Как сделать типа Application.TrackBars(1).position=222, где Application-объект главного окна приложения; TrackBars(1)-объект трекбара; position-св-во трекбара. Написать класс для Application-не проблема, TrackBar-тоже не проблема, написать св-во для класса тоже не проблема, а вот именно реализовать обращение Application.TrackBars(1).position=222 - Никак не разберусь.

К примеру, в классе Application объявляешь Public TrackBars As Collection, потом при создании классов для контрола кидаешь в эту коллекцию класс, работающий с конкретным контролом.

Либо, как вариант, создаёшь приватную коллекцию, и делаешь в классе доступ к ней через Property Get.
label:
cli
jmp label

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Как работать с "чужой" прогой не вручную.

Сообщение Twister » 18.11.2008 (Вт) 7:07

2. На каком яз. написана - не знаю.
А это бы существенно облегчило тебе жизнь. ;) PEiD, LordPE, PE Tools тебе помогут.
1. Как отключать кнопки системного меню?
DeleteMenu() - просто удалить соответствующий пункт меню, так же, как и с кнопкой закрыть.

ЗЫ. Данные из гридов читать не собираешься, случаем? :lol:
А я все практикую лечение травами...

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 18.11.2008 (Вт) 18:25

Насчёт коллекций вроде как понятно. Только вот не понял что значит "потом при создании классов для контрола кидаешь в эту коллекцию класс, работающий с конкретным контролом." То есть будет что то типа:

Код: Выделить всё
Dim UserApp as new Application ' класс Application уже написан и  коллекция TrackBars в нём есть.
Dim TrBrVert as TrackBar  ' класс TrackBar  написан

call  UserApp.TrackBars.Add(TrBrVert )

UserApp.TrackBars(1).Position=500 'это -  например


Да?

При этом при написании строки
Код: Выделить всё
UserApp.TrackBars(1).Position=500 

IDE (VBA-шная, хотя это без разницы наверное) не будет автоматически добалять после написания "UserApp.TrackBars(1)." слово pisition (конечно это св-во я написать позаботился)? Можно ли сделать чтобы добавляла?
Пробовал объявить в классе "Application" public TrackBarVert as TrackBar. Не добавляет IDE автоматически св-ва для TrackBarVert.

Насчёт DeleteMenu() думал что она только для несистемного меню. Попробую найти её описание на русском.

Из гридов не считывал и пока, слава Богу, не собираюсь. Но способ, "описанный в ссылке", прочитал и понял что это тяжело (считывать из гридов). У меня пока для этого недостаточно знаний и понимания работы компа и ОС.

Как может помочь знание языка, на котором написано "чужое" App? Всё равно никаких языков кроме VB не знаю, ну разве что по СИ++ кое что кое как получалось (вывести на экран - в чёрном окошке, какой нибудь текст).

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как работать с "чужой" прогой не вручную.

Сообщение iGrok » 18.11.2008 (Вт) 18:42

Ну тогда второй вариант. Я его тоже описывал. )

На картинке - он показан в действии.

Если уж ты делаешь объект Application с классами - то пусть он за инициализацию и отвечает.
Т.е. пусть классы для контролов создаются и кидаются в коллекцию при инициализации Application.
Вложения
classcollection.JPG
classcollection.JPG (35.13 Кб) Просмотров: 6448
label:
cli
jmp label

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 19.11.2008 (Ср) 19:28

Ну вот. Разобрался. Причём наврал я про IDE. Извиняюсь за это. Похоже, просто в прошлый раз, где - нибудь сам накосячил.
iGrok, большое спасибо что помог.
Насчёт "системного" меню тоже разобрался. Оказалось что "чужая" программа из системного меню оставляет при загрузке только кн. "Закрыть", а кн. "свернуть" и "восстановить" видимо делает сама (причём по внешн. виду точно такие же как аналогично действующие кнопки системного меню. Про функцию DeleteMenu() - она сделала недоступной кнопку "Закрыть", но не удалила её из заголовка окна.

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 08.12.2008 (Пн) 18:12

Вновь прошу помощи уже по более конкретным вещам. 1. В "чужой" проге есть меню, в котором некоторые пункты отмечаются (или не отмечаются) галочкой. С помощью функции API GetMenuState() хотел узнавать отмечен пункт или нет. Но почему то она возвращает 0 независимо от состояния пункта меню. Пробовал по разному получить состояние - по Hwnd пункта и по его ID. Не получается. В переведённом описании GetMenuState() сказано что она должна возвращать комбинацию флагов. 2. Не могу разобраться как работать с контролом, у которого имя класса SysListView32 . А именно как выудить текст из выделенной строки (или не только из выделенной) и как узнать какая иконка присвоена данной строчке этого списка (SysListView32). Пока получилось только узнать сколько строчек содержится в окне контрола. Если есть примеры - напишите пожалуйста, а то в интернете нашёл штук пять примеров но все они либо не на VB, либо для других целей (напр. изменение фона иконок на рабоч. столе).

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 10.12.2008 (Ср) 13:50

C меню разобрался. С помощью API Guide, хотя он и на англ., зато там есть примеры, из которых понятно хотябы типы данных. Для того чтобы узнать отмечен галочкой пункт меню или нет пришлось воспользоваться функцией GetMenuItemInfo(). :) А вот функция GetMenuState() в API Guide, который уменя установлен, отсутствует. :( Хотя и разобрался с меню, это не помогло в работе с "чужой" прогой. :( Меню в ней обновляет состояние пунктов только когда пользователь раскрывает меню. А я не хочу чтобы мой макрос открывал окна меню только для выяснения "отмеченности" его пункта. Придётся работать с окном, у которого класс "ToolbarWindow32". Нет у кого-нибудь примеров для работы с такими окнами? Или хотя бы подскажите где искать инфу и какие функции будут нужны.

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 16.12.2008 (Вт) 18:07

Примеры для ToolbarWindow32 нашёл на этом сайте в одном из форумов. Причём искал через Google TB_PRESSBUTTON. Пример проверил, он оказался рабочим но с недостатками. Всё работает если код расположен в форме (работаю в VBA Word). При попытке перенести код в стандартный модуль или в модуль класса ничего не выходит. В той же теме говорилось, что кнопки на ToolbarWindow32 не имеют HWnd или хорошо запрятаны. При поисках по интернету наткнулся на какой то форум, где было выяснено при экспериментировании, что поле dwData структуры TBBUTTON содержит в первых четырёх байтах HWnd кнопки. А в MSDN про это типа не сказано. Правда форум был то ли С то ли Delpfi то ли ещё что. Короче разобраться не получилось.

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 28.01.2009 (Ср) 13:43

Благодаря некоторым людям разобрался в некоторых вопросах по ToolBar(ам) и строчкам состояния. Так что если кому интересно.....

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 09.02.2009 (Пн) 19:03

Теперь остались три вопроса.
1. Надо вытащить из окна SysListView32 все надписи. Пробовал LVM_GETITEMTEXTA с выделением памяти в чужом процессе и последующим чтением в свою переменную. Не помогает. Т.е. вроде бы что то считывает (ну, например, номер Item(a) выдаётся правильный), но текст отсутствует. Hwnd окна правильный т.к. количество строчек получить удалось (несложно это было).
2. Надо вытащить оттуда же информацию об иконке к-либо элемента (скопировать, если удастся, эту иконку), да и вообще всю инф. об к-либо элементе. Не пробовал пока ничё. Сложно. Да и не обязательно. Это надо просто для косвенной "защиты от дурака".
3. Считать значения переменных чужой проги из памяти её процесса. В общем всё про это: как найти, считать, заменить и т.п. Адреса этих переменных могут меняться в процессе работы чужой проги? Сам думаю что могут. Это вопрос просто ради спортивного интереса и общего развития.

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

Re: Как работать с "чужой" прогой не вручную.

Сообщение tyomitch » 10.02.2009 (Вт) 0:43

Специалисты по телепатической отладке, из-за кризиса, в бессрочном отпуске.
Подставляй свой код.
Изображение

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 11.02.2009 (Ср) 13:34

С некоторых пор решил оформлять работу в виде классов. Поэтому выложу код всего модуля класса. Процедура называется ATest.
Код: Выделить всё
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'Напpавляет сообщение окну пpикладной задачи.
'Паpаметpы:
     'Wnd: Окно, котоpое будет пpинимать сообщение, или $FFFF для всех пеpекpываемых или всплывающих окон.
     'Msg: Тип сообщения.
     'wParam: Дополнительная инфоpмация о сообщении.
     'lParam: Дополнительная инфоpмация о сообщении.
'Возвpащаемое значение:
     'Не нуль в случае успешного завеpшения; 0 - если нет.
Private Const WM_COMMAND = &H111
Private Const LVM_FIRST As Long = &H1000
Private Const LVM_GETHOTITEM As Long = (LVM_FIRST + 61)
Private Const LVM_GETITEMCOUNT As Long = (LVM_FIRST + 4)
Private Const LVM_GETITEMSTATE As Long = (LVM_FIRST + 44)
Private Const LVM_GETSELECTEDCOUNT As Long = (LVM_FIRST + 50)
Private Const LVM_GETSELECTIONMARK As Long = (LVM_FIRST + 66)
Private Const LVM_GETTOPINDEX As Long = (LVM_FIRST + 39)
Private Const LVM_GETITEMTEXTA As Long = (LVM_FIRST + 45)
Private Const LVM_GETITEMTEXTW As Long = (LVM_FIRST + 115)


Private Const LVIS_SELECTED As Long = &H2
Private Const LVIF_TEXT As Long = &H1




Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hWnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpAddress As Any, ByRef dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpBaseAddress As Any, ByRef lpBuffer As Any, ByVal nSize As Long, ByRef lpNumberOfBytesWritten As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpAddress As Any, ByRef dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long


Private Const WM_USER As Long = &H400
Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000
Private Const SYNCHRONIZE As Long = &H100000
Private Const PROCESS_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF)
Private Const PROCESS_DUP_HANDLE As Long = (&H40)
Private Const MEM_COMMIT As Long = &H1000
Private Const MEM_TOP_DOWN As Long = &H100000
Private Const PAGE_READWRITE As Long = &H4
Private Const TB_GETBUTTON As Long = (WM_USER + 23)
Private Const MEM_RELEASE As Long = &H8000



Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As Long, ByRef lpRect As RECT) As Long



Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type LVITEM
    mask As Long
    iItem As Long
    iSubItem As Long
    state As Long
    stateMask As Long
    pszText As String
    cchTextMax As Long
    iImage As Long
    lParam As Long
    iIndent As Long
End Type


Dim HWndGNm As Long
Dim HWndObjm As Long



Public Function InitObjectGN(HWndGNp As Long) 'Эта ф-ция специально для родительского окна.
'Её цель - получить хендл окна списка SysListView32 и записать в этот объект хендл родительского окна списка.
Dim FObjf As New FGDK
Dim HWndGNf As Long
Dim GNWinArrf() As Long

HWndGNf = HWndGNp
HWndGNm = HWndGNf

GNWinArrf() = FObjf.GetGNChWind(HWndGNf)
HWndObjm = GNWinArrf(14)
Set FObjf = Nothing
End Function

Public Function InitSLV32(HWndLV As Long) '
HWndObjm = HWndLV
End Function


Public Property Get GetWinTop() As Long
Dim GNRectf As RECT
Call GetWindowRect(HWndObjm, GNRectf) 'Получаем прямоугольник окна списка
GetWinTop = GNRectf.Top
End Property
Public Property Get GetWinBottom() As Long
Dim GNRectf As RECT
Call GetWindowRect(HWndObjm, GNRectf) 'Получаем прямоугольник окна списка
GetWinBottom = GNRectf.Bottom
End Property
Public Property Get GetWinLeft() As Long
Dim GNRectf As RECT
Call GetWindowRect(HWndObjm, GNRectf) 'Получаем прямоугольник окна списка
GetWinLeft = GNRectf.Left
End Property
Public Property Get GetWinRight() As Long
Dim GNRectf As RECT
Call GetWindowRect(HWndObjm, GNRectf) 'Получаем прямоугольник окна списка
GetWinRight = GNRectf.Right
End Property

Public Property Get GetWinWidth() As Long
Dim GNRectf As RECT
Call GetWindowRect(HWndObjm, GNRectf) 'Получаем прямоугольник окна списка
GetWinWidth = GNRectf.Right - GNRectf.Left
End Property
Public Property Get GetWinHeigt() As Long
Dim GNRectf As RECT
Call GetWindowRect(HWndObjm, GNRectf) 'Получаем прямоугольник окна списка
GetWinHeigt = GNRectf.Bottom - GNRectf.Top
End Property

Public Property Get GetHWndTrNameList() As Long
GetHWndTrNameList = HWndObjm
End Property

Public Property Get GetHWndGN() As Long
GetHWndGN = HWndGNm
End Property

Public Property Get GetItemCount() As Long
Dim i As Long
i = SendMessage(HWndObjm, LVM_GETITEMCOUNT, 0, 0)
GetItemCount = i
End Property


Public Property Get ATest()
Dim i As Long
Dim BufStr As String

'i = SendMessage(HWndObjm, LVM_GETITEMSTATE, 1, LVIS_SELECTED)
'Debug.Print i & " - HHHHH"
   Dim rwb As Long
   Dim procidf As Long
   Dim hProcess As Long
   Dim L As Long
   Dim prc As Long ' указатель на выделенную память
   Dim s() As Byte
   Dim BufLV As LVITEM
   Dim RezLV As LVITEM

BufLV.mask = 1
BufLV.cchTextMax = 255
BufLV.iSubItem = 3
BufLV.stateMask = LVIS_SELECTED

    HWndStBrf = HWndObjm
'Exit Property
   Call GetWindowThreadProcessId(HWndObjm, procidf) ' найти PID окна

   hProcess = OpenProcess(PROCESS_ALL_ACCESS Or PROCESS_DUP_HANDLE, True, procidf) ' получить хендл процесса

   prc = VirtualAllocEx(hProcess, 0, LenB(BufLV), MEM_COMMIT Or MEM_TOP_DOWN, PAGE_READWRITE) 'выделить память для LVItem

   Call SendMessage(HWndObjm, LVM_GETITEMTEXTA, 1, prc) 'Попытка выдернуть текст

   Call ReadProcessMemory(hProcess, prc, BufLV, LenB(BufLV), rwb) 'прочитать LVItem из памяти

   Call VirtualFreeEx(hProcess, prc, LenB(BufLV), MEM_RELEASE) 'освободить память

   Call CloseHandle(hProcess) 'Закрыть доступ к процессу

End Property



Нашел статью об этом в "поиске гуглей". Правда она для делфи, а я с ним не служил :lol: .
Из неё понял, что надо:
Выделить память в чужом процессе не только для переменной (структуры LVITEM), но кроме того уже в памяти чужого процесса заполнить некоторые "поля" этой структуры (чтобы посылаемое сообщение выбрало именно текст итема); ещё тоже в памяти чужого процесса выделить память для приёма текста. И вот потом уже посылать GETITEMTEXT. Не пойму как заполнить структуру в чужом процессе. И ещё никак не разберусь что всё таки должно содержаться в структуре LVITEM в поле pszText . В APIViewer2004 написано что pszText as String, значит текст должен содержаться? A из MSDN понял (с моим незнанием англ.) что вроде как в pszText должен содержаться указатель на часть памяти, в которой хранится текст итема. Ну и разок встречал, объявление структуры LVITEM , где pszText as Long. Так текст или указатель :? ???

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

Re: Как работать с "чужой" прогой не вручную.

Сообщение tyomitch » 11.02.2009 (Ср) 18:31

GDK писал(а):С некоторых пор решил оформлять работу в виде классов. Поэтому выложу код всего модуля класса. Процедура называется ATest.

добавь ещё класс FGDK, иначе не дебажится

GDK писал(а):Из неё понял, что надо:
Выделить память в чужом процессе не только для переменной (структуры LVITEM), но кроме того уже в памяти чужого процесса заполнить некоторые "поля" этой структуры (чтобы посылаемое сообщение выбрало именно текст итема); ещё тоже в памяти чужого процесса выделить память для приёма текста. И вот потом уже посылать GETITEMTEXT. Не пойму как заполнить структуру в чужом процессе. И ещё никак не разберусь что всё таки должно содержаться в структуре LVITEM в поле pszText . В APIViewer2004 написано что pszText as String, значит текст должен содержаться? A из MSDN понял (с моим незнанием англ.) что вроде как в pszText должен содержаться указатель на часть памяти, в которой хранится текст итема. Ну и разок встречал, объявление структуры LVITEM , где pszText as Long. Так текст или указатель :? ???

Там указатель.
Всегда, когда в UDT объявлено As String, это там указатель.

Заполнять память через WriteProcessMemory
Изображение

GDK
Обычный пользователь
Обычный пользователь
 
Сообщения: 80
Зарегистрирован: 23.10.2008 (Чт) 16:15

Re: Как работать с "чужой" прогой не вручную.

Сообщение GDK » 12.02.2009 (Чт) 16:57

Получилось вытянуть текст итемов! :alien:
Нашёл исходный текст на одном из английских форумов. Там был модуль полностью предназначенный для извлечения текста итема. В нём были все декларации API, константы, структуры. Скопировал этот модуль. Попробовал. Не получилось. Удалил модуль не разбираясь в нём, но запомнил из него некоторые детали. После прочитанной статьи по делфи решил сначала перевести её код на VB (в меру своего понимания). При попытке это сделать вдруг вспомнил про англ. модуль и понял, что он весьма похож на код из статьи. Решил отталкиваться от него. Короче решил выяснить почему он не работает. И оказалось - в нём была забыта константа LVM_GETITEMTEXT, ну и OPTION EXPLICIT не стоял. Объявил LVM_GETITEMTEXT и всё заработало. ВО БЛИН! Ну решил на основе его изменить процедуру в приведённом выше классе. А там у меня уже были объявления многих API, ну я и дополнил только те, которых не было. Причём недостающие скопировал из того рабочего модуля. Попробовал. Не работает. Начал выяснять. При выделении памяти VirtualAllocEx возвращает ноль, а в рабочем модуле число из нескольких знаков. Скопировал из рабочего модуля декларацию VirtualAllocEx. Пробую. Получаю результат, отличный от нуля, при выделении памяти. Текст не вытягивается. Ну после такого конечно же решил удалить все свои декларации и заменить их копиями из рабочего модуля. Всё заработало как надо!!!! А свои декларации брал из АПИ вьювера2004. :x
Вот такие приключения с выдёргиванием текста из SysListView32.
Короче если кому интересно, могу переписать код в виде класса, который будет работать с окном SysListView32. Есть к-нибудь советы по поводу того каким лучше сделать код? В интернете находил несколько программ, выдёргивающих текст из листбоксов и все в виде .ехе и ни одной в виде класса или dll. И ещё. Теперь собираюсь извлекать иконки из итемов. Алгоритм будет примерно тем же?

Tyomitch, спасибо. А можно поподробнее про
Всегда, когда в UDT объявлено As String, это там указатель.
Что значит всегда и что значит UDT.

Для меня это значит:
Всегда, когда в к-либо структуре объявлено As String, это там указатель.
Но здравый смысл подсказывает, что я всё неправильно понял.

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Как работать с "чужой" прогой не вручную.

Сообщение iGrok » 12.02.2009 (Чт) 17:52

GDK писал(а):Для меня это значит:
Всегда, когда в к-либо структуре объявлено As String, это там указатель.
Но здравый смысл подсказывает, что я всё неправильно понял.

Всё ты правильно понял. =)
UDT - User Defined Type. Вот это: Public Type blablabla ... End Type
label:
cli
jmp label


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

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

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

    TopList