Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
14-1094333513
kull
2004-09-05 01:31
2004.09.26
Как писать ТЗ?


1-1095069384
Mishel
2004-09-13 13:56
2004.09.26
Clipboard: ограничения по размеру


9-1085842791
FRick
2004-05-29 18:59
2004.09.26
GLScene стрельба


1-1094795737
Геннадий
2004-09-10 09:55
2004.09.26
Service: проблема с OnExecute


3-1093240908
gunner
2004-08-23 10:01
2004.09.26
Post данных из DataSet в базу





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