【问题标题】:Delphi 2010 differs in Canvas transparency compared to Delphi 7?与 Delphi 7 相比,Delphi 2010 的 Canvas 透明度有何不同?
【发布时间】:2011-05-09 09:50:36
【问题描述】:

出于通常的原因,我将一些非常旧的代码从 Delph7 移植到 Delphi2010对现有代码库进行了一些更改

首先:对于那些还没有跳起来的人来说是个好消息:它并不像看起来那么令人生畏!实际上,我很高兴(也很惊讶)看到 1,000,000 多行代码的移动如此简单。回到领先地位真是一种解脱! Delphi 2010 有很多很棒的增强功能。

但是,我遇到了一些 TStringGrids 和 TDbGrids 后代的外观问题。

在上个世纪(字面意思!)有人写了以下两种方法。

第一种方法用于对齐文本。在 Delphi 2010 中运行时,新文本 不对齐的文本 both 出现在写入的单元格中。当然,它在视觉上是一团糟,几乎难以辨认。有时,由于使用了第二种方法,网格单元实际上是半透明的,下面窗口中的文本显示出来。 (再次,不漂亮!)

在我看来,Delphi 2010 的 TDbGrid 和 TStringGrid 在处理透明度的方式上有些不同?

我在 Delphi 的这个领域没有太多经验(事实上,我不知道第二种方法实际上在做什么!)并且希望有人能给我一些关于正在发生的事情以及如何解决它的指示。

TIA!

方法一

  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;

方法二

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;

【问题讨论】:

    标签: delphi


    【解决方案1】:

    在方法 2 中,我会尝试使用 SetBkMode(Handle, OPAQUE);

    更新:我会把它放在 FillRect(B) 之前

    【讨论】:

      【解决方案2】:

      我们总是使用 DrawText 函数来控制对齐(垂直和水平)。 您必须在清理内容之前使用 FillRect(Rect)。

      我从未使用过 SetBkMode(),但我猜你可以不用它。

      【讨论】:

        【解决方案3】:

        我将此作为答案发布(不是),因此我可以包含图片。

        感谢您的建议。使用 OPAQUE 有助于对 TDbGrid 进行初始写入。背景不再流血了!我有点尴尬,我之前没有发现“透明”这个词。

        但是,对单元格的更改仍然无法删除以前的内容,因此它们看起来像下面的屏幕。该死!

        网格内容向下移动了一行,但也保留在它们之前所在的单元格中。

        【讨论】:

        • 更新了我的答案:尝试在SetBkMode(Handle, OPAQUE) 之后执行FillRect(B)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-27
        • 1970-01-01
        • 2011-06-22
        • 2015-06-21
        • 2016-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多