Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как получить данные из чужого контрола?


Страницы:   1 2

maxistent ©   (2006-08-15 00:00:00) 

Привет всем! Не знаю, куда отнести этот вопрос, так что пишу сюда. В Win 2000/XP есть такая вещь, как диспетчер задач. В нем на вкладке Процессы есть контрол, очень похожий на TListView. Я могу получить его хэндл:

...
var
w1:hwnd;
...
begin
w1:=FindWindow(nil,PChar(Диспетчер задач Windows'));
w1:=FindWindowEX(w1,0,'#32770','');
w1:=FindWindowEX(w1,0,PChar('SysListView32'),nil);
...
end;


Как мне теперь из этого контрола "вытянуть" данные? (кол-во строк/столбцов, заголовки столбцов, и, собственно, данные из ячеек)
Т.е. мне нужно создать на своей форме такой же контрол (а не его изображение) - объект TListView со свойством ViewStyle=vsReport - с теми же данными.

Буду очень признателен за помощь. С уважением, maxistent.


Rouse_   (2006-08-15 14:15:00) [21]


> Как вытянуть всё остальное?

Я ж тебе показал как вытянуть все остальное, и на дельфи и на Си, что еще не понятно то? :)


maxistent   (2006-08-15 13:59:00) [22]

Ладно, пусть Диспетчер задач будет в качестве испытуемого :-)

Я попробовал получить кол-во элементов списка:
uses CommCtlr,...;
...
i_count:=ListView_GetItemCount(w1);
...

И это все, что я смог получить :-) Как вытянуть всё остальное?
Точнее, СКОПИРОВАТЬ В МОЙ TListView?


Сергей М.   (2006-08-15 13:40:00) [23]


> maxistent ©   (15.08.06 12:49) [5]
>
>
> > Сергей М. ©   (15.08.06 08:35) [1]
>
>
> Мне не нужен список процессов! Я ж русским по белому сказал:
>  ВЫТЯНУТЬ ДАННЫЕ ИЗ ЧУЖОГО КОНТРОЛА.


А к чему тогда Диспетчер задач упомянул ? Всуе ?)
Мало ли какие еще приложения используют SysListView32-контрол !)

Учись обобщать задачу)


Rouse_   (2006-08-15 13:35:00) [24]

program Project20;

{$APPTYPE CONSOLE}

uses
 Windows, CommCtrl;

var
 hwndRemoteSysListView: HWND = 0;
 hProcess: THandle = 0;
 dwProcessID: DWORD = 0;
 dwBytesWriten: DWORD;
 nItemCount: Integer = 0;
 I, nTextLength: Integer;
 cchTextMax: Integer = 255;
 plviRemoteLVItem: PLVItem = nil;
 lviRemoteLVItem: LV_ITEM;
 pszText: PChar = nil;
 svText: ShortString;

function GetFirstChild(hwndValue: HWND): HWND;
begin
 Result := GetWindow(hwndValue, GW_CHILD);
end;

begin
 // Ищем SysListView32 рабочего стола
 hwndRemoteSysListView := GetFirstChild(GetFirstChild(FindWindow('ProgMan', nil)));
 if hwndRemoteSysListView = 0 then ExitProcess(GetLastError);

 // Получаем количество элементов (ярлыков на рабочем столе)
 nItemCount := ListView_GetItemCount(hwndRemoteSysListView);

 // Получаем ID процесса, которому принадлежит найденное окно
 GetWindowThreadProcessId(hwndRemoteSysListView, &dwProcessID);
 if dwProcessID = 0 then ExitProcess(GetLastError);

 // Открываем процесс
 hProcess := OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessID);
 if hProcess = 0 then ExitProcess(GetLastError);

 // Выделяем в нем память под текстовый буффер
 pszText := VirtualAllocEx(hProcess, nil, cchTextMax,
   MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
 if GetLastError 0 then ExitProcess(GetLastError);

 // Выделяем в нем память под структуру LVITEM
 plviRemoteLVItem := VirtualAllocEx(hProcess, nil, SizeOf(LV_ITEM),
   MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
 if GetLastError 0 then ExitProcess(GetLastError);

 // Заполняем структуру
 ZeroMemory(@lviRemoteLVItem, SizeOf(LV_ITEM));
 lviRemoteLVItem.mask := LVIF_TEXT;
 lviRemoteLVItem.pszText := pszText;
 lviRemoteLVItem.cchTextMax := cchTextMax;

 // Пишем ее в память удаленного процесса
 if not WriteProcessMemory(hProcess, plviRemoteLVItem, @lviRemoteLVItem,
  SizeOf(LV_ITEM), dwBytesWriten) then ExitProcess(GetLastError);

 // Получаем текст со всех элементов
 for I := 0 to nItemCount - 1 do
 begin
  // Отправляем сообщение с указателем на выделенный буффер
  nTextLength := SendMessage(hwndRemoteSysListView, LVM_GETITEMTEXT,
   I, Integer(plviRemoteLVItem));

  // Читаем результат
  ZeroMemory(@svText, cchTextMax);
  ReadProcessMemory(hProcess, pszText, @svText[1], nTextLength, dwBytesWriten);

  Writeln(PChar(@svText[1]));

 end;

 // Освобождаем ранее выделенную память
 VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE);
 VirtualFreeEx(hProcess, plviRemoteLVItem, 0, MEM_RELEASE);

 // Закрываем описатель процесса
 CloseHandle(hProcess);

 Readln;
end.


maxistent   (2006-08-15 12:49:00) [25]


> Сергей М. ©   (15.08.06 08:35) [1]


Мне не нужен список процессов! Я ж русским по белому сказал: ВЫТЯНУТЬ ДАННЫЕ ИЗ ЧУЖОГО КОНТРОЛА.


> Медведъ   (15.08.06 08:57) [2]


Где этого "рихтера" взять? :-)


