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

The*_*Cat 2 delphi desktop window draw invalidation

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

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

InvalidateRect(0, 0, True);
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Jer*_*dge 5

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

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

例如:

窗口周围的边框

  1. 每个窗口的边框样式都应该是 bsNone
  2. 每个窗口的表单样式都应该是 fsStayOnTop
  3. 每个窗口应位于聚焦形式的每个边缘周围

使用此方法,您不必担心失效.可以从一个单一的形式做到这一点,但是你必须担心透明度等等.每个边缘使用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.
Run Code Online (Sandbox Code Playgroud)

形式: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
Run Code Online (Sandbox Code Playgroud)

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

PositionBorder(WindowRect, 5, clGreen);
Run Code Online (Sandbox Code Playgroud)

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