Форум: "WinAPI";
Текущий архив: 2004.09.26;
Скачать: [xml.tar.bz2];
ВнизБуфер или не буфер... Найти похожие ветки
← →
DeadMeat © (2004-08-16 00:36) [0]Здрассте всем.
У меня такая вот странная ситуация. Есть *.DLL-ка в чужом процессе (внедрена мною). Есть map файл, открытый для общего пользования. Через него мне надо передать от этой *.DLL-ке, некий hBitmap, для отрисовки его "содержимого" в своей программе.
hBitmap существует и его содержимое "реально", т.е. из самой *.DLL-ки можно его отрисовать.
Вопрос: почему он не отрисовывается у меня в программе?
Вот код *.DLL-ки:.....
const MMFName="Window_Shooter";
type
PBufDat=^TBufDat;
TBufDat=packed record
hnd:hwnd;
bufbit:hbitmap;
bufrect:trect;
end;
var
rBufDat:PBufDat=nil;
hMapObject:THandle=0;
.....
hMapObject:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TBufDat), MMFName);
rBufDat:=MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TBufDat));
shotwindow (rBufDat^.hnd);
.....
procedure ShotWindow(hnd: HWND);
var hdcmem:hdc;
bufrect:trect;
dc:hdc;
hold:HGDIOBJ;
evhnd:thandle;
begin
hDCMem:=CreateCompatibleDC(0);
GetWindowRect(hnd,bufrect);
DC:=GetDC(hnd);
rbufdat^.bufbit:=CreateCompatibleBitmap(DC, bufrect.right-bufrect.left, bufrect.bottom-bufrect.top);
ReleaseDC(hnd, DC);
hOld:=SelectObject(hDCMem, rbufdat^.bufbit);
SendMessage(hnd, WM_PRINT, hDCMem, PRF_CHILDREN or PRF_CLIENT or PRF_ERASEBKGND or PRF_NONCLIENT or PRF_OWNED or PRF_CHECKVISIBLE);
//bitblt (getdc (0),0,0,bufrect.Right-bufrect.Left,bufrect.Bottom-bufrect.Top,hdcmem,0,0,srccopy); //это так... для проверки того, что он "реальный"
SelectObject(hDCMem, hOld);
DeleteObject(hDCMem);
rBufDat^.bufrect.Left:=0;
rBufDat^.bufrect.Top:=0;
rBufDat^.bufrect.Right:=bufrect.Right-bufrect.Left;
rBufDat^.bufrect.Bottom:=bufrect.Bottom-bufrect.Top;
evhnd:=openevent (EVENT_MODIFY_STATE,false,"Shotter_Event");
setevent (evhnd);
end;
Вот код в программе:const MMFName="Window_Shooter";
type
PBufDat=^TBufDat;
TBufDat=packed record
hnd:hwnd;
bufbit:hbitmap;
bufrect:trect;
end;
var
rBufDat:PBufDat=nil;
hMapObject:THandle=0;
.....
hMapObject:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TBufDat), MMFName);
rBufDat:=MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TBufDat));
.....
evhnd:=createevent (nil,true,false,"Shotter_Event");
hnd:=findwindow (nil, "Calculator");
if (hnd=0) or (hnd=handle) then exit;
GetWindowThreadProcessId(hnd, @PID);
rBufDat^.hnd:=hnd;
libpath:=extractfilepath (application.exename)+"sys.dll";
if inject (pid,libpath)=true then
begin
if waitforsingleobject (evhnd,1000)=WAIT_OBJECT_0 then
begin
dc:=createcompatibledc (paintbox1.Canvas.Handle);
hold:=selectobject (dc,rBufDat^.bufbit);
bitblt (paintbox1.canvas.Handle,0,0,rBufDat^.bufrect.Right,rBufDat^.bufrect.Bottom,dc,0,0,srccopy);
SelectObject(dc, hOld);
DeleteObject(dc);
end;
eject (pid,libpath);
end;
closehandle (evhnd);
end;
Передаются размеры, но там, куда ссылается hBitmap, оказывается (как я понял) пусто...
В чем может быть проблема?
P.S. Пример самого WM_PRINT взял (и немного модифицировал) от Фень Юань-я. Там у него было ещё копирование в буфер обмена, так вот если эти строки оставить в *.DLL-кеOpenClipboard(hnd);
EmptyClipboard;
SetClipboardData(CF_BITMAP, rbufdat^.bufbit);
CloseClipboard;
То все работает нормально. Именно это меня и смущает...
← →
Кириешки © (2004-08-16 00:57) [1]А почему надо именно из dll ки рисовать? Нельзя тот же код поместить в программу? Занимать из за него программа много не будет. А вообще если с dll кой приспичило - грузи ее в bitmap и передавай ей хендл этого битмапа вместе с параметрами. Хотя можно и без них. Или хотябы ссылку на файл передай, а в дллке будешь его грузить уже куда хочешь. IMHO если ничего не путаю, и правильно понял вопрос.
← →
Digitman © (2004-08-16 08:26) [2]
> DeadMeat
хэндл (в дан.случае - hBitmap) не является глобально уникальным и имеет смысл только для процесса, создавшего этот хэндл
← →
DeadMeat © (2004-08-16 18:10) [3]
> [1] Кириешки © (16.08.04 00:57)
В *.DLL-ку надо, потомучто WM_PRINT не делает снимок в HDC, который был создан в другом приложении. А TBitmap не хочу использовать, из-за лишних в нем функций..., да и размеру он прибавляет килов так на 100.
> [2] Digitman © (16.08.04 08:26)
Если я правильно понял, то выходит что передается только ссылка на саму картинку, а она находится в другом процессе... Если так, то 2-два вопроса:
1) Почему картинка все же отрисовывается в моей проге, если строки про буфер обмена вернуть на место (в самом конце процедуры ShowWindow, в *.DLL-ке)?
2) Как все таки передать содержимое этой картинки?
---
...Death Is Only The Begining...
← →
DeadMeat © (2004-08-16 18:26) [4]
> в самом конце процедуры ShowWindow, в *.DLL-ке
Пардон... ShotWindow
---
...Death Is Only The Begining...
← →
Digitman © (2004-08-17 08:23) [5]
> DeadMeat © (16.08.04 18:10) [3]
> передается только ссылка на саму картинку
хэндл - это не ссылка, это просто некое "число", являющее собой дескриптор (описатель) объекта
1) потому что в клипборд копируется не хэндл битмапа, а его содержимое
2) например, предусмотри в TBufDat поле-массив достаточного размера и копируй туда содержимое битмапа, а в приложении считывай его и отрисовывай
← →
DeadMeat © (2004-08-17 12:15) [6]
> [5] Digitman © (17.08.04 08:23)
В таком случае ещё два вопроса:
2.1) Как узнать, где находится сама картинка, чтобы ее скопировать, т.е. адрес на блок памяти?
2.2) А можно ли сделать так, чтобы при создании, вся картинка изначально располагалась в нужном мне блоке памяти?
Понимаю, что достал, но если укажете просто куда рыть, то и это будет хорошо...
---
...Death Is Only The Begining...
← →
Digitman © (2004-08-17 12:34) [7]есть класс TBitmap, у которого есть св-во Handle, которому ты можешь назначить полученный тобой hBitmap, и метод SaveToStream(), который скопирует в стрим битмап, хэндл которого ты назначил св-ву Handle
в кач-ве стрима можно задействовать TMemoryStream
после сохранения битмапа в стрим его св-во Size даст инфу о размере блока данных, полностью описывающих картинку, а св-во Memory - указатель на буфер, где лежат данные размером Size, описывающие сохраненную картинку
← →
DeadMeat © (2004-08-17 12:58) [8]Это та понятно, но есть одна вещ, из-за которой этого делать не выйдет - надо на чистом API. А Graphics и Classes - это ещё пару сотен киллобайт. А *.DLL-ка размером 300 кб., (да и ещё ее надо внедрять в разные процессы) ИМХО, выглядит не очень та...
Я посмотрел в исходниках TBitmap.SaveToStream, дык там столько всего пишется, что просто так реализовать будет тяжело.
Рядом где-то нашел GetObject, GetDIBits. Мож они помогут?
---
...Death Is Only The Begining...
← →
Digitman © (2004-08-17 13:03) [9]
> посмотрел в исходниках TBitmap.SaveToStream, дык там столько
> всего пишется, что просто так реализовать будет тяжело
а зачем все подряд оттуда тащить ? только ключевые моменты, в которых производится вызов минимально необходимого числа ВинАПИ-ф-ций, реализующих центральную функц-ть метода
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.09.26;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.042 c