I need to disable just the close button (minimize and maximize should be allowed) temporarily.
Every solution I\'ve tried disables all the buttons
Using Win32 API, you can do this the following way:
[DllImport("User32.dll")]
private static extern uint GetClassLong(IntPtr hwnd, int nIndex);
[DllImport("User32.dll")]
private static extern uint SetClassLong(IntPtr hwnd, int nIndex, uint dwNewLong);
private const int GCL_STYLE = -26;
private const uint CS_NOCLOSE = 0x0200;
private void Form1_Load(object sender, EventArgs e)
{
var style = GetClassLong(Handle, GCL_STYLE);
SetClassLong(Handle, GCL_STYLE, style | CS_NOCLOSE);
}
You will need to use GetClassLong / SetClassLong to enable the CS_NOCLOSE style. You then can remove it with the same operations, just use (style & ~CS_NOCLOSE) in SetClassLongPtr.
Actually, you can do this in WPF apps as well (yeah, I know, the question is about WinForms, but maybe someone will need this some day):
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
var hwnd = new WindowInteropHelper(this).Handle;
var style = GetClassLong(hwnd, GCL_STYLE);
SetClassLong(hwnd, GCL_STYLE, style | CS_NOCLOSE);
}
Still, you should consider what others have suggested: just show a MessageBox or another kind of message to indicate that user should not close the window right now.
Edit: Since window class is just a UINT, you can use GetClassLong and SetClassLong functions instead of GetClassLongPtr and SetClassLongPtr (as says MSDN):
If you are retrieving a pointer or a handle, this function has been superseded by the GetClassLongPtr function. (Pointers and handles are 32 bits on 32-bit Windows and 64 bits on 64-bit Windows.)
This resolves the problem described by Cody Gray regarding the absense of *Ptr funcs in 32-bit OS.