Jump to content


Photo

Event OnCustomDrawCell not fired


  • Please log in to reply
15 replies to this topic

#1 PeterNu

PeterNu
  • Members
  • 7 posts

Posted 22 April 2022 - 02:53 PM

Im using Delphi 11 Alexandria an Im using NextDBGrid6 first time.

 

To paint an PNG image into a cell, I need the event OnCustomDrawCell, but it was not fired.



#2 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 23 April 2022 - 03:31 PM

Hi,

 

For this purpose you can use following events in column itself:

 

- OnDrawBackground

- OnDrawContent

 

You can use one or both of them if you need, but in your case it seems that you need the 2nd one.

 

One more thing is that you need to do is setting DrawingOptions property of Column. Inside this property you can include and exclude layers of your drawing. In your case you need to turn off doContent and turn on doCustom as you don't need default drawing, but you want to do custom one.

 

I hope that this helps, please tell me if you have more questions. 


boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#3 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 23 April 2022 - 03:32 PM

And, also there is a small demo inside: ...Demos\Next Grid\Delphi XE6\Cell Background custom drawing sub-folder


boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#4 PeterNu

PeterNu
  • Members
  • 7 posts

Posted 25 April 2022 - 01:23 PM

Thanks for your answer. The problem in this case is that each cell of the column displays the same PNG.

In my case, however, a different PNG should be displayed for each row of the column.

 



#5 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 25 April 2022 - 02:38 PM

Hi,

 

If you are for example storing path to PNG file in some adjacent field, you can simply access this field inside this event.

 

Something like this:

 

PathToMyPng := HiddenColumnWithPath.DataBinding.Field.AsString;

boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#6 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 25 April 2022 - 02:43 PM

Then you can load your PNGs and draw them.

 

If you want I can make small demo project for you.


boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#7 PeterNu

PeterNu
  • Members
  • 7 posts

Posted 26 April 2022 - 05:38 PM

The PNG data is inside a blob field and I use this code:

 

procedure TForm1.NxDBGraphicColumn1DrawContent(Sender: TObject; ACol,
  ARow: Integer; CellRect: TRect; State: TNxCellPaintingState);
var PngImage:      TPngImage;
    DeltaX,DeltaY: Integer;
    BlobStream:    TStream;
begin
  if ACol=0 then
  begin
    if UniQuery1.FindField('thumbnail')<>nil then
    begin
      if UniQuery1.FieldByName('thumbnail').IsBlob and not UniQuery1.FieldByName('thumbnail').IsNull then
      begin
        BlobStream:=UniQuery1.CreateBlobStream(UniQuery1.FieldByName('thumbnail'),bmRead);
        try
          if BlobStream.Size>0 then
          begin
            PngImage:=TPngImage.Create;
            try
              Blobstream.Position:=0;
              PngImage.LoadFromStream(BlobStream);
              PngImage.Transparent:=True;
              DeltaX:=((CellRect.Right-CellRect.Left)-PngImage.Width) div 2;
              DeltaY:=((CellRect.Bottom-CellRect.Top)-PngImage.Height) div 2;
              NextDBGrid61.Canvas.Draw(CellRect.Left+DeltaX,CellRect.Top+DeltaY,PngImage);
            finally
              PngImage.Free;
            end;
          end;
        finally
          BlobStream.Free;
        end;
      end;
    end;
  end;
end;
 
But each row display the same image and not the blob data of the cell.


#8 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 26 April 2022 - 07:56 PM

Hi,

 

Can you just tell me if UniQuery1 is the same DataSet that is used as all other data in the grid? Or is a separate TDataSet.

 

I can maybe try to make similar demo project (this is probably UniDac used here).


boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#9 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 26 April 2022 - 09:50 PM

One more update before I start with my test project:

 

If UniQuery1 is the same data set that also the column uses, then maybe you can set thumbnail field to be used by the column.

 

Then, instead using UniQuery1.FindField etc. just use TNxDBGraphicColumn6(NextDBGrid61.Columns[ACol]).DataBinding.Field

 

One another solution is that I make an event where Blob TField can be simply converted back to TGraphic and the grid will do drawings automatically as it does currently for BMP and JPG.

 

Maybe later I can include PNG support out of the box. Tell me what you think about the event idea.


boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#10 PeterNu

PeterNu
  • Members
  • 7 posts

Posted 27 April 2022 - 09:37 AM

That with the event is a good idea. Also the native support of PNG would be great, but until then I need a workaround.

 

How can I assign the content of TNxDBGraphicColumn6(NextDBGrid61.Columns[ACol]).DataBinding.Field to my PngImage?



#11 PeterNu

PeterNu
  • Members
  • 7 posts

Posted 27 April 2022 - 10:21 AM

Ok I assign the field to the PngImage like this:

 

  if ACol=0 then
  begin
    PngImage:=TPngImage.Create;
    try
      PngImage.Assign(TNxDBGraphicColumn6(NextDBGrid61.Columns[ACol]).DataBinding.Field);
      PngImage.Transparent:=True;
      DeltaX:=((CellRect.Right-CellRect.Left)-PngImage.Width) div 2;
      DeltaY:=((CellRect.Bottom-CellRect.Top)-PngImage.Height) div 2;
      NextDBGrid61.Canvas.Brush.Color:=clWhite;
      NextDBGrid61.Canvas.FillRect(CellRect);
      NextDBGrid61.Canvas.Draw(CellRect.Left+DeltaX,CellRect.Top+DeltaY,PngImage);
    finally
      PngImage.Free;
    end;
  end;
 
But the result is always the same. Each cell in the column display the same picture.
I need to display a image for each row. :-(


#12 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 27 April 2022 - 05:53 PM

Maybe I can add this event and we can try that way. Hope it’s ok to wait for 2 days until I finish it.

 

Problem with PNG for me is that not all Delphi versions are supporting it. I thought about adding conditional directives.

 

Can you tell me which Delphi version you use?


boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#13 PeterNu

PeterNu
  • Members
  • 7 posts

Posted 28 April 2022 - 09:20 PM

Delphi 11 Alexandria.

Thank you for your support.

#14 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 02 May 2022 - 02:58 PM

Hi,

 

I have sent you new personal message with new files.

 

I hope that we are near to solve this problem.


boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.

#15 PeterNu

PeterNu
  • Members
  • 7 posts

Posted 03 May 2022 - 11:22 AM

Hello,

 

thanks for your mail.

 

The graphic column is the result of an query. The datatype is ftBlob not ftGraphic.

 

I make in your source a short modification:

 

     if DataField.DataType = ftGraphic then
 
to
 
     if DataField.DataType in [ftGraphic,ftBlob] then
 
 
The images are displayed now.
 
procedure TForm1.NextDBGrid61GetBlobGraphic(Sender: TObject; Field: TField;var Graphic: TGraphic);
var PngImage:  TPngImage;
begin
  if Field.IsBlob then
  begin
    PngImage:=TPngImage.Create;
    try
      PngImage.Assign(Field);
      PngImage.Transparent:=True;
      Graphic:=PngImage;
    finally
      //PngImage.Free;  
    end;
  end;
end;
 
 
But now we have a strange behavior. When I move the mouse pointer over the grid an EOutOfResources exception occurce.
 
Maybe its better you fire the OnCustomDrawCell event. Then I can paint die PNG image into the cell.


#16 Boki (Berg)

Boki (Berg)

    Boki (Berg)

  • Forum Admin
  • PipPipPipPipPip
  • 8,191 posts
  • Gender:Male

Posted 03 May 2022 - 08:31 PM

Hi,

 

This bug is happening because PNG image object is created many times. I will try to find some nice place where we can destroy this object.

 

If you want, and which I suggest is that you store (cache) your images in some kind of list and then simply show them (without need to create object at every repaint).

 

I will check once again why your custom draw solution always shows the same picture. But, using built-in solution can give some nice extra features like FillMode, Effects and alignments.

 

But, I will definitely go with the route to store PNG images into a list and then simply provide them to this event. If you don't like caching, I will add auto-destroy of PNG images when they are not needed anymore.


boki@bergsoft.net | LinkedIn Profile
--
BergSoft Home Page: www.bergsoft.net
Users Section: users.bergsoft.net
Articles and Tutorials: help.bergsoft.net (Developers Network)
--
BergSoft Facebook page
--
Send us applications made with our components and we will submit them on: www.bergsoft.net/apps.htm. Link to this page will be also set on home page too.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users