Patch by Dmitry Timoshkov dmitry@baikal.ru. Take into account CS_NOCLOSE window class style and SC_CLOSE system menu item state while adding MDI system menu buttons and generating WM_SYSCOMMAND messages.
Modified: trunk/reactos/lib/user32/windows/mdi.c

Modified: trunk/reactos/lib/user32/windows/mdi.c
--- trunk/reactos/lib/user32/windows/mdi.c	2005-07-29 23:15:01 UTC (rev 16889)
+++ trunk/reactos/lib/user32/windows/mdi.c	2005-07-29 23:37:11 UTC (rev 16890)
@@ -264,6 +264,20 @@
 #endif
 }
 
+static BOOL is_close_enabled(HWND hwnd, HMENU hSysMenu)
+{
+    if (GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE) return FALSE;
+
+    if (!hSysMenu) hSysMenu = GetSystemMenu(hwnd, FALSE);
+    if (hSysMenu)
+    {
+        UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
+        if (state == 0xFFFFFFFF || (state & (MF_DISABLED | MF_GRAYED)))
+            return FALSE;
+    }
+    return TRUE;
+}
+
 /**********************************************************************
  *			MDI_MenuModifyItem
  */
@@ -1108,14 +1122,14 @@
     if (!(hSysPopup = GetSystemMenu(hChild, FALSE)))
 	return 0;
 
-    AppendMenuA(menu,MF_HELP | MF_BITMAP,
-                   SC_MINIMIZE, (LPSTR)(DWORD)HBMMENU_MBAR_MINIMIZE ) ;
-    AppendMenuA(menu,MF_HELP | MF_BITMAP,
-                   SC_RESTORE, (LPSTR)(DWORD)HBMMENU_MBAR_RESTORE );
+    AppendMenuW(menu, MF_HELP | MF_BITMAP,
+                SC_MINIMIZE, (LPCWSTR)HBMMENU_MBAR_MINIMIZE ) ;
+    AppendMenuW(menu, MF_HELP | MF_BITMAP,
+                SC_RESTORE, (LPCWSTR)HBMMENU_MBAR_RESTORE );
+    AppendMenuW(menu, MF_HELP | MF_BITMAP,
+                SC_CLOSE, is_close_enabled(hChild, hSysPopup) ?
+                (LPCWSTR)HBMMENU_MBAR_CLOSE : (LPCWSTR)HBMMENU_MBAR_CLOSE_D );
 
-    AppendMenuA(menu,MF_HELP | MF_BITMAP,
-                   SC_CLOSE, (LPSTR)(DWORD)HBMMENU_MBAR_CLOSE );
-
     /* The system menu is replaced by the child icon */
     hIcon = (HICON)GetClassLongW(hChild, GCL_HICONSM);
     if (!hIcon)
@@ -1612,13 +1626,14 @@
                     if( !ci->hwndChildMaximized ) break;
                     switch( id )
                     {
+                    case SC_CLOSE:
+                        if (!is_close_enabled(ci->hwndActiveChild, 0)) break;
                     case SC_SIZE:
                     case SC_MOVE:
                     case SC_MINIMIZE:
                     case SC_MAXIMIZE:
                     case SC_NEXTWINDOW:
                     case SC_PREVWINDOW:
-                    case SC_CLOSE:
                     case SC_RESTORE:
                         return SendMessageW( ci->hwndChildMaximized, WM_SYSCOMMAND,
                                              wParam, lParam);
@@ -2033,8 +2048,12 @@
                 break;
             case VK_F4:
             case VK_RBUTTON:
-                wParam = SC_CLOSE;
-                break;
+                if (is_close_enabled(ci->hwndActiveChild, 0))
+                {
+                    wParam = SC_CLOSE;
+                    break;
+                }
+                /* fall through */
             default:
                 return 0;
             }