-2

I need your help. Draw method the DBGrid. I have table DBGrid.

How? To my method "DrawDBGrid", add my method "LoadDefaultImage" If there is no file path (image), a replacement image from the resource will be displayed.

My "LoadDefaultImage"

procedure LoadDefaultImage(AImage: TImage; aPngName: string);
var
  lImage: TPngImage;
begin
  lImage := TPngImage.Create();
  try
    lImage.LoadFromResourceName(hInstance, aPngName);
    AImage.picture.Graphic := lImage;
  finally
    lImage.Free();
  end;
end;

Call the method

LoadDefaultImage(AImage, 'No image');

My "DrawDBGrid"

procedure DrawDBGrid(aDBGrid: TDBGrid; aGraphicFieldName: string; Column: TColumn; State: TGridDrawState; Sender: TObject;
  const Rect: TRect; DataCol: Integer);
var
  lRect: TRect;
  lImage: TJPEGImage;
  lPicturePath: string;
  lDataset: TclientDataSet;
  lIsFile: Boolean;

begin
  lDataset := TclientDataSet(aDBGrid.DataSource.DataSet);
  lPicturePath := extractfilepath(paramstr(0)) + lDataset.FieldByName(aGraphicFieldName).AsString;
  lIsFile := fileexists(lPicturePath);
  if (Column.Field.FieldName <> aGraphicFieldName) or (not lIsFile) then
  begin
    if (gdSelected in State) and (TDBGrid(Sender).Focused) then
      TDBGrid(Sender).canvas.Brush.color := $E8E3A8
    else
      TDBGrid(Sender).canvas.Brush.color := clWhite;
    aDBGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
  end
  else
  begin
    lRect.left := Rect.left + 1;
    lRect.Top := Rect.Top + 1;
    lRect.Right := Rect.Right - 1;
    lRect.Bottom := Rect.Bottom - 1;
    lImage := TJPEGImage.Create;
    try
      try
        lImage.LoadFromFile(extractfilepath(paramstr(0)) + lDataset.FieldByName(aGraphicFieldName).AsString);
        aDBGrid.canvas.StretchDraw(lRect, lImage);
      except
        on e: exception do
        begin
          raise exception.Create('Błąd wyświetlania pliku ' + lDataset.FieldByName(aGraphicFieldName)
              .AsString + ''#13'' + ''#10'' + e.Message);
        end;
      end;
    finally
      lImage.Free;
    end;
  end;
end;
Maryna
  • 9
  • 3
  • Will you please **stop** posting questions on one of your various accounts (like RedWomen), then deleting it and asking the same q from another one! – MartynA May 20 '17 at 20:27
  • I do not ask about the same, besides, I solved the problem, so I removed it to ask what I can not do – Maryna May 20 '17 at 20:37
  • 1
    You should be a bit more considerate of other users. Firstly, suppose someone was in the middle of writing an answer to your earlier q and found that they couldn't post it because you had deleted it. Secondly a q on SO is not just for the benefit of the person who asked it. So, if you manage to solve your q's problem yourself, you should consider posting an answer saying what you did, for the benefit of future readers. In any case you should pick one account for asking qs and stick to it. – MartynA May 20 '17 at 20:46
  • Going back to the question. I think it is enough to replace `AImage : TImage` in the procedure `LoadDefaultImage` I do not know what to replace and whether this is enough – Maryna May 20 '17 at 21:15

1 Answers1

0

If the DrawDBGrid is a standalone procedure called from the rendering event, you can modify it for passing a pre-loaded default image like so:

procedure DrawDBGrid(aDBGrid: TDBGrid; aGraphicFieldName: string; Column: TColumn; State: TGridDrawState; Sender: TObject;
  const Rect: TRect; DataCol: Integer; DefaultImage: TPngImage);

Then inside it you can do this:

  ...
  lIsFile := FileExists(lPicturePath);
  // if not the desired column
  if (Column.Field.FieldName <> aGraphicFieldName) then
  begin
    if (gdSelected in State) and (TDBGrid(Sender).Focused) then
      TDBGrid(Sender).canvas.Brush.color := $E8E3A8
    else
      TDBGrid(Sender).canvas.Brush.color := clWhite;
    aDBGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
  end
  else // the right column
  begin
    // if the file was not found, draw the default image that was passed
    if not lIsFile then
    begin
      aDBGrid.canvas.Draw(Rect, DefaultImage);
    end
    else
    begin
      lRect.left := Rect.left + 1;
      lRect.Top := Rect.Top + 1;
      lRect.Right := Rect.Right - 1;
      lRect.Bottom := Rect.Bottom - 1;
      lImage := TJPEGImage.Create;
      try
        try
          lImage.LoadFromFile(extractfilepath(paramstr(0)) + lDataset.FieldByName(aGraphicFieldName).AsString);
          aDBGrid.canvas.StretchDraw(lRect, lImage);
        except
          on e: exception do
          begin
            raise exception.Create('Błąd wyświetlania pliku ' + lDataset.FieldByName(aGraphicFieldName)
              .AsString + ''#13'' + ''#10'' + e.Message);
          end;
        end;
      finally
        lImage.Free;
      end;
    end;
    ...

The last piece of Lego here is that you'll pre-load the default image, for instance when the form is created and keep it stored e.g. as a private field of type TPngImage in the form class and pass it into your standalone procedure.

Victoria
  • 7,477
  • 2
  • 18
  • 40