Commit 14743a0f authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

SetMenu should always call SetWindowPos whether the window is visible

or not. However we shouldn't call SWP from CreateWindowEx. Added a test for this behaviour.
parent 41596e80
......@@ -3758,9 +3758,12 @@ HMENU WINAPI GetMenu( HWND hWnd )
/**********************************************************************
* SetMenu (USER32.@)
* MENU_SetMenu
*
* Helper for SetMenu. Also called by WIN_CreateWindowEx to avoid the
* SetWindowPos call that would result if SetMenu were called directly.
*/
BOOL WINAPI SetMenu( HWND hWnd, HMENU hMenu )
BOOL MENU_SetMenu( HWND hWnd, HMENU hMenu )
{
TRACE("(%p, %p);\n", hWnd, hMenu);
......@@ -3784,14 +3787,23 @@ BOOL WINAPI SetMenu( HWND hWnd, HMENU hMenu )
lpmenu->Height = 0; /* Make sure we recalculate the size */
}
SetWindowLongW( hWnd, GWL_ID, (LONG_PTR)hMenu );
if (IsWindowVisible(hWnd))
SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
return TRUE;
}
/**********************************************************************
* SetMenu (USER32.@)
*/
BOOL WINAPI SetMenu( HWND hWnd, HMENU hMenu )
{
if(!MENU_SetMenu(hWnd, hMenu))
return FALSE;
SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
return TRUE;
}
/**********************************************************************
* GetSubMenu (USER32.@)
......
......@@ -296,6 +296,44 @@ static struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */
{ WM_SETCURSOR, sent|parent },
{ 0 }
};
/* SetMenu for NonVisible windows with size change*/
static struct message WmSetMenuNonVisibleSizeChangeSeq[] = {
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
{ WM_NCCALCSIZE, sent|wparam, 1 },
{ WM_WINDOWPOSCHANGED, sent|wparam, 0 },
{ WM_MOVE, sent },
{ WM_SIZE, sent },
{ 0 }
};
/* SetMenu for NonVisible windows with no size change */
static struct message WmSetMenuNonVisibleNoSizeChangeSeq[] = {
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
{ WM_NCCALCSIZE, sent|wparam, 1 },
{ WM_WINDOWPOSCHANGED, sent|wparam, 0 },
{ 0 }
};
/* SetMenu for Visible windows with size change */
static struct message WmSetMenuVisibleSizeChangeSeq[] = {
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
{ WM_NCCALCSIZE, sent|wparam, 1 },
{ WM_NCPAINT, sent|wparam, 1 },
{ WM_GETTEXT, sent },
{ WM_ACTIVATE, sent },
{ WM_WINDOWPOSCHANGED, sent|wparam, 0 },
{ WM_MOVE, sent },
{ WM_SIZE, sent },
{ 0 }
};
/* SetMenu for Visible windows with no size change */
static struct message WmSetMenuVisibleNoSizeChangeSeq[] = {
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
{ WM_NCCALCSIZE, sent|wparam, 1 },
{ WM_NCPAINT, sent|wparam, 1 },
{ WM_GETTEXT, sent },
{ WM_ACTIVATE, sent },
{ WM_WINDOWPOSCHANGED, sent|wparam, 0 },
{ 0 }
};
static int sequence_cnt, sequence_size;
static struct message* sequence;
......@@ -380,6 +418,7 @@ static void test_messages(void)
{
HWND hwnd, hparent, hchild;
HWND hchild2, hbutton;
HMENU hmenu;
hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
100, 100, 200, 200, 0, 0, 0, NULL);
......@@ -420,6 +459,30 @@ static void test_messages(void)
DestroyWindow(hchild);
ok_sequence(WmDestroyChildSeq, "DestroyWindow:child");
DestroyWindow(hchild2);
DestroyWindow(hbutton);
DestroyWindow(hparent);
flush_sequence();
/* Message sequence for SetMenu */
hmenu = CreateMenu();
ok (hmenu != 0, "Failed to create menu\n");
ok (InsertMenuA(hmenu, -1, MF_BYPOSITION, 0x1000, "foo"), "InsertMenu failed\n");
hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
100, 100, 200, 200, 0, hmenu, 0, NULL);
ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
ok (SetMenu(hwnd, 0), "SetMenu");
ok_sequence(WmSetMenuNonVisibleSizeChangeSeq, "SetMenu:NonVisibleSizeChange");
ok (SetMenu(hwnd, 0), "SetMenu");
ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq, "SetMenu:NonVisibleNoSizeChange");
ShowWindow(hwnd, TRUE);
flush_sequence();
ok (SetMenu(hwnd, 0), "SetMenu");
ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange");
ok (SetMenu(hwnd, hmenu), "SetMenu");
ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange");
DestroyWindow(hwnd);
}
static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
......
......@@ -141,6 +141,8 @@ extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ); /* windows/defwnd.c
extern BOOL FOCUS_MouseActivate( HWND hwnd );
extern BOOL MENU_SetMenu(HWND, HMENU);
/* check if hwnd is a broadcast magic handle */
inline static BOOL is_broadcast( HWND hwnd )
{
......
......@@ -1185,7 +1185,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
if (((wndPtr->dwStyle & (WS_CAPTION|WS_CHILD)) == WS_CAPTION) ||
(wndPtr->dwExStyle & WS_EX_APPWINDOW))
{
if (cs->hMenu) SetMenu(hwnd, cs->hMenu);
if (cs->hMenu) MENU_SetMenu(hwnd, cs->hMenu);
else
{
LPCSTR menuName = (LPCSTR)GetClassLongA( hwnd, GCL_MENUNAME );
......@@ -1196,7 +1196,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
else
cs->hMenu = HMENU_32(LoadMenu16(HINSTANCE_16(cs->hInstance),menuName));
if (cs->hMenu) SetMenu( hwnd, cs->hMenu );
if (cs->hMenu) MENU_SetMenu( hwnd, cs->hMenu );
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment