我的问题是, 窗体的 TransparentColor 属性会在很大程度上影响到窗体的绘制效率, 有办法改善吗?有过经验的朋友应该知道, 如果想要做异形窗体(简单的比如四周圆角)就要用到窗体的 TransparentColor 属性.大家可以做一个实验, 就建一个空白 Form, 并把它的 TransparentColor 属性设置为 True. 同时与 TransparentColor 为 False 的空白窗体做比较, 在窗体最大化或拖动改变大小时, 绘制的效率相差很大. TransparentColor 为 True 的窗体的绘制效率低, 闪烁比较严重. 这还只是实验用的空白窗体, 如果再多放些控件的话, 效果就更不用说了.所以问题就是, 当设置了窗体的 TransparentColor 属性为 True 时, 有什么办法能改善这个窗体的绘制效率吗?请大家帮帮忙, 谢谢!

解决方案 »

  1.   

    猜测透明效果的实现,就是先取得背景,再结合form里的东西重新画到from上的
    这样的效率肯定就会低了
      

  2.   

    Form.DoubleBuffer := true;另外,使用GDI+处理。
      

  3.   

    @sz_haitao
    你解释得没错, 但只是重述了我的问题现象, 而我要的是解决方案.@mjp1234airen4385
    DoubleBuffered 属性并不能解决问题, 如果你先自试过就不会这样回答了.
    "另外,使用GDI+处理。", 能详细说说应该怎么处理吗?
    另外, 再补充一个实验参数, 要设置一下 TransparentColorValue, 不要用默认值, 可以设置成常用做透明色的紫色(clFuchsia)或绿色(clLime). 不然实验效果不明显. 可能 TForm 对默认值做了特别处理.
      

  4.   

    如果你只是想实现四周圆角的窗体,可以这样
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        procedure CreateParams(var Params: TCreateParams); override;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.CreateParams(var Params: TCreateParams);
    begin
      inherited CreateParams(Params);
      Params.Style   :=  (Params.Style or   WS_POPUP)   xor   (ws_dlgframe)
        xor WS_THICKFRAME;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      hr :thandle;
    begin
      hr:=createroundrectrgn(0,0,width,height,60,60);
      setwindowrgn(handle,hr,true);
    end;end.
      

  5.   

    @wintergoes
    单是"四周圆角"并不能满足我的要求, 不过 SetWindowRgn 却是个很好的入口, 之前我也尝试过, 裁剪窗体区域要比 Delphi 的计算背景绘图方式的所表现出来的效率好很多. 谢谢.根据这个思路, 那现在要解决的问题就是, 根据图像中指定的"透明色"来计算出非透明部分 Rgn 区域, 有谁做过这个的吗? 给个现成的算法好省我些时间, 我就再次谢谢了.
      

  6.   

    const
      RgnPoints:array[1..10]   of   TPoint=
      ((x:203;y:22),(x:157;y:168),(x:3;y:168),(x:128;y:257),
      (x:81;y:402),(x:203;y:334),(x:325;y:422),(x:278;y:257),
      (x:402;y:168),(x:249;y:168));//????
      LinePoints:array[1..11]   of   Tpoint=
      ((x:199;y:0),(x:154;y:146),(x:2;y:146),(x:127;y:235),
      (x:79;y:377),(x:198;y:308),(x:320;Y:396),(x:272;y:234),
      (x:396;y:146),(x:244;y:146),(x:199;Y:0));procedure TForm1.FormCreate(Sender: TObject);
    var   Rgn:HRGN;
    begin
      Setwindowpos(Form1.Handle,HWND_TOPMOST,Form1.Left,form1.Top,Form1.Width,Form1.Height,0);
      Rgn:=CreatepolygonRgn(Rgnpoints,High(RgnPoints),ALTERNATE);
      SetWindowRgn(Handle,rgn,True);
      Form1.color:=clgreen;
    end;这是曾经有人csdn贴的代码实现一个五角星的窗口不知对你有没有用
    我觉得画不规则窗体,用SetWindowRgn和设置透明色是两个思路
    计算出显示部分 Rgn 区域是不是可以用其他办法,而不需要用颜色来区别
    另外下面是TCustomForm中实现窗体透明或半透明的部分,看不出对默认色进行了处理
    procedure TCustomForm.SetLayeredAttribs;
    const
      cUseAlpha: array [Boolean] of Integer = (0, LWA_ALPHA);
      cUseColorKey: array [Boolean] of Integer = (0, LWA_COLORKEY);
    var
      AStyle: Integer;
    begin
      if not (csDesigning in ComponentState) and
        (Assigned(SetLayeredWindowAttributes)) and HandleAllocated then
      begin
        AStyle := GetWindowLong(Handle, GWL_EXSTYLE);
        if FAlphaBlend or FTransparentColor then
        begin
          if (AStyle and WS_EX_LAYERED) = 0 then
            SetWindowLong(Handle, GWL_EXSTYLE, AStyle or WS_EX_LAYERED);
          SetLayeredWindowAttributes(Handle, FTransparentColorValue, FAlphaBlendValue,
            cUseAlpha[FAlphaBlend] or cUseColorKey[FTransparentColor]);
        end
        else
        begin
          SetWindowLong(Handle, GWL_EXSTYLE, AStyle and not WS_EX_LAYERED);
          RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN);
        end;
      end;
    end;
      

  7.   

    procedure TCustomForm.SetLayeredAttribs;
    const
      cUseAlpha: array [Boolean] of Integer = (0, LWA_ALPHA);
      cUseColorKey: array [Boolean] of Integer = (0, LWA_COLORKEY);
    var
      AStyle: Integer;
    begin
      if not (csDesigning in ComponentState) and
        (Assigned(SetLayeredWindowAttributes)) and HandleAllocated then
      begin
        AStyle := GetWindowLong(Handle, GWL_EXSTYLE);
        if FAlphaBlend or FTransparentColor then
        begin
          if (AStyle and WS_EX_LAYERED) = 0 then
            SetWindowLong(Handle, GWL_EXSTYLE, AStyle or WS_EX_LAYERED);
          SetLayeredWindowAttributes(Handle, FTransparentColorValue, FAlphaBlendValue,
            cUseAlpha[FAlphaBlend] or cUseColorKey[FTransparentColor]);
        end
        else
        begin
          SetWindowLong(Handle, GWL_EXSTYLE, AStyle and not WS_EX_LAYERED);
          RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN);
        end;
      end;
    end;这段代码不全,能发个全的吗?
    [Error] Unit1.pas(32): Undeclared identifier: 'ComponentState'
    有很多这样的报错?