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. [001576]