Inplace DBLookupComboBox editor inside DB Grid Raise "Division by zero" in DLL under Windows 7 when component is free
Original Reporter info from Mantis: zgabrovski
-
Reporter name: Zdravko Gabrovski
Original Reporter info from Mantis: zgabrovski
- Reporter name: Zdravko Gabrovski
Description:
A very strange problem, which raises ONLY UNDER Windows 7 when the project inside LCL dll project.
I am developing a plugin-dll library, which have a screen with TDBGrid and DBLookupCompoBox as inplace-editor.
I am using "OnSelectEditor" event, to assign a DBLookupComboBox as custom editor.
I am using exactly the same form in standalone .exe project.
In standalone project, everything works fine. But In Dll, only under Windows 7, it raises "Division by zero" then I am freeng the form.
After a deep bebug, I found that the problem becomes from
destructor TBrush.Destroy;
begin
FreeReference;
inherited Destroy;
end;
Specially in method "FreeReference" which calls "CacheItem.DecreaseRefCount"
procedure TBrush.FreeReference;
var
CacheItem: TResourceCacheItem;
begin
if not FReference.Allocated then Exit;
Changing;
if FBrushHandleCached then
begin
BrushResourceCache.Lock;
try
CacheItem := BrushResourceCache.FindItem(FReference.Handle);
if CacheItem <> nil then
CacheItem.DecreaseRefCount; <-------------- Heree
FBrushHandleCached := False;
finally
BrushResourceCache.Unlock;
end;
end else
DeleteObject(HGDIOBJ(FReference.Handle));
FReference._lclHandle := 0;
end;
In this method there is a check - if refcount is = 0 to raise "Division by zero" exception.
procedure TResourceCacheItem.DecreaseRefCount;
procedure RaiseRefCountZero;
begin
RaiseGDBException('TResourceCacheItem.DecreaseRefCount=0 '+ClassName);
end;
begin
//debugln('TResourceCacheItem.DecreaseRefCount ',ClassName,' ',dbgs(Self),' ',dbgs(FReferenceCount));
if FReferenceCount = 0 then
RaiseRefCountZero;
dec(FReferenceCount);
if FReferenceCount = 0 then
Cache.ItemUnused(Self);
//debugln('TResourceCacheItem.DecreaseRefCount END ');
end;
My proposal is to add a check inside brush.inc:
...<br/>
if ( CacheItem <> nil ) and ( CacheItem.ReferenceCount>0 ) then
CacheItem.DecreaseRefCount;
.....
That will avoid this exception.
I know, that this is not so good way to solve the problem, but I found that this is very specific error, that happens, because a inplace DBComboBox Editor does not receive "WM_PAINT" event from Windows in that specefic situation (as a DLL under Windows 7). I thing it is some windows error, because the same DLL works fine under Windows 10. I spent 3 days to debug it and I thing that this is the best solution for the moment.
Steps to reproduce:
I can give AnyDesk access to my PC to demonstrate the problem.
Additional information:
Please, find attached .diff patch.
Mantis conversion info:
- Mantis ID: 37072
- OS: Windows 7
- OS Build: 7
- Build: trunk
- Platform: Windows
- Fixed in revision: r63167 (#320f05fb)