2013-06-25 118 views
2

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

我试图使桌面窗口无效,这实际上工作,但它使很多闪烁。

InvalidateRect(0, 0, True); 

在这种情况下直接在桌面上绘制是否正确?任何其他的想法,以避免闪烁?

谢谢。

+1

'GetWindow(GetDesktopWindow,0)'?寻找桌面的兄弟姐妹?曾经测试过GetWindow的返回? –

+0

@SertacAkyuz你是对的好先生,我的错不复制我的实际代码... – ThePirateCat

+0

@ThePirate - 哦!我想知道它是否工作,因为InvalidateRect与HWND_DESKTOP没有问题,它也是0.但是没关系。请始终发布实际的代码;)。 –

回答

5

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

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

例如

Border around window

  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. 

表: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是帧的颜色。

+0

呃,这实际上是一个很好的选择,我只是做了一个例子,它工作得很好。 PS:感谢您的快速代码:) – ThePirateCat

+0

...我再次更新了代码,不依赖于4个创建的窗口,此版本在一个单元中处理整个位。由于某些原因,虽然第一次点击并不能正常工作,但在其余时间内仍能正常工作。 –

+0

我终于使用这个技巧,谢谢你的选择! – ThePirateCat