代码之家  ›  专栏  ›  技术社区  ›  RobertFrank Picarus

Delphi2010与Delphi7在画布透明度上有所不同?

  •  3
  • RobertFrank Picarus  · 技术社区  · 16 年前

    我将一些非常古老的代码从Delph7移植到Delphi2010 对现有代码库进行一些更改 因为通常的原因。

    第一:对于那些还没有跳下去的人来说,这是个好消息:它并没有看上去那么令人畏惧!我真的很高兴(&惊讶)1000000多行代码的移动如此简单。回到领先地位真让人宽慰!Delphi2010有很多很好的增强功能。

    但是,我对一些tstringgrids和tdbgrids的后代有一个表面上的问题。

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

    第一种方法用于调整文本。在Delphi2010中运行时,新文本 不合理的文本 二者都 出现在写入的单元格中。当然,视觉上是一团糟,几乎难以辨认。有时,由于使用了第二种方法,网格单元实际上是半透明的,下面的窗口中的文本显示通过。(再说一遍,不漂亮!)

    在我看来,Delphi2010的tdbgrid和tstringgrid在处理透明度方面有一些不同?

    在Delphi这个领域我没有太多的经验(事实上,我不知道第二种方法实际上在做什么!)希望有人能给我一些线索,告诉我发生了什么以及如何解决。

    蒂亚!

    方法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;
    

    方法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;
    
    3 回复  |  直到 15 年前
        1
  •  1
  •   Francesca    16 年前

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

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

        2
  •  0
  •   Daniel Luyo    16 年前

    我们总是使用drawtext函数来控制对齐(垂直和水平)。 在清理内容之前,必须使用fillRect(rect)。

    我从来没有用过setbkmode(),但我想你可以不用它。

        3
  •  0
  •   RobertFrank Picarus    15 年前

    我把这个贴出来作为一个答案(不是),这样我就可以包含一个图片。

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

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

    网格内容向下移动了一行,但仍保留在先前所在的单元格中。