tags:

views:

150

answers:

3

I'm porting some very old code from Delph7 to Delphi2010 with a few changes as possible to the existing code base for the usual reasons.

First: the good news for anyone who hasn't jumped yet: it's not as daunting as it may look! I'm actually pleased (& surprised) at how easy 1,000,000+ lines of code have moved across. And what a relief to be back on the leading edge! Delphi 2010 has so many great enhancements.

However, I'm having a cosmetic problem with some TStringGrids and TDbGrids descendants.

In the last century (literally!) someone wrote the two methods below.

The first method is used to justify text. When run in Delphi 2010, the new text and the unjustified text to both appear in the cells written to. Of course it's a mess visually, almost illegible. Sometimes, as a result of the second method is use, the grid cells are actually semi-transparent, with text from the window below showing through. (Again, not pretty!)

It appears to me that Delphi 2010's TDbGrid and TStringGrid have some differences in the way they handle transparency?

I haven't much experience in this area of Delphi (in fact, I have no idea what the 2nd method is actually doing!) and was hoping someone could give me some pointers on what's going on and how to fix it.

TIA!

Method 1

  procedure TForm1.gridDrawCell(Sender: TObject; Col, Row: Integer;
    Rect: TRect; State: TGridDrawState);
  {Used to align text in cells.}
  var
    x: integer;
  begin
    if (Row > 0) AND (Col > 0) then
      begin
        SetTextAlign(grdTotals.Canvas.Handle, TA_RIGHT);
        x := Rect.Right - 2;
      end
    else
      begin
        SetTextAlign(grdTotals.Canvas.Handle, TA_CENTER);
        x := (Rect.Left + Rect.Right) div 2;
      end;
    grdTotals.Canvas.TextRect(Rect, x, Rect.Top+2, grdTotals.Cells[Col,Row]);    
  end;

Method 2

procedure WriteText(ACanvas: TCanvas; ARect: TRect; DX, DY: Integer; const Text: string;
  TitleBreak: TTitleBreak; Alignment: TAlignment);
const
  AlignFlags: array [TAlignment] of Integer = (DT_LEFT or
    { DT_WORDBREAK or } DT_EXPANDTABS or DT_NOPREFIX, DT_RIGHT or
    { DT_WORDBREAK or } DT_EXPANDTABS or DT_NOPREFIX, DT_CENTER or
    { DT_WORDBREAK or } DT_EXPANDTABS or DT_NOPREFIX);
var
  ABitmap: TBitmap;
  AdjustBy: Integer;
  B, R: TRect;
  WordBreak: Integer;
begin
  WordBreak := 0;
  if (TitleBreak = tbAlways) or ((TitleBreak = tbDetect) and (Pos(Chr(13) + Chr(10), Text) = 0))
      then
    WordBreak := DT_WORDBREAK;
  ABitmap := TBitmap.Create;
  try
    ABitmap.Canvas.Lock;
    try
      AdjustBy := 1;
      if (Alignment = taRightJustify) then
        Inc(AdjustBy);
      with ABitmap, ARect do
        begin
          Width := Max(Width, Right - Left);
          Height := Max(Height, Bottom - Top);
          R := Rect(DX, DY, Right - Left - AdjustBy, Bottom - Top - 1); { @@@ }
          B := Rect(0, 0, Right - Left, Bottom - Top);
        end;
      with ABitmap.Canvas do
        begin
          Font := ACanvas.Font;
          Brush := ACanvas.Brush;
          Brush.Style := bsSolid;
          FillRect(B);
          SetBkMode(Handle, TRANSPARENT);
          DrawText(Handle, PChar(Text), Length(Text), R, AlignFlags[Alignment] or WordBreak);
        end;
      ACanvas.CopyRect(ARect, ABitmap.Canvas, B);
    finally
      ABitmap.Canvas.Unlock;
    end;
  finally
    ABitmap.Free;
  end;
end;
+1  A: 

In Method 2, I would try with SetBkMode(Handle, OPAQUE);

Update: and I would put it before FillRect(B)

François
A: 

Hi, Francois,

I'm posting this as an answer (which it's not) so I can include an image.

Thanks for your suggestion. Using OPAQUE helped with initial writing to the TDbGrid. Backgrounds don't bleed through anymore! I'm a bit embarrassed I hadn't spotted the "TRANSPARENT" term before.

However, changes to cells are still failing to erase previous contents, so they look like the screen below. Darn!

In the example below, the grid contents were moved down one row, but the also remain in the cell above in which they were previously.

Image showing grid with characters super-imposed on one another.

Tom1952
Updated my answer: try doing `FillRect(B)` after `SetBkMode(Handle, OPAQUE)`.
François
A: 

We always use the DrawText function that gives us control on alignment (vert and hor). You have to use a FillRect(Rect) before to clean up the content.

I've never used SetBkMode() but my guess is you can go without that.

Daniel Luyo