-
> Так точно не получится, надо в другое приложение DLL внедрять
Библиотеку то зачем?
-
> Про маршаллинг сообщений.Некоторые структуры таки оказываются > "чудом" в чужом процессе. Все структуры сообщений, что меньше > WM_USER
Тут как раз таки никакого волшебства, система про эти сообщения знает, знает размер структуры или строки и копирует в адресное пространство все это. В данном случае надо это делать самому, без магии все ручками ИМХО тут WM_COPYDATA лучший вариант
-
Никак не могу понять, чем WM_COPYDATA (будучи упомянутой уже дважды в данной ветке) может помочь при отправке того-же DTM_SETSYSTEMTIME?
-
Rouse_ © (08.04.09 22:31) [22]
> Никак не могу понять, чем WM_COPYDATA (будучи упомянутой > уже дважды в данной ветке) может помочь при отправке того- > же DTM_SETSYSTEMTIME?
ну если DTM_SETSYSTEMTIME не получается, может DateTimePicker на WM_COPYDATA согласится...
-
С WM_COPYDATA у меня таки ничего не получилось. Да даже еслиб и получилось, то как в этом случае быть с TreeView?
-
> даже еслиб и получилось, то как в этом случае быть с TreeView?
а почему тривью должно вдруг обрабатывать wm_copydata?
-
> как в этом случае быть с TreeView?
Вот тебе старый пример работы с CommCtrl окнами в удаленном процессе, делай по аналогии:
program RemoteSysListView32;
uses
Windows,
SysUtils,
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;
ARect: TRect;
pRemoteRect: Pointer = nil;
function GetFirstChild(hwndValue: HWND): HWND;
begin
Result := GetWindow(hwndValue, GW_CHILD);
end;
function Translate(Value: String): String;
begin
SetLength(Result, Length(Value));
AnsiToOem(@Value[1], @Result[1]);
end;
begin
hwndRemoteSysListView := GetFirstChild(GetFirstChild(FindWindow('ProgMan', nil)));
if hwndRemoteSysListView = 0 then ExitProcess(GetLastError);
nItemCount := ListView_GetItemCount(hwndRemoteSysListView);
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);
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);
pRemoteRect := VirtualAllocEx(hProcess, nil, SizeOf(TRect),
MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
if GetLastError <> 0 then ExitProcess(GetLastError);
for I := 0 to nItemCount - 1 do
begin
nTextLength := SendMessage(hwndRemoteSysListView, LVM_GETITEMTEXT,
I, Integer(plviRemoteLVItem));
ZeroMemory(@svText, cchTextMax);
ReadProcessMemory(hProcess, lviRemoteLVItem.pszText,
@svText[1], nTextLength, dwBytesWriten);
ZeroMemory(@ARect, SizeOf(TRect));
ARect.Left := LVIR_ICON;
if not WriteProcessMemory(hProcess, pRemoteRect, @ARect,
SizeOf(TRect), dwBytesWriten) then ExitProcess(GetLastError);
SendMessage(hwndRemoteSysListView, LVM_GETITEMRECT,
I, Integer(pRemoteRect));
ReadProcessMemory(hProcess, pRemoteRect,
@ARect, SizeOf(TRect), dwBytesWriten);
Writeln(Translate(PChar(@svText[1])));
Writeln(Translate(
Format('- координаты: Left = %d, Top = %d, Right = %d, Bottom = %d',
[ARect.Left, ARect.Top, ARect.Right, ARect.Bottom])));
end;
VirtualFreeEx(hProcess, pszText, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, plviRemoteLVItem, 0, MEM_RELEASE);
CloseHandle(hProcess);
Readln;
end.
-
Дело в том, что элементов управления очень много и придется адаптировать код к каждому отдельно (или адаптировать ко всем сразу). Но вот на что я наткнулся "Внедрение библиотеки через CreateRemoteThread" http://delphisite.ru/faq/vnedrenie-biblioteki-cherez-createremotethreadВыполнение собственного кода в чужом процессе. Осталось только взвесить эти два варианта на предмет трудоемкости и выбрать наиболее гибкое и легкореализуемое...
-
-
Наверное много времени бы потратил на отладку :)
К счастью человек эволюционирует и на смену рогаткам, с чрезвычайно узким спектром применения, приходят мелкокалиберные винтовки, с ненамного большим, но однако же большим. И все это я к тому, что не факт что только по "воробьям", если ты меня понимаешь. :) В мое случае приложение должно быть достаточно гибким, чтобы в перспективе была возможноть оперативно изменять его согласно новым требованиям. Мне кажется в случае с DLL injection приложение будет обладать достаточной гибкостью и масштабируюмостью.
-
> Никак не могу понять, чем WM_COPYDATA (будучи упомянутой > уже дважды в данной ветке) может помочь при отправке того- > же DTM_SETSYSTEMTIME?
Привилегий хватит писать в память чужого процесса ? Как Виста на такое отреагирует и Вин7 (я точно не знаю)? Лучше переписать прогу чтобы она принимала WM_COPYDATA и не волноваться за будующее
-
> Лучше переписать прогу чтобы она принимала WM_COPYDATA и > не волноваться за будующее
DateTimePicker переписать или TreeView ?
-
> DateTimePicker переписать или TreeView ?
Такие откровенные глупости писать не надо. Хорошо ? Я понимаю делфи и все такое, но есть же предел в конце концов.
-
> Такие откровенные глупости писать не надо. Хорошо ?
Хорошо, не будем - только и ты плз глупости не пиши о переписывании программы и читай внимательней, желательно с самого начала. Приложение чужое, поэтому у тебя и спрашивают, что именно в чужом приложении стоит переписать?
-
Возможно я ввел кого-то в заблуждение, но к коду тестируемого приложения доступа нет.
-
> Хорошо, не будем - только и ты плз глупости не пиши о переписывании > программы и читай внимательней, желательно с самого начала. > Приложение чужое, поэтому у тебя и спрашивают, что именно > в чужом приложении стоит переписать?
Где там сказано, что код чужой ? Там сказано, что процесс другой.
-
Задача решена. Я внедрил DLL в процесс тестируемого приложения и передал ему SendMessage(handle, DTM_SETSYSTEMTIME, GDT_VALID, Longint(@dateTime)); теперь все работает, не тестировал еще с TreView, но думаю и здесь проблем не будет. Осталось решить проблему с адаптированием DLLки к разным элементам управления, но это уже другая история.
p.s. Ради таких минут мы и живем друзья, спасибо! :)
-
Удалено модератором
|