Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.01.21;
Скачать: [xml.tar.bz2];

Вниз

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

 
maxistent ©   (2006-08-15 00:00) [0]

Привет всем! Не знаю, куда отнести этот вопрос, так что пишу сюда. В 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.


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


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


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

см. EnumProcesses() (psapi.pas)


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

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


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

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


 
Rouse_ ©   (2006-08-15 10:35) [4]

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

#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>

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;
}


 
maxistent ©   (2006-08-15 12:49) [5]


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


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


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


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


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


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

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


 
Rouse_ ©   (2006-08-15 13:35) [6]

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.


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


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


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

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


 
maxistent ©   (2006-08-15 13:59) [8]

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

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

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


 
Rouse_ ©   (2006-08-15 14:15) [9]


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

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


 
begin...end ©   (2006-08-15 14:19) [10]

> Rouse_ ©   (15.08.06 13:35) [6]

> ReadProcessMemory(hProcess, pszText, @svText[1], nTextLength,
> dwBytesWriten);

Только читать, ИМХО, лучше не из pszText, а по тому адресу, который находится в lviRemoteLVItem.pszText после посылки сообщения.


 
Rouse_ ©   (2006-08-15 14:29) [11]

Да тут роли не играет, согласен :)


 
begin...end ©   (2006-08-15 14:31) [12]

> Rouse_ ©   (15.08.06 14:29) [11]

Я вот о чём:

If the LVIF_TEXT flag is set in the mask member of the LVITEM structure, the pszText member must point to a valid buffer and the cchTextMax member must be set to the number of characters in that buffer. Applications should not assume that the text will necessarily be placed in the specified buffer. The control may instead change the pszText member of the structure to point to the new text, rather than place it in the buffer.


 
Rouse_ ©   (2006-08-15 14:53) [13]

Ооопс, вот на эту строку не обратил внимания. Сенькс, учтем.


 
Медведъъ   (2006-08-15 16:24) [14]

автор читай рихтера
http://c100.rusbook.biz/item_8283.html
а тупо передирая код роуза обезьяне будешь подобен


 
Медведъъ   (2006-08-15 16:26) [15]

ПС
господа власть имущие не утомились медведов регистрировать ?


 
maxistent ©   (2006-08-15 21:01) [16]


> Rouse_ ©   (15.08.06 13:35) [6]


Используя приведенный тобой код я получаю список ярлыков (ну или список процессов из диспетчера задач, т.е. ТОЛЬКО ПЕРВЫЙ СТОЛБЕЦ объекта TListView, если его свойство ViewStyle=vsReport). Их я могу получить более упрощенным способом :-) Мне нужно получить те строки, которые находятся в остальных столбцах!  Т.е. полностью скопировать данные оттуда в свой объект TListView. И совсем не обязательно использовать Диспетчер задач! Это только для проверки, т.к. у него свойство ViewStyle=vsReport, а мне, собственно, это и нужно. Так как мне ЭТО сделать?


 
begin...end ©   (2006-08-15 21:12) [17]

> maxistent ©   (15.08.06 21:01) [16]

> Мне нужно получить те строки, которые находятся в остальных
> столбцах!

Для этого перед посылкой LVM_GETITEMTEXT следует присваивать полю lviRemoteLVItem.iSubItem номер столбца (считая с нуля).


 
maxistent ©   (2006-08-15 23:01) [18]


> begin...end ©   (15.08.06 21:12) [17]

Я пробовал - не получается. Прога вылетает, не успевая ничего сказать. :-(

А есть ли способ получить инфу о процессах так, как это делает тот же Диспетчер задач, т.е. Имя процесса, Имя пользователя, ЦП, Память (столбцы по умолчанию)? И при этом не использовать сам Диспетчер задач? Если да, то лучше подскажите как ЭТО сделать.


 
Rouse_ ©   (2006-08-16 10:09) [19]

Можно, пример у меня на сайте: http://rouse.front.ru/taskmon.zip


 
Сергей М. ©   (2006-08-16 10:19) [20]


> maxistent ©   (15.08.06 23:01) [18]


А что ж ты тогда в [5] "русским по белому" кричал, что список задач тебя не интересует, а ?)


 
Rouse_ ©   (2006-08-16 11:26) [21]


> "русским по белому" кричал

:))))))))))))))))


 
maxistent ©   (2006-08-16 12:19) [22]


> Rouse_ ©   (16.08.06 10:09) [19]

Благодарю за помощь!!! Терь буду знать, к кому обращаться :-)


> А что ж ты тогда в [5] "русским по белому" кричал, что список задач тебя не интересует, а ?)

Да ладно вам! Не кипятитесь. :-) Просто я сначала хотел сделать что-то вроде Диспетчера задач, потом заинтересовался задачей вытягивания инфы из других окон. Ещё раз спасибо Роузу за исходничОк!!! А терь контрольный в голову: Можно ли создавать СВОИ контролы НА ЧУЖИХ?


 
Сергей М. ©   (2006-08-16 12:33) [23]


> контрольный в голову: Можно ли создавать СВОИ контролы НА
> ЧУЖИХ?
>


"НА" - это как ?)


 
maxistent ©   (2006-08-16 21:37) [24]

Ну типа имеется хэндл какого-то окна... Вот. В это какое-то (! ЧУЖОЕ !) окно "засунуть" свой контрол, например кнопку или поле ввода (TEdit). Как это сделать?


 
Сергей М. ©   (2006-08-17 08:40) [25]

Засунуть-то проще простого - установи у своего контрола св-во ParentWindow равным значению хэндла того самого окна.
Только работать твоконтрол не будет при этом. Нужно внедрять код контрола в АП того процесса, который создал то самое окно.


 
maxistent ©   (2006-08-22 02:29) [26]


> Сергей М. ©   (17.08.06 08:40) [25]


Понятно.

Ладно, всем ОГРОМНОЕ спасибо за помощь! Терь, думаю, ветку можно прикрыть.


 
GrayFace ©   (2006-08-25 18:50) [27]

Rouse_ ©   (15.08.06 10:35) [4]
+ для Win9x вместо VirtualAllocEx создавать MMF.

Сергей М. ©   (17.08.06 8:40) [25]
Только работать твоконтрол не будет при этом. Нужно внедрять код контрола в АП того процесса, который создал то самое окно.

Сувать вместе с формой и будет счстье.


 
Сергей М. ©   (2006-08-25 19:10) [28]


> GrayFace ©   (25.08.06 18:50) [27]


Ой)

А форма - она, конечно, не контрол)

"Упалпацтул" (С) Ат падонкафф


 
GrayFace ©   (2006-09-08 15:25) [29]

Сергей М. ©   (25.08.06 19:10) [28]
Говорю, суй с формой и все будет работать. АП тут не при чем.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.01.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.038 c
15-1167192755
Pazitron_Brain
2006-12-27 07:12
2007.01.21
Для владельцев Миранды


3-1162193140
zero-g
2006-10-30 10:25
2007.01.21
Работа с ADO


15-1167746350
ProgRAMmer Dimonych
2007-01-02 16:59
2007.01.21
Смотрю на задачу, как баран на новые ворота...


2-1167517472
rolex
2006-12-31 01:24
2007.01.21
База данных на любом пк


2-1167757954
zol
2007-01-02 20:12
2007.01.21
заблокировать(запретить) ввод в TEdit





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский