-
Код снимает копию экрана и отображает на форме. Особенности: 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;
try
hdcScreen:=GetDC(0);
try
hdcCompatible := CreateCompatibleDC(hdcScreen); hbmScreen := CreateCompatibleBitmap(hdcScreen,
GetDeviceCaps(hdcScreen, HORZRES),
GetDeviceCaps(hdcScreen, VERTRES)); 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;
-
Второй пункт уточню:
Зависает только второй код. Из-за утечки GDI объектов. Каких я пока не понял кто что видит подскажите.
-
> Каких я пока не понял кто что видит подскажите.
проблема в CreateCompatibleBitmap + SelectObject
плюс почему у тебя создание объекта внутри try except
-
> внутри try except
я хотел сказать внутри try finally.
-
Create[Compatible]DC -> DeleteDC, GetDC -> ReleaseDC
-
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:=GetDC(0);
try
hdcCompatible := CreateCompatibleDC(hdcScreen); try
hbmScreen := CreateCompatibleBitmap(hdcScreen,
GetDeviceCaps(hdcScreen, HORZRES),
GetDeviceCaps(hdcScreen, VERTRES)); 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;
-
> Попробовал так как в коде ниже не помогло
> DeleteDC(hbmScreen);
Конечно, если создавать Bitmap, а удалять DC. В справке по CreateCompatibleBitmap что сказано про удаление, какая там функция?
-
DVM Мдя... накосячил так накосячил.... Большущее тебе спасибо :)
Может ты ещё знаешь почему второй код показывает tooltip-ы а первый нет? Почему промежуточное копирование даёт такой хитрый эффект?
-
> Почему промежуточное копирование даёт такой хитрый эффект?
либо DC не совсем Compatible, либо GDI(который не +(плюс)) вообще не умеет напрямую копировать из Common DC в Private DC(кажется где-то что-то такое упоминалось, но найти не могу, возможно просто дежа-вю)
-
> 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;
-
Потестил... Там кажется чудовищные глюки из-за "Form1.Canvas.Handle"... А если через промежуточный TBitmap делать - то всё норм, как ни в чём ни бывало...
То ли в винде касяк, то ли в VCL... Надо будет переписать на чистом WinAPI чтоб точно выяснить...
-
> чудовищные глюки из-за "Form1.Canvas.Handle"
Я его тоже не люблю :) Всегда отдельный контекст брал.
|