> Rouse_ ©   (15.08.06 10:35) [4]


Я в Сях этих дуб дубом, если честно :-( Может кто сообразит, как переписать на дельфи? Или представит свой вариант?

По-прежнему жду подмоги...


Rouse_   (2006-08-15 10:35:00) [26]

Зачем внедряться то, достаточно простого выделения буффера?
Вот примерчик, сори что на сях, нет времени на дельфи перекидывать:

#include "stdafx.h"
#include
#include
#include

int main(int argc, char* argv[])
{
HWND hwndRemoteSysListView = 0;
HANDLE hProcess = 0;
DWORD dwProcessID = 0, dwBytesWriten;
int nItemCount = 0, I, nTextLength, cchTextMax = 255;
LPLVITEM plviRemoteLVItem = NULL;
LVITEM lviRemoteLVItem;
LPSTR pszText = NULL;
char svText[255];

// Ищем SysListView32 рабочего стола
hwndRemoteSysListView = GetFirstChild(GetFirstChild(FindWindow(__TEXT("ProgMan"), NULL)));
if (!hwndRemoteSysListView) return GetLastError();  

// Получаем количество элементов (ярлыков на рабочем столе)
nItemCount = ListView_GetItemCount(hwndRemoteSysListView);

// Получаем ID процесса, которому принадлежит найденное окно
GetWindowThreadProcessId(hwndRemoteSysListView, &dwProcessID);
if (!dwProcessID) return GetLastError();  

// Открываем процесс
hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessID);
if (!hProcess) return GetLastError();  

// Выделяем в нем память под текстовый буффер
pszText = (LPSTR)VirtualAllocEx(hProcess, NULL, cchTextMax,
 MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE);
if (!GetLastError()) return 10;

// Выделяем в нем память под структуру LVITEM
plviRemoteLVItem = (LPLVITEM)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM),
 MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE);

// Заполняем структуру
ZeroMemory(&lviRemoteLVItem, sizeof(LVITEM));
lviRemoteLVItem.mask = LVIF_TEXT;
lviRemoteLVItem.pszText = pszText;
lviRemoteLVItem.cchTextMax = cchTextMax;

// Пишем ее в память удаленного процесса
if (!WriteProcessMemory(hProcess, plviRemoteLVItem, &lviRemoteLVItem,
 sizeof(LVITEM), &dwBytesWriten)) return GetLastError();  

// Получаем текст со всех элементов
for (I = 0; I < nItemCount; I++)
{
 // Отправляем сообщение с указателем на выделенный буффер
 nTextLength = SendMessage(hwndRemoteSysListView, LVM_GETITEMTEXT,
  I, (LPARAM)plviRemoteLVItem);

 // Читаем результат
 ZeroMemory(&svText, cchTextMax);
 ReadProcessMemory(hProcess, pszText, svText,
           nTextLength, &dwBytesWriten);

 printf(svText);
 printf("\n");

}

// Освобождаем ранее выделенную память
VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, plviRemoteLVItem, 0, MEM_RELEASE);

// Закрываем описатель процесса
CloseHandle(hProcess);

return 0;
}


Ketmar   (2006-08-15 10:00:00) [27]

а после внедрения не забыть почитать справку по API. на предмет общения с List View. %-)


Медведъ   (2006-08-15 08:57:00) [28]

по сабжу нужно внедряться в процесс
пример с рабочим столом есть у рихтера


Сергей М.   (2006-08-15 08:35:00) [29]


> Как мне теперь из этого контрола "вытянуть" данные?


Тот же список процессов можно получить гораздо проще, не столь заумным путем)

см. EnumProcesses() (psapi.pas)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо