在窗口周围绘制框架的桌面窗口无效

时间:2013-06-25 22:47:56

标签: delphi window draw desktop invalidation

我正在编写一个简单的程序,列出屏幕上显示的每个窗口。我可以从列表中选择一个窗口,用矩形围绕它。我正在将矩形直接绘制到桌面窗口。我之前需要清除画布,因为我想选择我想要的窗口,一次选择一个窗口

我已经尝试使桌面窗口无效,这实际上有效,但它会造成很多闪烁。

InvalidateRect(0, 0, True);

在这种情况下直接在桌面上绘图是否正确?还有其他想法可以避免闪烁吗?

谢谢。

1 个答案:

答案 0 :(得分:5)

通常当您直接绘制到桌面时,防止出现伪影的唯一方法是不断重绘整个屏幕。这可能会变得很重,并且会破坏视频缓存的整个目的。

我见过应用程序不是通过直接绘制到屏幕的画布来实现这一点,而是通过创建4个不同的“边缘”窗口。例如,窗口的顶部,左侧,右侧和底部边缘都有一个窗口,您想要“框架”。顶部和底部窗口的高度为5px,左右边缘的宽度为5px。将这些窗口(没有边框样式)放在窗口边缘周围,为每个窗体着色,例如绿色,然后在窗口周围有绿色边框。

例如

Border around window

  1. 每个窗口的边框样式应为bsNone
  2. 每个窗口的表单样式应为fsStayOnTop
  3. 每个窗口应围绕聚焦形式的每个边缘定位
  4. 使用此方法,您不必担心失效。可以从一个单一的形式做到这一点,但是你必须担心透明度等等。每个边缘使用4个表单可确保用户仍然可以单击焦点表单,而无需任何透明度。

    快速样本......

    单位:uMain.pas

    unit uMain;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages,
      System.SysUtils, System.Variants, System.Classes,
      Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
    
    type
      TfrmMain = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        FTop: TForm;
        FLeft: TForm;
        FRight: TForm;
        FBottom: TForm;
        procedure PositionBorder(const ARect: TRect; const Thickness: Integer;
          const Color: TColor);
        procedure HideBorder;
      public
        function FormRect: TRect;
      end;
    
    var
      frmMain: TfrmMain;
    
    implementation
    
    {$R *.dfm}
    
    procedure TfrmMain.FormCreate(Sender: TObject);
    begin
      //Create each form
      FTop:= TForm.Create(nil);
      FLeft:= TForm.Create(nil);
      FRight:= TForm.Create(nil);
      FBottom:= TForm.Create(nil);
      //Default position
      FTop.Position:= poDefault;
      FBottom.Position:= poDefault;
      FLeft.Position:= poDefault;
      FRight.Position:= poDefault;
      //Border Style
      FTop.BorderStyle:= bsNone;
      FBottom.BorderStyle:= bsNone;
      FLeft.BorderStyle:= bsNone;
      FRight.BorderStyle:= bsNone;
      //Form Style
      FTop.FormStyle:= fsStayOnTop;
      FBottom.FormStyle:= fsStayOnTop;
      FLeft.FormStyle:= fsStayOnTop;
      FRight.FormStyle:= fsStayOnTop;
    end;
    
    procedure TfrmMain.FormDestroy(Sender: TObject);
    begin
      FTop.Free;
      FBottom.Free;
      FLeft.Free;
      FRight.Free;
    end;
    
    procedure TfrmMain.PositionBorder(const ARect: TRect; const Thickness: Integer; const Color: TColor);
    var
      Thick: Integer;
      HalfThick: Integer;
    begin
      Thick:= Thickness;
      if Thick < 1 then Thick:= 1;
      HalfThick:= Thickness div 2;
      if HalfThick < 1 then HalfThick:= 1;
      //Color
      FTop.Color:= Color;
      FBottom.Color:= Color;
      FLeft.Color:= Color;
      FRight.Color:= Color;
      //Thickness
      FTop.Height:= Thick;
      FBottom.Height:= Thick;
      FLeft.Width:= Thick;
      FRight.Width:= Thick;
      //Lengths
      FTop.Width:= ARect.Width + Thick;
      FBottom.Width:= ARect.Width + Thick;
      FLeft.Height:= ARect.Height + Thick;
      FRight.Height:= ARect.Height + Thick;
      //Positions
      FTop.Left:= ARect.Left - HalfThick;
      FTop.Top:= ARect.Top - HalfThick;
      FBottom.Left:= ARect.Left - HalfThick;
      FBottom.Top:= ARect.Bottom + HalfThick;
      FLeft.Left:= ARect.Left - HalfThick;
      FLeft.Top:= ARect.Top - HalfThick;
      FRight.Left:= ARect.Right + HalfThick;
      FRight.Top:= ARect.Top - HalfThick;
      //Show windows
      FTop.Show;
      FBottom.Show;
      FLeft.Show;
      FRight.Show;
    end;
    
    procedure TfrmMain.HideBorder;
    begin
      FLeft.Hide;
      FTop.Hide;
      FRight.Hide;
      FBottom.Hide;
    end;
    
    function TfrmMain.FormRect: TRect;
    begin
      Result.Left:= Left;
      Result.Top:= Top;
      Result.Width:= Width;
      Result.Height:= Height;
    end;
    
    procedure TfrmMain.Button1Click(Sender: TObject);
    begin
      PositionBorder(FormRect, 5, clGreen);
    end;
    
    end.
    

    表格:uMain.dfm

    对象

     frmMain: TfrmMain
      Left = 315
      Top = 113
      Caption = 'frmMain'
      ClientHeight = 204
      ClientWidth = 368
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      OldCreateOrder = False
      Position = poScreenCenter
      OnCreate = FormCreate
      OnDestroy = FormDestroy
      PixelsPerInch = 96
      TextHeight = 13
      object Button1: TButton
        Left = 64
        Top = 80
        Width = 209
        Height = 25
        Caption = 'Button1'
        Default = True
        TabOrder = 0
        OnClick = Button1Click
      end
    end
    

    假设你有一个按钮Button1。这个电话就像......

    PositionBorder(WindowRect, 5, clGreen);
    

    ...其中WindowRect =一个TRect记录,窗口的坐标为“框架”,5是该框架的厚度,clGreen是框架的颜色。