БОЛЬШОЙ FAQ ПО DELPHI



TCanvas и освобождение дескрипторов

TCanvas автоматически ReleaseDC не вызывает. При создании холста с WindowDC в качестве дескриптора, лучшей идеей будет создание потомка TCanvas (моделированного с TControlCanvas):


 type
   TWindowCanvas = class(TCanvas)
   private
     FWinControl: TWinControl;
     FDeviceContext: HDC;
     procedure SetWinControl(AControl: TWinControl);
   protected
     procedure CreateHandle; override;
   public
     destructor Destroy; override;
     procedure FreeHandle;
     property WinControl: TWinControl read FWinControl write SetWinControl;
   end;
 
 implementation
 
 destructor TWindowCanvas.Destroy;
 begin
   FreeHandle;
   inherited Destroy;
 end;
 
 procedure TWindowCanvas.CreateHandle;
 begin
   if FControl = nil then
     inherited CreateHandle
   else
   begin
     if FDeviceContext = 0 then
       FDeviceContext := GetWindowDC(WinControl.Handle);
     Handle := FDeviceContext;
   end;
 end;
 
 procedure TControlCanvas.FreeHandle;
 begin
   if FDeviceContext <> 0 then
   begin
     Handle := 0;
     ReleaseDC(WinControl.Handle, FDeviceContext);
     FDeviceContext := 0;
   end;
 end;
 
 procedure TControlCanvas.SetWinControl(AControl: TWinControl);
 begin
   if FWinControl <> AControl then
   begin
     FreeHandle;
     FWinControl := AControl;
   end;
 end;
 

Очевидно, вы должны должны следить за ситуацией, и разрушать TWindowCanvas (или освобождать дескриптор) перед тем, как уничтожить элемент управления, связанный с ним. Также, имейте в виду, что дескриптор DeviceContext не освобождается автоматически после обработки каждого сообщения (как это происходит с дескрипторами TControlCanvas); для освобождения дескриптора вы должны явно вызвать FreeHandle (или разрушить Canvas). И, наконец, имейте в виду, что "WindowCanvas.Handle:= 0" не освобождает десктиптор, для его освобождения вы должны вызывать FreeHandle.




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Видеокурс ВЗЛОМ