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.
This commit is contained in:
Huw Davies 2004-02-17 20:29:05 +00:00 committed by Alexandre Julliard
parent 41596e8031
commit 14743a0f3b
4 changed files with 85 additions and 8 deletions

View File

@ -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); 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 */ lpmenu->Height = 0; /* Make sure we recalculate the size */
} }
SetWindowLongW( hWnd, GWL_ID, (LONG_PTR)hMenu ); 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; 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.@) * GetSubMenu (USER32.@)

View File

@ -296,6 +296,44 @@ static struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */
{ WM_SETCURSOR, sent|parent }, { WM_SETCURSOR, sent|parent },
{ 0 } { 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 int sequence_cnt, sequence_size;
static struct message* sequence; static struct message* sequence;
@ -380,6 +418,7 @@ static void test_messages(void)
{ {
HWND hwnd, hparent, hchild; HWND hwnd, hparent, hchild;
HWND hchild2, hbutton; HWND hchild2, hbutton;
HMENU hmenu;
hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW, hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
100, 100, 200, 200, 0, 0, 0, NULL); 100, 100, 200, 200, 0, 0, 0, NULL);
@ -420,6 +459,30 @@ static void test_messages(void)
DestroyWindow(hchild); DestroyWindow(hchild);
ok_sequence(WmDestroyChildSeq, "DestroyWindow:child"); 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) static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

View File

@ -141,6 +141,8 @@ extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ); /* windows/defwnd.c
extern BOOL FOCUS_MouseActivate( HWND hwnd ); extern BOOL FOCUS_MouseActivate( HWND hwnd );
extern BOOL MENU_SetMenu(HWND, HMENU);
/* check if hwnd is a broadcast magic handle */ /* check if hwnd is a broadcast magic handle */
inline static BOOL is_broadcast( HWND hwnd ) inline static BOOL is_broadcast( HWND hwnd )
{ {

View File

@ -1185,7 +1185,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
if (((wndPtr->dwStyle & (WS_CAPTION|WS_CHILD)) == WS_CAPTION) || if (((wndPtr->dwStyle & (WS_CAPTION|WS_CHILD)) == WS_CAPTION) ||
(wndPtr->dwExStyle & WS_EX_APPWINDOW)) (wndPtr->dwExStyle & WS_EX_APPWINDOW))
{ {
if (cs->hMenu) SetMenu(hwnd, cs->hMenu); if (cs->hMenu) MENU_SetMenu(hwnd, cs->hMenu);
else else
{ {
LPCSTR menuName = (LPCSTR)GetClassLongA( hwnd, GCL_MENUNAME ); LPCSTR menuName = (LPCSTR)GetClassLongA( hwnd, GCL_MENUNAME );
@ -1196,7 +1196,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
else else
cs->hMenu = HMENU_32(LoadMenu16(HINSTANCE_16(cs->hInstance),menuName)); 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 );
} }
} }
} }