Форум: "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.057 c