Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.074 c
15-1353949627
dummy_user
2012-11-26 21:07
2013.03.22
Отследить движение человека на камере.


15-1336994384
AV
2012-05-14 15:19
2013.03.22
Copy команда. Как не затирать без вопросов?


15-1339412694
NieL
2012-06-11 15:04
2013.03.22
ошибка xml


2-1330408847
Delphi2007
2012-02-28 10:00
2013.03.22
перекомпиляция проекта на 64bit


1-1298886494
harisma
2011-02-28 12:48
2013.03.22
Упаковка массива рекордов в олевариант





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