我愿意使用以下代码在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;
请帮帮我。
答案 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的边框,只需在其下方创建一个矩形。