去的方法永久禁用关闭按钮是设置CS_NOCLOSE style对于窗体的窗口类。要从 WinForms 应用程序执行此操作,您需要覆盖表单的CreateParams财产并添加SC_NOCLOSE
标志使用|
运算符,例如:
protected override CreateParams CreateParams
{
get
{
const int CS_NOCLOSE = 0x200;
CreateParams cp = base.CreateParams;
cp.ClassStyle = cp.ClassStyle | CS_NOCLOSE;
return cp;
}
}
不过,这是一个永久的解决方案,因为您无法即时更新窗口类样式。您必须销毁并重新创建窗口类。
但是,您可以禁用系统菜单中的“关闭”命令,这也会自动禁用标题栏中的关闭按钮。
internal static class NativeMethods
{
public const int SC_CLOSE = 0xF060;
public const int MF_BYCOMMAND = 0;
public const int MF_ENABLED = 0;
public const int MF_GRAYED = 1;
[DllImport("user32.dll")]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool revert);
[DllImport("user32.dll")]
public static extern int EnableMenuItem(IntPtr hMenu, int IDEnableItem, int enable);
}
public class MyForm : Form
{
// ...
// If "enable" is true, the close button will be enabled (the default state).
// If "enable" is false, the Close button will be disabled.
bool SetCloseButton(bool enable)
{
IntPtr hMenu = NativeMethods.GetSystemMenu(this.Handle, false);
if (hMenu != IntPtr.Zero)
{
NativeMethods.EnableMenuItem(hMenu,
NativeMethods.SC_CLOSE,
NativeMethods.MF_BYCOMMAND | (enable ? NativeMethods.MF_ENABLED : NativeMethods.MF_GRAYED));
}
}
}
请注意,这实际上是一个瞬态操作。如果你这样做anything这会导致系统菜单被框架修改(例如最大化或最小化窗体),您的修改将被删除。更多详细信息请参见我的相关答案在这里。这通常是一个问题,也是您为什么更愿意使用第一个解决方案的原因。但在这种情况下,由于您想要动态禁用和重新启用,所以这没什么大不了的。
最后,请注意您的提议与事实背道而驰对话框的 Windows UI 指南。他们说,本质上,用户希望看到一个关闭按钮,它的存在给了他们一种安全感,让他们总是可以安全地“摆脱”屏幕上弹出的任何内容。因此,您不应该禁用它。它确实将进度对话框作为例外调用,但它接着说进度对话框应该始终有一个允许中止操作的“取消”按钮。在这种情况下,您只需使标题栏中的关闭按钮调用此“取消”按钮即可,无需禁用它。