Delphi无边框和无标题应用程序

时间:2012-01-16 18:24:47

标签: delphi delphi-xe2

我愿意使用以下代码在Delphi XE2中无边界和无标题地设计一个应用程序:

  BorderIcons = []
  BorderStyle = bsNone

但问题是右键单击任务栏上的应用程序没有菜单,就像上图中一样。然后我在FormShow事件上尝试了以下代码,但还有另一个问题。在左侧和左侧B侧创建一个边框。代码是:

procedure TForm1.FormShow(Sender: TObject);
var
  r: TRect;
begin
  r := ClientRect;
  OffsetRect(r, 0, GetSystemMetrics(SM_CYCAPTION));
  OffsetRect(r, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
  SetWindowRgn(Handle,
  CreateRectRgn(
  r.Left, r.Top,
  ClientWidth + r.Left, ClientHeight + r.Top), True);

end;

请帮帮我。

4 个答案:

答案 0 :(得分:7)

简单的解决方案不是首先删除系统菜单。请注意,系统菜单是应用程序中缺少的菜单的正式名称。

使您的.dfm文件看起来像这样:

BorderIcons = [biSystemMenu]
BorderStyle = bsNone

摆脱FormShow代码 - 不需要它。

好吧,看起来我的实验中的一些代码混乱让我感到困惑。这是有效的。

完全按照.dfm格式执行的操作:

BorderIcons = []
BorderStyle = bsNone

然后使用CreateParams

添加系统菜单
TForm1 = class(TForm)
protected
  procedure CreateParams(var Params: TCreateParams); override;
end;
...
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style or WS_SYSMENU;
end;

答案 1 :(得分:5)

procedure TForm1.FormCreate(Sender: TObject);
begin
  BorderStyle := bsNone;
  SetWindowLong(Handle, GWL_STYLE, 
      WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_SYSMENU);
  SetWindowLong(Handle, GWL_EXSTYLE, WS_EX_CONTROLPARENT or WS_EX_APPWINDOW);
end;

使用此解决方案,您不需要OnShow处理程序中的代码。

上面的代码可以随时调用(不只是在OnCreate中),它可以用来改变正在运行的表单的行为(如果表单只包含WS_VISIBLE到窗口样式已经可见了)。

如果您希望行为在表单的生命周期中生效,最好在覆盖CreateParams(其中表单样式由VCL应用)中设置标志。这也将考虑到形式的重新创建。不要为此解决方案从OI设置任何表单属性,所有标志都在代码中显式设置:

type
  TForm1 = class(TForm)
    ..
  protected
    procedure CreateParams(var Params: TCreateParams); override;

..

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := WS_POPUP or WS_CLIPSIBLINGS or WS_CLIPCHILDREN or WS_SYSMENU;
  Params.ExStyle := WS_EX_CONTROLPARENT or WS_EX_APPWINDOW;
end;

答案 2 :(得分:3)

通过简单地接管整个窗口的绘画,您可以看到一个看起来没有标题栏或标准标题的窗口:

创建一个新的空应用程序。将此代码用于表单:

unit ncUnit1;

interface

// XE2 uses clause
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,      
  Vcl.Graphics,   Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
// If you're not using XE2 take out the prefixes (WinApi, Vcl, System, etc)

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  protected
    procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;
    procedure SolidColorNcPaint(solidColor,frameColor:TColor);
    procedure Resizing(State: TWindowState); override;


  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.WMNCPaint(var Message: TWMNCPaint);
begin
  SolidColorNcPaint(clBtnFace,clBtnFace);
end;

procedure TForm1.Resizing(State: TWindowState);
begin
  inherited;
  PostMessage(Self.Handle,WM_NCPAINT,0,0); {force initial paint}
end;

procedure TForm1.SolidColorNcPaint(solidColor,frameColor:TColor);
var
 aBorder:Integer;
 ahdc : HDC;
begin
 aBorder := GetSystemMetrics(SM_CYSIZEFRAME);
 canvas.Lock;
 ahdc := GetWindowDC(Handle);
 canvas.Handle := ahdc;
 ExcludeClipRect(canvas.Handle, aBorder, 0, Width-aBorder, Height - aBorder) ;
 Canvas.Brush.Style := bsSolid;
 Canvas.Brush.Color := frameColor;
 Canvas.Pen.Color := solidColor;
 Canvas.Rectangle( 0,0, Width,Height);
 ReleaseDC(Self.Handle, ahdc);
 canvas.Handle := 0;
 canvas.Unlock;
end;


end.

您在上面看到的只是足够的代码来重绘窗口的非客户区域上的纯色,而不是完全删除它。根据您想要的自定义窗口的样式,您应该在表单上呈现您想要的任何内容。如果您不想要“关闭”按钮,则删除关闭按钮,如果您不想调整大小行为,请删除调整大小行为。如果您设置FormStyle=fsDialog加上上面的代码,您将获得一个窗口,其中包含一个完整的自定义绘制标题区域(您可以将任何内容放入其中)。如果您实际上根本不希望标题区域存在,您可以修改上面的代码来实现它。

答案 3 :(得分:2)

您可以执行David所说的内容和/或同时查看: SetWindowRgn API。

如果仅使用SetWindowRgn,则不必删除TForm的边框,只需在其下方创建一个矩形。