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

Вниз

Ошибка с LISTVIEW   Найти похожие ветки 

 
Дубинка   (2006-02-19 20:46) [0]

var
 h1, h2, h3: HWND;
 lvFindInfo: LV_FINDINFO;

 h1 := FindWindow(nil, "Диспетчер задач Windows");
 h2 := FindWindowEx(h1, 0, nil, "");
 h3 := FindWindowEx(h2, 0, "SysListView32", "Процессы");
 ListView_FindItem(h3, -1, lvFindInfo);


Конечно понять для чего нужен этот код просто, я думаю, но вот понять почему он не канает - диспетчер задач завершается ошибкой - у меня мозгов не хватает понять....


 
begin...end ©   (2006-02-19 21:11) [1]

> Дубинка   (19.02.06 20:46)
> ListView_FindItem(h3, -1, lvFindInfo)

Здесь третьим параметром фактически передаётся указатель на структуру типа LV_FINDINFO, расположенную в памяти Вашего процесса. Оконная процедура "чужого" ListView"а, получив сообщение LVM_FINDITEM, а в качестве его параметра -- этот указатель, будет рассматривать последний как адрес структуры в адресном пространстве своего процесса. А там такой структуры нет -- отсюда и ошибка.


 
Дубинка   (2006-02-19 22:09) [2]

хе-хе.... я сразу почему-то до этого не допер(ла)....
Я вообще ноль в работе с чужими приложениями... по сути как засунуть по данному адресу во вражеский процесс пару байт я знаю, а вот как найти "чистый" кусок памяти для этого? ну чтоб я ему ничего не испортил... Ну и как соответственно отметить это самое изменение вы мне не подскажите?


 
Хинт ©   (2006-02-20 08:56) [3]

Вот кусок кода из одного моего проекта. Немного модифицировать и...
procedure GetText(ListWND: HWND; Lines: TStrings);
const
 PROCESS_ACCESS = PROCESS_VM_OPERATION or PROCESS_VM_READ or
   PROCESS_VM_WRITE;
type
 PProcData = ^TProcData;
 TProcData = record
   Item: TLVItemA;
   Txt: packed array[0..1023] of AnsiChar;
   ItemRect: TRect;
 end;
var
 Cnt, I,J: Integer;
 ProcID: DWORD;
 ProcessHandle: THandle;
 Data: TProcData;
 RemoteProcData: PProcData;
 Res: Boolean;
 LI: TListItem;
 ColWid: Integer;
 pt: TPoint;
 List:Array of record
   count,item:string;
   end;
begin
 ProcID := 0;
 GetWindowThreadProcessId(ListWND, ProcID);
 if ProcId = 0 then
 begin
   MessageDlg("Cannot retrieve process ID.", mtError, [mbOK], 0);
   Exit;
 end;

 ProcessHandle := OpenProcess(PROCESS_ACCESS, False, ProcID);
 if ProcessHandle = 0 then RaiseLastOSError;
 try
   RemoteProcData := VirtualAllocEx(ProcessHandle, nil,
     SizeOf(RemoteProcData^), MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
   if RemoteProcData = nil then RaiseLastOSError;
   try
     Cnt := ListView_GetItemCount(ListWND);
     setlength(list,cnt);
     Lines.Clear;
     for I := 0 to Cnt - 1 do for j:=0 to 1 do
     begin
       FillChar(Data, SizeOf(Data), 0);
       with Data.Item do
       begin
         iSubItem := j;
         pszText := @RemoteProcData^.Txt;
         cchTextMax := SizeOf(RemoteProcData^.Txt) - 1;
       end;

       Res := WriteProcessMemory(ProcessHandle, RemoteProcData,
         @Data, SizeOf(Data), PLongWord(nil)^);
       if not Res then RaiseLastOSError;

       SendMessage(ListWND, LVM_GETITEMTEXT, I, LPARAM(@RemoteProcData^.Item));

       SendMessage(ListWND, LVM_GETITEMRECT, I, LPARAM(@RemoteProcData^.ItemRect));

       Res := ReadProcessMemory(ProcessHandle, RemoteProcData,
         @Data, SizeOf(Data), PLongWord(nil)^);
       if not Res then RaiseLastOSError;

       if j=0 then List[i].item:=data.Txt else
         begin
          List[i].count:=data.txt;
          Lines.Add(List[i].item+" - "+List[i].count);
         end;

     end;
   finally
     Res := LongBool(VirtualFreeEx(ProcessHandle, RemoteProcData,
       0, MEM_RELEASE));
     if not Res then RaiseLastOSError;
   end;
 finally
   CloseHandle(ProcessHandle);
 end;
end;


 
begin...end ©   (2006-02-20 08:59) [4]

> Дубинка   (19.02.06 22:09) [2]

Находить чистые куски самостоятельно не придётся. Нужно запросить нужный объём памяти в чужом процессе (предварительно получив дескриптор процесса) с помощью функции VirtualAllocEx, передав ей в качестве второго параметра (желаемого начального адреса региона) 0 -- это означает, что функция выделит память там, где посчитает нужным.

Если функция отработает успешно, она вернёт значение, отличное от нуля -- базовый адрес выделенной памяти в адресном пространстве чужого процесса. Теперь по этому адресу можно записывать то, что Вам нужно. Конкретно для данного примера нужно будет записать, во-первых, саму структуру LV_FINDINFO. Во-вторых, если предполагается использовать тип поиска LVFI_STRING (т.е. поиск элементов, заголовки которых полностью или частично совпадают с некоторой указанной строкой), то в LV_FINDINFO нужно будет инициализировать поле psz, а именно -- поместить туда указатель на строку-образец. Причём этот указатель тоже должен быть действителен именно в чужом процессе. А значит, выделять память в нём нужно не только под структуру LV_FINDINFO, но и под строку.

ОК, теперь память выделена, в неё записаны строка и структура LV_FINDINFO . Вот теперь можно посылать LVM_FINDITEM (или использовать ListView_FindItem), причём это уже можно делать из своего процесса.

А после того, как сообщение будет обработано, выделенную "чужую" память надо освободить (если она больше не понадобится).



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

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

Наверх




Память: 0.47 MB
Время: 0.01 c
2-1145272457
Сергей И
2006-04-17 15:14
2006.05.14
работа с DBgrid


15-1145357489
WondeRu
2006-04-18 14:51
2006.05.14
Хочу воспользоваться оператором GOTO,


2-1146065265
tio
2006-04-26 19:27
2006.05.14
AddIndex


15-1145188119
Tirael
2006-04-16 15:48
2006.05.14
вход


2-1146048913
Meganop
2006-04-26 14:55
2006.05.14
Вызов exe





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский