![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как получить данные из чужого контрола?
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)