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

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

Вот запарка мож кто заметит в чем проблема... [D6, Win2k]


Olorin ©   (2002-09-04 15:37:00) 

При вызове этой ф-ии возникает екзепшен в вызываюшей строке
Invalid variant operation как побороть да и почему?


function UOReadCharasterInfo(ProcHWND: HWND; Stat: TUOCharasterInfo): variant;
var
BytesRead: DWORD;
UOProcID: DWORD;
PtrToCharaster: DWORD;
PtrJournal: DWORD;
CharasterInfo: DWORD;
PtrTmp: DWORD;
PtrNxt: DWORD;
ProcHandle: THandle;
buff: array [0..13] of Char;
StrTmp: array[1..255] of Char;
Res: Variant;
begin
PtrToCharaster := $00C26164;
PtrJournal := $00D16B8C;
PtrNxt := 0;
UOProcID := 0;
BytesRead := 0;

GetWindowText(ProcHWND, buff, 14);
if (ProcHWND <> 0) and (StrPas(buff) = "Ultima Online") then begin
GetWindowThreadProcessId(ProcHWND, @UOProcID);
ProcHandle := OpenProcess(PROCESS_VM_READ, True, UOProcID);
ReadProcessMemory(ProcHandle, Ptr(PtrToCharaster), @CharasterInfo, 4, BytesRead);
case Stat of
CNAME: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $A4), @Res, 30, BytesRead);
STRN: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C4), @Res, 2, BytesRead);
DEXT: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C6), @Res, 2, BytesRead);
INTL: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C8), @Res, 2, BytesRead);
HITS: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $CA), @Res, 2, BytesRead);
STAM: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $CE), @Res, 2, BytesRead);
MANA: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $D2), @Res, 2, BytesRead);
GOLD: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $D8), @Res, 4, BytesRead);
ARM: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $DC), @Res, 2, BytesRead);
WEIGHT: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $DE), @Res, 2, BytesRead);
LASTMSG: begin
ReadProcessMemory(ProcHandle, Ptr(PtrJournal), @PtrTmp, 4, BytesRead);
while PtrTmp <> 0 do begin
PtrNxt := PtrTmp + $18;
ReadProcessMemory(ProcHandle, Ptr(PtrNxt), @PtrTmp, 4, BytesRead);
end;
ReadProcessMemory(ProcHandle, Ptr(PtrNxt - $18), @PtrTmp, 4, BytesRead);
ReadProcessMemory(ProcHandle, Ptr(PtrTmp), @StrTmp, 255, BytesRead);
Result := LowerCase(Trim(StrTmp));
end;
end;
CloseHandle(ProcHandle);
Result := Res;
end
else begin
Result := False;
exit;
end;
end;


Olorin   (2002-09-05 13:27:00) [1]

И вся нелегкая! :o))

Спасибо всем кто помог мне и не бросил "в беде" :o)


function UOReadCharasterInfo(ProcHWND: HWND; Stat: TUOCharasterInfo): Variant;
var
BytesRead: DWORD;
UOProcID: DWORD;
PtrToCharaster: DWORD;
PtrJournal: DWORD;
CharasterInfo: DWORD;
PtrTmp: DWORD;
PtrNxt: DWORD;
ProcHandle: THandle;
buff: array [0..13] of Char;
StrTmp1: array[1..30] of Char;
StrTmp2: array[1..255] of Char;
Res: Variant;
begin
PtrToCharaster := $00C26164;
PtrJournal := $00D16B8C;
PtrNxt := 0;
UOProcID := 0;
BytesRead := 0;

GetWindowText(ProcHWND, buff, 14);
if (ProcHWND <> 0) and (StrPas(buff) = "Ultima Online") then begin
GetWindowThreadProcessId(ProcHWND, @UOProcID);
ProcHandle := OpenProcess(PROCESS_VM_READ, True, UOProcID);
ReadProcessMemory(ProcHandle, Ptr(PtrToCharaster), @CharasterInfo, 4, BytesRead);
case Stat of
CNAME: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $A4), @StrTmp1, 30, BytesRead);
Result := Trim(StrTmp1);
end;
STRN: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C4), @Res, 2, BytesRead);
Result := Res;
end;
DEXT: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C6), @Res, 2, BytesRead);
Result := Res;
end;
INTL: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C8), @Res, 2, BytesRead);
Result := Res;
end;
HITS: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $CA), @Res, 2, BytesRead);
Result := Res;
end;
STAM: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $CE), @Res, 2, BytesRead);
Result := Res;
end;
MANA: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $D2), @Res, 2, BytesRead);
Result := Res;
end;
GOLD: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $D8), @Res, 4, BytesRead);
Result := Res;
end;
ARM: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $DC), @Res, 2, BytesRead);
Result := Res;
end;
WEIGHT: begin
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $DE), @Res, 2, BytesRead);
Result := Res;
end;
LASTMSG: begin
ReadProcessMemory(ProcHandle, Ptr(PtrJournal), @PtrTmp, 4, BytesRead);
while PtrTmp <> 0 do begin
PtrNxt := PtrTmp + $18;
ReadProcessMemory(ProcHandle, Ptr(PtrNxt), @PtrTmp, 4, BytesRead);
end;
ReadProcessMemory(ProcHandle, Ptr(PtrNxt - $18), @PtrTmp, 4, BytesRead);
ReadProcessMemory(ProcHandle, Ptr(PtrTmp), @StrTmp2, 255, BytesRead);
Result := LowerCase(Trim(StrTmp2));
end;
end;
CloseHandle(ProcHandle);
end
else begin
Result := False;
exit;
end;
end;


