![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Чем принципиально отличаются эти два примера кода ... [D7, WinXP]
Megavolt_Old © (2009-12-09 17:50:00)Код снимает копию экрана и отображает на форме.
Особенности:
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;
SPeller (2010-01-18 06:13:00) [1]
> чудовищные глюки из-за "Form1.Canvas.Handle"
Я его тоже не люблю :) Всегда отдельный контекст брал.
_L_ (2010-01-16 15:00:00) [2]Потестил... Там кажется чудовищные глюки из-за "Form1.Canvas.Handle"...
А если через промежуточный TBitmap делать - то всё норм, как ни в чём ни бывало...
То ли в винде касяк, то ли в VCL... Надо будет переписать на чистом WinAPI чтоб точно выяснить...
_L_ (2010-01-16 13:42:00) [3]> 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;
han_malign (2009-12-18 14:25:00) [4]
> Почему промежуточное копирование даёт такой хитрый эффект?
либо DC не совсем Compatible, либо GDI(который не +(плюс)) вообще не умеет напрямую копировать из CommonDC в PrivateDC(кажется где-то что-то такое упоминалось, но найти не могу, возможно просто дежа-вю)
MegaVolt_Old (2009-12-10 01:26:00) [5]DVMМдя... накосячил так накосячил.... Большущее тебе спасибо :)
Может ты ещё знаешь почему второй код показывает tooltip-ы а первый нет? Почему промежуточное копирование даёт такой хитрый эффект?
DVM (2009-12-10 01:21:00) [6]
> Попробовал так как в коде ниже не помогло
> DeleteDC(hbmScreen);
Конечно, если создавать Bitmap, а удалять DC. В справке по CreateCompatibleBitmap что сказано про удаление, какая там функция?
MegaVolt_Old (2009-12-10 00:27:00) [7]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;
Sapersky (2009-12-09 20:53:00) [8]Create[Compatible]DC -> DeleteDC, GetDC -> ReleaseDC
DVM (2009-12-09 18:58:00) [9]
> внутри try except
я хотел сказать внутри try finally.
DVM (2009-12-09 18:56:00) [10]
> Каких я пока не понял кто что видит подскажите.
проблема в CreateCompatibleBitmap + SelectObject
плюс почему у тебя создание объекта внутри try except
MegaVolt_old (2009-12-09 18:28:00) [11]Второй пункт уточню:
Зависает только второй код. Из-за утечки GDI объектов. Каких я пока не понял кто что видит подскажите.