- Make GetSystemMenu respect CS_NOCLOSE.

- EnableMenuItem should not generate WM_WINDOWPOSCHANGING message.
- Make nonclient code check for presence of SC_CLOSE, not CS_NOCLOSE
  window class style.
- Add a test case.
This commit is contained in:
Dmitry Timoshkov 2005-03-30 18:59:27 +00:00 committed by Alexandre Julliard
parent 46d2be988a
commit 9640918917
4 changed files with 70 additions and 8 deletions

View File

@ -380,6 +380,9 @@ HMENU MENU_GetSysMenu( HWND hWnd, HMENU hPopupMenu )
if (hPopupMenu)
{
if (GetClassLongW(hWnd, GCL_STYLE) & CS_NOCLOSE)
DeleteMenu(hPopupMenu, SC_CLOSE, MF_BYCOMMAND);
InsertMenuW( hMenu, -1, MF_SYSMENU | MF_POPUP | MF_BYPOSITION,
(UINT_PTR)hPopupMenu, NULL );
@ -3248,15 +3251,18 @@ UINT WINAPI EnableMenuItem( HMENU hMenu, UINT wItemID, UINT wFlags )
{
if (menu->hSysMenuOwner != 0)
{
RECT rc;
POPUPMENU* parentMenu;
/* Get the parent menu to access*/
if (!(parentMenu = MENU_GetMenu(menu->hSysMenuOwner)))
return (UINT)-1;
/* Refresh the frame to reflect the change*/
SetWindowPos(parentMenu->hWnd, 0, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
/* Refresh the frame to reflect the change */
GetWindowRect(parentMenu->hWnd, &rc);
MapWindowPoints(0, parentMenu->hWnd, (POINT *)&rc, 2);
rc.bottom = 0;
RedrawWindow(parentMenu->hWnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
}
}

View File

@ -2849,6 +2849,47 @@ static void test_showwindow(void)
flush_sequence();
}
static void test_sys_menu(HWND hwnd)
{
HMENU hmenu;
UINT state;
/* test existing window without CS_NOCLOSE style */
hmenu = GetSystemMenu(hwnd, FALSE);
ok(hmenu != 0, "GetSystemMenu error %ld\n", GetLastError());
state = GetMenuState(hmenu, SC_CLOSE, MF_BYCOMMAND);
ok(state != 0xffffffff, "wrong SC_CLOSE state %x\n", state);
ok(!(state & (MF_DISABLED | MF_GRAYED)), "wrong SC_CLOSE state %x\n", state);
EnableMenuItem(hmenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
ok_sequence(WmEmptySeq, "WmEnableMenuItem", FALSE);
state = GetMenuState(hmenu, SC_CLOSE, MF_BYCOMMAND);
ok(state != 0xffffffff, "wrong SC_CLOSE state %x\n", state);
ok((state & (MF_DISABLED | MF_GRAYED)) == MF_GRAYED, "wrong SC_CLOSE state %x\n", state);
EnableMenuItem(hmenu, SC_CLOSE, 0);
ok_sequence(WmEmptySeq, "WmEnableMenuItem", FALSE);
state = GetMenuState(hmenu, SC_CLOSE, MF_BYCOMMAND);
ok(state != 0xffffffff, "wrong SC_CLOSE state %x\n", state);
ok(!(state & (MF_DISABLED | MF_GRAYED)), "wrong SC_CLOSE state %x\n", state);
/* test new window with CS_NOCLOSE style */
hwnd = CreateWindowExA(0, "NoCloseWindowClass", NULL, WS_OVERLAPPEDWINDOW,
100, 100, 200, 200, 0, 0, 0, NULL);
ok (hwnd != 0, "Failed to create overlapped window\n");
hmenu = GetSystemMenu(hwnd, FALSE);
ok(hmenu != 0, "GetSystemMenu error %ld\n", GetLastError());
state = GetMenuState(hmenu, SC_CLOSE, MF_BYCOMMAND);
ok(state == 0xffffffff, "wrong SC_CLOSE state %x\n", state);
DestroyWindow(hwnd);
}
/* test if we receive the right sequence of messages */
static void test_messages(void)
{
@ -2912,6 +2953,9 @@ static void test_messages(void)
SetWindowPos( hwnd, 0, 0, 0, 200, 200, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE );
ok_sequence(WmSWP_ResizePopupSeq, "SetWindowPos:ResizePopup", FALSE );
test_sys_menu(hwnd);
flush_sequence();
DestroyWindow(hwnd);
ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped", FALSE);
@ -4650,6 +4694,10 @@ static BOOL RegisterWindowClasses(void)
cls.lpszClassName = "SimpleWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
cls.style = CS_NOCLOSE;
cls.lpszClassName = "NoCloseWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
cls.style = 0;
cls.hInstance = GetModuleHandleA(0);

View File

@ -891,9 +891,9 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, DWORD style,
hSysMenu = GetSystemMenu(hwnd, FALSE);
state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
/* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
/* Draw a grayed close button if disabled or if SC_CLOSE is not there */
NC_DrawCloseButton (hwnd, hdc, FALSE,
((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
(state & (MF_DISABLED | MF_GRAYED)) || (state == 0xFFFFFFFF));
r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
@ -1451,9 +1451,17 @@ LONG NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam )
break;
case HTSYSMENU:
if (!(GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE))
{
HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
UINT state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
/* If the item close of the sysmenu is disabled or not there do nothing */
if ((state & (MF_DISABLED | MF_GRAYED)) || (state == 0xFFFFFFFF))
break;
SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, lParam );
break;
break;
}
case HTHSCROLL:
SendMessageW( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );

View File

@ -1023,7 +1023,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
wndPtr->userdata = 0;
wndPtr->hIcon = 0;
wndPtr->hIconSmall = 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, 0 ) : 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, (HMENU)-1 ) : 0;
/*
* Correct the window styles.