Olorin   (2002-09-05 13:21:00) [2]

Упс... сорри... я идиот... ведь LASTMSG так же выбирается...


Dimk   (2002-09-05 12:25:00) [3]

Если уж так надо string
то надо сначала SetLength(Res, 31)
потом читать 30 байт по адресу PChar(Res)

string ( длинная строка по умолчанию ) это указатель
на структурв в памяти:

Pointer(Res)-8 количество ссылок на строку
Pointer(Res)-4 длина строки
Pointer(Res)+0 ASCIIZ строка ограниченная 0 кстати. ( для совместимости с PChar )

Что касается variant - то как правильно сказал(а) ЮЮ
он представляет собой структуру TVarData про которую долго писать а лучше позырить в доке.

А можно вместо строки использовать буфер или array of Char


ЮЮ   (2002-09-05 12:08:00) [4]

SizeOf(String)=4, причем это указатель, который ты портишь.
Можно сделать так
Res: String[255]
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $A4), @Res[0], 30, BytesRead);
SetLength(Res,BytesRead);


Olorin   (2002-09-05 11:58:00) [5]

>ЮЮ
Да но во втором варианте Res: String
Или я что-то не понял??
Феня в том что и с остальными вызовами такая же петрушка!


ЮЮ   (2002-09-05 11:49:00) [6]

SizeOf(Variant)=16
SizeOf(String)=4
A ты по адресу @Res пишешь 30 байт


Olorin   (2002-09-05 11:17:00) [7]

>ЮЮ
Так какой вариант реализации тогда?


ЮЮ   (2002-09-05 09:26:00) [8]

Писать в Res:Stringтакже необдуманно, как и предыдущем варианте
ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $A4), @Res, 30, BytesRead);


Olorin   (2002-09-05 09:08:00) [9]

Изменил код... теперь возвращаемое значение типизированно... вылетает Access violation at address.....


function UOReadCharasterInfo(ProcHWND: HWND; Stat: TUOCharasterInfo): String;
var
BytesRead: DWORD;
UOProcID: DWORD;
PtrToCharaster: DWORD;
PtrJournal: DWORD;
CharasterInfo: DWORD;
PtrTmp: DWORD;
PtrNxt: DWORD;
ProcHandle: THandle;
buff: array [0..13] of Char;
StrTmp: array[1..255] of Char;
Res: String;
begin
PtrToCharaster := $00C26164;
PtrJournal := $00D16B8C;
PtrNxt := 0;
UOProcID := 0;
BytesRead := 0;

GetWindowText(ProcHWND, buff, 14);
if (ProcHWND <> 0) and (StrPas(buff) = "Ultima Online") then begin
GetWindowThreadProcessId(ProcHWND, @UOProcID);
ProcHandle := OpenProcess(PROCESS_VM_READ, True, UOProcID);
ReadProcessMemory(ProcHandle, Ptr(PtrToCharaster), @CharasterInfo, 4, BytesRead);
case Stat of
CNAME: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $A4), @Res, 30, BytesRead);
STRN: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C4), @Res, 2, BytesRead);
DEXT: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C6), @Res, 2, BytesRead);
INTL: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $C8), @Res, 2, BytesRead);
HITS: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $CA), @Res, 2, BytesRead);
STAM: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $CE), @Res, 2, BytesRead);
MANA: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $D2), @Res, 2, BytesRead);
GOLD: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $D8), @Res, 4, BytesRead);
ARM: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $DC), @Res, 2, BytesRead);
WEIGHT: ReadProcessMemory(ProcHandle, Ptr(CharasterInfo + $DE), @Res, 2, BytesRead);
LASTMSG: begin
ReadProcessMemory(ProcHandle, Ptr(PtrJournal), @PtrTmp, 4, BytesRead);
while PtrTmp <> 0 do begin
PtrNxt := PtrTmp + $18;
ReadProcessMemory(ProcHandle, Ptr(PtrNxt), @PtrTmp, 4, BytesRead);
end;
ReadProcessMemory(ProcHandle, Ptr(PtrNxt - $18), @PtrTmp, 4, BytesRead);
ReadProcessMemory(ProcHandle, Ptr(PtrTmp), @StrTmp, 255, BytesRead);
Result := LowerCase(Trim(StrTmp));
end;
end;
CloseHandle(ProcHandle);
Result := Res;
end
else begin
Result := "False";
exit;
end;
end;


Olorin   (2002-09-05 08:58:00) [10]

>ЮЮ
Ставил результат нулевой... пишет variant array of unknown ничего то есть плохого... :o(


ЮЮ   (2002-09-05 08:57:00) [11]

Почитай в Helpe
TVarData type
TVarData represents the internal structure of a Variant variable.
Врядли запись чего-то по адресу @Res обеспечит правильную структуру этого самого Res. Поэтому Result := Res просто обязана говорить Invalid variant operation


ЮЮ   (2002-09-05 08:44:00) [12]

>вызове этой ф-ии возникает екзепшен в вызываюшей строке
А самому слабо точку останова поставить внутри функции?


Olorin   (2002-09-05 08:35:00) [13]

Хм никто не шарит в variant типах? :o(


Olorin   (2002-09-04 15:53:00) [14]

Неужели и Ученика нет чтоб спасти страдающего Ола... :-)


Наверх

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