【发布时间】:2017-06-13 12:42:24
【问题描述】:
我需要一个表单来禁用菜单关闭按钮(也禁用 Alt-F4 关闭),所以我使用了CS_NOCLOSE 类样式。如果我在CreateParams 中设置它,它会按预期工作:
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WindowClass.style := Params.WindowClass.style or CS_NOCLOSE;
end;
关闭按钮被禁用,您无法使用 ALT+F4 关闭窗口(我有自己的关闭按钮)。
现在我添加了一个标志:FNoCloseButton,最初设置为False。
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
if FNoCloseButton then
Params.WindowClass.style := Params.WindowClass.style or CS_NOCLOSE;
end;
创建表格后,我有这个:
procedure TForm1.Button1Click(Sender: TObject);
begin
FNoCloseButton := True;
RecreateWnd;
end;
点击 Button1 后,窗口重新创建,但 CS_NOCLOSE 现在无效,被忽略。
为什么会有这种行为? Window类style创建后为什么不能更改? (我想我可以,因为SetClassLong api 存在)
我还尝试了SetClassLong:
procedure TForm1.Button2Click(Sender: TObject);
begin
SetClassLong(Self.Handle, GCL_STYLE, GetClassLong(Self.Handle, GCL_STYLE) or CS_NOCLOSE);
DrawMenuBar(Self.Handle); // Must call this to invalidate
end;
这行得通。关闭被禁用(加上 Alt-F4),但系统菜单项“关闭”是可见的,我可以通过单击它来关闭窗口。所以SetClassLong 的行为有点不同。
我错过了什么?
【问题讨论】:
-
@IInspectable,谢谢。我会调查的。
-
我无法理解的是为什么调用
DestroyWindow(并重新创建它)的RecreateWnd不会使用CS_NOCLOSE。 -
我也没有,但也许 Raymond Chen 将修改此类样式的代码放在 斜体 中是有原因的。