Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Чем принципиально отличаются эти два примера кода ...   Найти похожие ветки 

 
Megavolt_Old   (2009-12-09 17:50) [0]

Код снимает копию экрана и отображает на форме.

Особенности:

1. Второй код снимает копию экрана с ToolTip (всплывающе подсказки во многих приложениях кроме дельфи. Например в проводнике). Что даёт промежуточное копирование во временную DC не очень понятно.

2. Через какое то время оба они перестают работать. Т.е. таймер считает а картинка не обновляется :(

procedure TForm1.Timer1Timer(Sender: TObject);
const  CAPTUREBLT = $40000000;
var
 hdcScreen: HDC;
 hdcCompatible: HDC;
 bmp: TBitmap;
 hbmScreen: HBITMAP;
begin
 Timer1.Enabled:=false;

 try
   hdcScreen:=GetDC(0);
   Win32Check(BitBlt(Form1.Canvas.Handle,0,0,200,300,  hdcScreen,  0, 0, SRCCOPY or CAPTUREBLT));
 finally
   DeleteDC(hdcScreen);
 end;
 Timer1.Enabled:=true;
 Label1.Caption:=IntToStr(GetTickCount);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
const  CAPTUREBLT = $40000000;
var
 hdcScreen: HDC;
 hdcCompatible: HDC;
 bmp: TBitmap;
 hbmScreen: HBITMAP;
begin
 Timer1.Enabled:=false;

 //hdcScreen := CreateDC("DISPLAY", nil, nil, nil);
 try
   hdcScreen:=GetDC(0);
   try
     hdcCompatible := CreateCompatibleDC(hdcScreen); // Create a compatible bitmap for hdcScreen.
     hbmScreen := CreateCompatibleBitmap(hdcScreen,
                                         GetDeviceCaps(hdcScreen, HORZRES),
                                         GetDeviceCaps(hdcScreen, VERTRES));// Select the bitmaps into the compatible DC.
     SelectObject(hdcCompatible, hbmScreen);
     Win32Check(BitBlt(hdcCompatible,0,0,GetDeviceCaps(hdcScreen, HORZRES),GetDeviceCaps(hdcScreen, VERTRES),hdcScreen,0,0,SRCCOPY or CAPTUREBLT));
     Win32Check(BitBlt(Form1.Canvas.Handle,0,0,200,300,  hdcCompatible,  0, 0, SRCCOPY or CAPTUREBLT));
   finally
     DeleteDC(hdcCompatible);
   end;
 finally
   DeleteDC(hdcScreen);
 end;
 Timer1.Enabled:=true;
 Label1.Caption:=IntToStr(GetTickCount);
end;


 
MegaVolt_old   (2009-12-09 18:28) [1]

Второй пункт уточню:

Зависает только второй код. Из-за утечки GDI объектов. Каких я пока не понял кто что видит подскажите.


 
DVM ©   (2009-12-09 18:56) [2]


> Каких я пока не понял кто что видит подскажите.

проблема в CreateCompatibleBitmap + SelectObject

плюс почему у тебя создание объекта внутри try except


 
DVM ©   (2009-12-09 18:58) [3]


> внутри try except

я хотел сказать внутри try finally.


 
Sapersky   (2009-12-09 20:53) [4]

Create[Compatible]DC -> DeleteDC, GetDC -> ReleaseDC


 
MegaVolt_Old   (2009-12-10 00:27) [5]

DVM
>проблема в CreateCompatibleBitmap + SelectObject

Ага похоже что так. Только вот как её исправить я не понял. Попробовал так как в коде ниже не помогло. Подскажи пожалуйста я не очень большой спец в API :(

>плюс почему у тебя создание объекта внутри try except

Вай вай... Какой позор. Мне очень стыдно.... :(

Sapersky

Поправил так как ты предложил ничего не изменилось :( Похоже они равнозначны.

procedure TForm1.Timer1Timer(Sender: TObject);
const  CAPTUREBLT = $40000000;
var
 hdcScreen: HDC;
 hdcCompatible: HDC;
 bmp: TBitmap;
 hbmScreen,hbmOld: HBITMAP;
begin
 Timer1.Enabled:=false;

 //hdcScreen := CreateDC("DISPLAY", nil, nil, nil);
 hdcScreen:=GetDC(0);
 try
   hdcCompatible := CreateCompatibleDC(hdcScreen); // Create a compatible bitmap for hdcScreen.
   try
     hbmScreen := CreateCompatibleBitmap(hdcScreen,
                                         GetDeviceCaps(hdcScreen, HORZRES),
                                         GetDeviceCaps(hdcScreen, VERTRES));// Select the bitmaps into the compatible DC.
     hbmOld:=SelectObject(hdcCompatible, hbmScreen);
     Win32Check(BitBlt(hdcCompatible,0,0,GetDeviceCaps(hdcScreen, HORZRES),GetDeviceCaps(hdcScreen, VERTRES),hdcScreen,0,0,SRCCOPY or CAPTUREBLT));
     Win32Check(BitBlt(Form1.Canvas.Handle,0,0,200,300,  hdcCompatible,  0, 0, SRCCOPY or CAPTUREBLT));
     SelectObject(hdcCompatible, hbmOld);
     DeleteDC(hbmScreen);

   finally
     DeleteDC(hdcCompatible);
   end;
 finally
   ReleaseDC(0,hdcScreen);
 end;
 Timer1.Enabled:=true;
 Label1.Caption:=IntToStr(GetTickCount);
end;


 
DVM ©   (2009-12-10 01:21) [6]


> Попробовал так как в коде ниже не помогло


> DeleteDC(hbmScreen);

Конечно, если создавать Bitmap, а удалять DC. В справке по CreateCompatibleBitmap что сказано про удаление, какая там функция?


 
MegaVolt_Old   (2009-12-10 01:26) [7]

DVM Мдя... накосячил так накосячил.... Большущее тебе спасибо :)

Может ты ещё знаешь почему второй код показывает tooltip-ы а первый нет? Почему промежуточное копирование даёт такой хитрый эффект?


 
han_malign   (2009-12-18 14:25) [8]


> Почему промежуточное копирование даёт такой хитрый эффект?

либо DC не совсем Compatible, либо GDI(который не +(плюс)) вообще не умеет напрямую копировать из Common DC в Private DC(кажется где-то что-то такое упоминалось, но найти не могу, возможно просто дежа-вю)


 
_L_   (2010-01-16 13:42) [9]

> Sapersky   (09.12.09 20:53) [4]
> Create[Compatible]DC -> DeleteDC, GetDC -> ReleaseDC


А мне говорили что надо всегда оба писать... То есть вот так например:

GetDC();
...
ReleaseDC();
DeleteDC();


А не рациональнее сделать глобальные переменные - GetDC(0) вроде ж постоянное...
Постоянно создавать и уничтожать часто используемые HDC не вижу смысла - лишняя работа для ОС...
Да и есть ли смысл так жоско всё упаковывать в "Try ... Finally ..."?

> Может ты ещё знаешь почему второй код показывает tooltip-ы а первый нет?

Хм... Флаг CAPTUREBLT по идее должен все слоёные окна включать в скрин... Надо бы разузнать почму так... Для начала я б выбросил все "Try ... Finally ..." - не удобно понимать код с ними (да и есть ли какой толк с него)...

P.S. А для чего делается так?:
begin
Timer1.Enabled:=false;
...
Timer1.Enabled:=true;
end;


 
_L_   (2010-01-16 15:00) [10]

Потестил... Там кажется чудовищные глюки из-за "Form1.Canvas.Handle"...
А если через промежуточный TBitmap делать - то всё норм, как ни в чём ни бывало...

То ли в винде касяк, то ли в VCL... Надо будет переписать на чистом WinAPI чтоб точно выяснить...


 
SPeller ©   (2010-01-18 06:13) [11]


> чудовищные глюки из-за "Form1.Canvas.Handle"

Я его тоже не люблю :) Всегда отдельный контекст брал.



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

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.486 c
15-1336633312
jacksotnik
2012-05-10 11:01
2013.03.22
Закрыть файл


15-1349268838
Чтец
2012-10-03 16:53
2013.03.22
Книга в формате Word


15-1327133819
Inovet
2012-01-21 12:16
2013.03.22
DrWeb 7.0 постоянное обращение к диску


15-1338322058
Bluejohn
2012-05-30 00:07
2013.03.22
Чем порезать видео?


11-1244317439
Lirk
2009-06-06 23:43
2013.03.22
Вариант решения проблемы...