Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.06.2015, 08:43   #1
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию получить текст из заголовка чужого ListView

не буду многословен, сразу код:
Код:
  hProcess: THandle;
dwProcessID: DWORD;
dwBytesWriten: DWORD;
CloneFrom : hwnd; //хэндл чужого ListView
pszText: PChar;
svText: ShortString;
pRemoteHeaderItem : PHDItemA;
RemoteHeaderItem : _HD_ITEMA;

begin
dwProcessID := 0;
GetWindowThreadProcessId(CloneFrom, @dwProcessID);
if dwProcessID = 0 then Exit;
hProcess := OpenProcess(PROCESS_ALL_ACCESS, True, dwProcessID);
if hProcess = 0 then Exit;
pszText := VirtualAllocEx(hProcess, nil, 254,
MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
premoteheaderitem := VirtualAllocEx(hProcess, nil, SizeOf(phditema),
MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);

                  ZeroMemory(@RemoteHeaderItem, SizeOf(_hd_itema));
                  RemoteHeaderItem.Mask := HDI_TEXT or HDI_WIDTH;
                  RemoteHeaderItem.pszText := pszText;
                  RemoteHeaderItem.cchTextMax := 255;
                  if WriteProcessMemory(hProcess,pRemoteHeaderItem,@RemoteHeaderItem,
                                SizeOf(_hd_itema), dwBytesWriten) then
                  begin
                      header := хэндл заранее известен, ввожу вручную
                    SendMessage(header, HDM_GETITEM, 0, LongInt(@remoteHeaderItem));
                    ZeroMemory(@svText, 255);
                    ReadProcessMemory(hProcess, pszText,
                    @svText[1], 500, dwBytesWriten);
                    t := PChar(@svText[1]);
                    MessageBox(0,PChar(t),'',0);
                  end;
end;
Приходит пустое значение и крашится на MessageBox'e.
BLACK_RAIN вне форума Ответить с цитированием
Старый 30.06.2015, 09:05   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Начните с того, что проверяйте системные вызовы на предмет ошибок.
Например, вы уверены, что память была выделена? А вы уверены, что header получен правильно, что указывает на правильное окно и т.н.
waleri вне форума Ответить с цитированием
Старый 30.06.2015, 09:15   #3
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Начните с того, что проверяйте системные вызовы на предмет ошибок.
GetLastError?
Цитата:
Сообщение от waleri Посмотреть сообщение
Например, вы уверены, что память была выделена? А вы уверены, что header получен правильно, что указывает на правильное окно и т.н.
уверен. Чужой ListView тоже мой и я знаю все хэндлы окон.
Проблема с крашем решена. Я выделял 254 байта, а получал 255.
но всё-равно приходит пустая строка.
BLACK_RAIN вне форума Ответить с цитированием
Старый 30.06.2015, 12:34   #4
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Если память выделена и хэндлы получены правильно, в чем еще может быть дело?
BLACK_RAIN вне форума Ответить с цитированием
Старый 01.07.2015, 09:00   #5
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Попробовал через LVM_GETCOLUMN
Код:
pRemoteColumn := VirtualAllocEx(hProcess, nil, SizeOf(_lv_column),
MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);

                    ZeroMemory(@RemoteColumn, SizeOf(_lv_column));
                    RemoteColumn.mask := LVCF_TEXT or LVCF_WIDTH;
                    RemoteColumn.pszText := pszText;
                    RemoteColumn.cchTextMax := 254;
                  if WriteProcessMemory(hProcess,pRemoteColumn,@RemoteColumn,
                                SizeOf(_lv_column), dwBytesWriten) then
                  begin
                    SendMessage(CloneFrom, LVM_GETCOLUMN,i, LongInt(@RemoteColumn));
                    ZeroMemory(@svtext,255);
                    ReadProcessMemory(hProcess,RemoteColumn.pszText,@svtext[1],255,dwBytesWriten);
                    t := PChar(@svText[1]);
                    MessageBox(0,PChar(t),'',0);
                  end;
всё-равно, для чужого процесса приходит пустое значение.
BLACK_RAIN вне форума Ответить с цитированием
Старый 01.07.2015, 10:19   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Проверяйте системные вызовы на предмет ошибок.
waleri вне форума Ответить с цитированием
Старый 01.07.2015, 10:24   #7
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Проверяйте системные вызовы на предмет ошибок.
Какие вызовы проверить и как? GetLastError не достаточно?
BLACK_RAIN вне форума Ответить с цитированием
Старый 02.07.2015, 03:40   #8
Krasiosoft
Форумчанин
 
Аватар для Krasiosoft
 
Регистрация: 01.06.2015
Сообщений: 497
По умолчанию

Цитата:
Сообщение от BLACK_RAIN Посмотреть сообщение
Какие вызовы проверить и как? GetLastError не достаточно?
Тут проверить можно:

SendMessage() - при HDM_GETITEM, если удача, должен вернуть true, иначе false: msdn.
ReadProcessMemory() - если удача, должен вернуть true.

В случае, если функция завершается неудачно, то смотрите какую ошибку вернет GetLastError().

Цитата:
Сообщение от BLACK_RAIN Посмотреть сообщение
Код:
SendMessage(header, HDM_GETITEM, 0, LongInt(@remoteHeaderItem));
ZeroMemory(@svText, 255);
ReadProcessMemory(hProcess, pszText,
@svText[1], 500, dwBytesWriten);
t := PChar(@svText[1]);
MessageBox(0,PChar(t),'',0);
Приходит пустое значение и крашится на MessageBox'e.
Но скорей всего тут проблема в LongInt(@remoteHeaderItem), ведь Вы передаете указатель на структуру, которая в этой программе, а не в той, которой посылается сообщение. Скорей всего тут нужно так:
Код:
SendMessage(header, HDM_GETITEM, 0, LongInt(pRemoteHeaderItem));
И почему после SendMessage() Вы считываете 500 байт, а не 255? Ведь указывали в структуре:
Код:
RemoteHeaderItem.cchTextMax := 255;
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).
Krasiosoft вне форума Ответить с цитированием
Старый 02.07.2015, 09:42   #9
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
Сообщение от Krasiosoft Посмотреть сообщение
Но скорей всего тут проблема в LongInt(@remoteHeaderItem), ведь Вы передаете указатель на структуру, которая в этой программе, а не в той, которой посылается сообщение.
Спасибо!!! Работает, но только со структурой _LV_COLUMNA.
Цитата:
Сообщение от Krasiosoft Посмотреть сообщение
И почему после SendMessage() Вы считываете 500 байт, а не 255? Ведь указывали в структуре:
Код:
RemoteHeaderItem.cchTextMax := 255;
уже исправил.

p.s. Немного не по теме, но как получить значение поля cx структуры _LV_COLUMNA? Там ширина столбца должна находиться.
BLACK_RAIN вне форума Ответить с цитированием
Старый 02.07.2015, 10:30   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от BLACK_RAIN Посмотреть сообщение
Немного не по теме, но как получить значение поля cx структуры _LV_COLUMNA? Там ширина столбца должна находиться.
Прочитайте pRemoteColumn обратно в свою память и смотрите на cx
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Получить содержимое выделения в текст. редакторе чужого окна без clipboard Foxpronet Общие вопросы Delphi 3 06.03.2015 00:39
Значение свойства Top для заголовка столбца ListView Mishel825 Microsoft Office Excel 0 10.08.2012 00:39
Получить данные с ListView чужого приложения BarsDG Общие вопросы Delphi 2 08.08.2012 13:59
[Проблема] Программное изменение заголовка чужого окна по хендлу процесс(EnumWindows) Человек_Борща Общие вопросы Delphi 8 08.01.2011 22:40
Замена заголовка чужого окна dacorp Общие вопросы Delphi 3 13.06.2010 00:05