delphidevexpressvcltcxgrid

How to properly implement a Custom Locked State Image in cxgrid in Delphi?


I'm using Delphi 10.2 Tokyo and would like to implement a custom "locked state image" in a descendant of Tcxgrid (DevExpress VCL 18.2).

I tried to override the DoPrepareLockedStateImage protected method as follows:

function TZcxGrid.DoPrepareLockedStateImage: Boolean;
begin
   Result: = False;

   if Assigned (OnPrepareLockedStateImage) then
     OnPrepareLockedStateImage (Self, LockedStatePaintHelper.GetImage, Result)
   else
     DoLockedStateImage (Self, LockedStatePaintHelper.GetImage, Result);
end;

The above implemented method is causing a Stack Overflow because LockedStatePaintHelper.GetImage calls DoPrepareLockedStateImage from the grid.

Is this the way to implement this functionality?

Note: I have not found a topic on the Support Center or the DevExpress FAQ. I just found a topic explaining how to use cxgrid's OnPrepareLockedStateImage method


Solution

  • The issue is that using TcxLockedStatePaintHelper's GetImage during preparation of the state image will cause the Stack Overflow you are experiencing. This is because until the image is completely prepared calling GetImage will cause the image to be prepared (again and again in this case).

    By directly accessing the protected Bitmap property with an accessor this can be circumvented. Using DoLockedStateImage (your implementation of drawing another image) your approach would look like this:

    type
      TcxLockedStatePaintHelperAccess = class(TcxLockedStatePaintHelper);
    
    function TZcxGrid.DoPrepareLockedStateImage: Boolean;
    begin
      DoLockedStateImage(Self, TcxLockedStatePaintHelperAccess(LockedStatePaintHelper).Bitmap, Result);
      Result := inherited DoPrepareLockedStateImage;
    end;