user32: Check for invalid menu handle passed to TrackPopupMenu and TrackPopupMenuEx.
This commit is contained in:
parent
29bd889cf8
commit
366334c2fa
|
@ -3447,6 +3447,40 @@ track_menu:
|
||||||
MENU_ExitTracking( hwnd );
|
MENU_ExitTracking( hwnd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* TrackPopupMenuEx (USER32.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
|
||||||
|
HWND hWnd, LPTPMPARAMS lpTpm )
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
|
TRACE("hmenu %p flags %04x (%d,%d) hwnd %p lpTpm %p rect %s\n",
|
||||||
|
hMenu, wFlags, x, y, hWnd, lpTpm,
|
||||||
|
lpTpm ? wine_dbgstr_rect( &lpTpm->rcExclude) : "-" );
|
||||||
|
|
||||||
|
/* Parameter check */
|
||||||
|
/* FIXME: this check is performed several times, here and in the called
|
||||||
|
functions. That could be optimized */
|
||||||
|
if (!MENU_GetMenu( hMenu ))
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_MENU_HANDLE );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MENU_InitTracking(hWnd, hMenu, TRUE, wFlags);
|
||||||
|
|
||||||
|
/* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
|
||||||
|
if (!(wFlags & TPM_NONOTIFY))
|
||||||
|
SendMessageW( hWnd, WM_INITMENUPOPUP, (WPARAM)hMenu, 0);
|
||||||
|
|
||||||
|
if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
|
||||||
|
ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
|
||||||
|
lpTpm ? &lpTpm->rcExclude : NULL );
|
||||||
|
MENU_ExitTracking(hWnd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* TrackPopupMenu (USER32.@)
|
* TrackPopupMenu (USER32.@)
|
||||||
|
@ -3456,35 +3490,9 @@ track_menu:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI TrackPopupMenu( HMENU hMenu, UINT wFlags, INT x, INT y,
|
BOOL WINAPI TrackPopupMenu( HMENU hMenu, UINT wFlags, INT x, INT y,
|
||||||
INT nReserved, HWND hWnd, const RECT *lpRect )
|
INT nReserved, HWND hWnd, const RECT *lpRect )
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
return TrackPopupMenuEx( hMenu, wFlags, x, y, hWnd, NULL);
|
||||||
|
|
||||||
TRACE("hmenu %p flags %04x (%d,%d) reserved %d hwnd %p rect %s\n",
|
|
||||||
hMenu, wFlags, x, y, nReserved, hWnd, wine_dbgstr_rect(lpRect));
|
|
||||||
|
|
||||||
MENU_InitTracking(hWnd, hMenu, TRUE, wFlags);
|
|
||||||
|
|
||||||
/* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
|
|
||||||
if (!(wFlags & TPM_NONOTIFY))
|
|
||||||
SendMessageW( hWnd, WM_INITMENUPOPUP, (WPARAM)hMenu, 0);
|
|
||||||
|
|
||||||
if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
|
|
||||||
ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd, lpRect );
|
|
||||||
MENU_ExitTracking(hWnd);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* TrackPopupMenuEx (USER32.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
|
|
||||||
HWND hWnd, LPTPMPARAMS lpTpm )
|
|
||||||
{
|
|
||||||
FIXME("not fully implemented\n" );
|
|
||||||
return TrackPopupMenu( hMenu, wFlags, x, y, 0, hWnd,
|
|
||||||
lpTpm ? &lpTpm->rcExclude : NULL );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -140,12 +140,25 @@ static int MOD_odheight;
|
||||||
static SIZE MODsizes[MOD_NRMENUS]= { {MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE},
|
static SIZE MODsizes[MOD_NRMENUS]= { {MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE},
|
||||||
{MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE}};
|
{MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE}};
|
||||||
static int MOD_GotDrawItemMsg = FALSE;
|
static int MOD_GotDrawItemMsg = FALSE;
|
||||||
|
static int gflag_initmenupopup,
|
||||||
|
gflag_entermenuloop,
|
||||||
|
gflag_initmenu;
|
||||||
|
|
||||||
/* wndproc used by test_menu_ownerdraw() */
|
/* wndproc used by test_menu_ownerdraw() */
|
||||||
static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg,
|
static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg,
|
||||||
WPARAM wparam, LPARAM lparam)
|
WPARAM wparam, LPARAM lparam)
|
||||||
{
|
{
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
|
case WM_INITMENUPOPUP:
|
||||||
|
gflag_initmenupopup++;
|
||||||
|
break;
|
||||||
|
case WM_ENTERMENULOOP:
|
||||||
|
gflag_entermenuloop++;
|
||||||
|
break;
|
||||||
|
case WM_INITMENU:
|
||||||
|
gflag_initmenu++;
|
||||||
|
break;
|
||||||
case WM_MEASUREITEM:
|
case WM_MEASUREITEM:
|
||||||
{
|
{
|
||||||
MEASUREITEMSTRUCT* pmis = (MEASUREITEMSTRUCT*)lparam;
|
MEASUREITEMSTRUCT* pmis = (MEASUREITEMSTRUCT*)lparam;
|
||||||
|
@ -2628,6 +2641,113 @@ static void test_menu_setmenuinfo(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* little func to easy switch either TrackPopupMenu() or TrackPopupMenuEx() */
|
||||||
|
static DWORD MyTrackPopupMenu( int ex, HMENU hmenu, UINT flags, INT x, INT y, HWND hwnd, LPTPMPARAMS ptpm)
|
||||||
|
{
|
||||||
|
return ex
|
||||||
|
? TrackPopupMenuEx( hmenu, flags, x, y, hwnd, ptpm)
|
||||||
|
: TrackPopupMenu( hmenu, flags, x, y, 0, hwnd, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* some TrackPopupMenu and TrackPopupMenuEx tests */
|
||||||
|
/* the LastError values differ between NO_ERROR and invalid handle */
|
||||||
|
/* between all windows versions tested. The first value is that valid on XP */
|
||||||
|
/* Vista was the only that made returned different error values */
|
||||||
|
/* between the TrackPopupMenu and TrackPopupMenuEx functions */
|
||||||
|
static void test_menu_trackpopupmenu(void)
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
HMENU hmenu;
|
||||||
|
DWORD gle;
|
||||||
|
int Ex;
|
||||||
|
HWND hwnd = CreateWindowEx(0, MAKEINTATOM(atomMenuCheckClass), NULL,
|
||||||
|
WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
|
||||||
|
if (!hwnd) return;
|
||||||
|
SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG_PTR)menu_ownerdraw_wnd_proc);
|
||||||
|
for( Ex = 0; Ex < 2; Ex++)
|
||||||
|
{
|
||||||
|
hmenu = CreatePopupMenu();
|
||||||
|
ok(hmenu != NULL, "CreateMenu failed with error %d\n", GetLastError());
|
||||||
|
if (!hmenu)
|
||||||
|
{
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* display the menu */
|
||||||
|
/* start with an invalid menu handle */
|
||||||
|
gle = 0xdeadbeef;
|
||||||
|
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
|
||||||
|
ret = MyTrackPopupMenu( Ex, NULL, 0x100, 100,100, hwnd, NULL);
|
||||||
|
gle = GetLastError();
|
||||||
|
ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : "");
|
||||||
|
ok( gle == ERROR_INVALID_MENU_HANDLE
|
||||||
|
|| broken (gle == 0xdeadbeef) /* win95 */
|
||||||
|
|| broken (gle == NO_ERROR) /* win98/ME */
|
||||||
|
,"TrackPopupMenu%s error got %u expected %u\n",
|
||||||
|
Ex ? "Ex" : "", gle, ERROR_INVALID_MENU_HANDLE);
|
||||||
|
ok( !(gflag_initmenupopup || gflag_entermenuloop || gflag_initmenu),
|
||||||
|
"got unexpected message(s)%s%s%s\n",
|
||||||
|
gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
|
||||||
|
gflag_entermenuloop ? "WM_INITMENULOOP ": "",
|
||||||
|
gflag_initmenu ? "WM_INITMENU": "");
|
||||||
|
/* another one but not NULL */
|
||||||
|
gle = 0xdeadbeef;
|
||||||
|
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
|
||||||
|
ret = MyTrackPopupMenu( Ex, (HMENU)hwnd, 0x100, 100,100, hwnd, NULL);
|
||||||
|
gle = GetLastError();
|
||||||
|
ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : "");
|
||||||
|
ok( gle == ERROR_INVALID_MENU_HANDLE
|
||||||
|
|| broken (gle == 0xdeadbeef) /* win95 */
|
||||||
|
|| broken (gle == NO_ERROR) /* win98/ME */
|
||||||
|
,"TrackPopupMenu%s error got %u expected %u\n",
|
||||||
|
Ex ? "Ex" : "", gle, ERROR_INVALID_MENU_HANDLE);
|
||||||
|
ok( !(gflag_initmenupopup || gflag_entermenuloop || gflag_initmenu),
|
||||||
|
"got unexpected message(s)%s%s%s\n",
|
||||||
|
gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
|
||||||
|
gflag_entermenuloop ? "WM_INITMENULOOP ": "",
|
||||||
|
gflag_initmenu ? "WM_INITMENU": "");
|
||||||
|
/* now a somewhat successfull call */
|
||||||
|
gle = 0xdeadbeef;
|
||||||
|
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
|
||||||
|
ret = MyTrackPopupMenu( Ex, hmenu, 0x100, 100,100, hwnd, NULL);
|
||||||
|
gle = GetLastError();
|
||||||
|
ok( ret == 0, "TrackPopupMenu%s returned %d expected zero\n", Ex ? "Ex" : "", ret);
|
||||||
|
ok( gle == NO_ERROR
|
||||||
|
|| gle == ERROR_INVALID_MENU_HANDLE /* NT4, win2k */
|
||||||
|
|| broken (gle == 0xdeadbeef) /* win95 */
|
||||||
|
,"TrackPopupMenu%s error got %u expected %u or %u\n",
|
||||||
|
Ex ? "Ex" : "", gle, NO_ERROR, ERROR_INVALID_MENU_HANDLE);
|
||||||
|
ok( gflag_initmenupopup && gflag_entermenuloop && gflag_initmenu,
|
||||||
|
"missed expected message(s)%s%s%s\n",
|
||||||
|
!gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
|
||||||
|
!gflag_entermenuloop ? "WM_INITMENULOOP ": "",
|
||||||
|
!gflag_initmenu ? "WM_INITMENU": "");
|
||||||
|
/* and another */
|
||||||
|
ret = AppendMenuA( hmenu, MF_STRING, 1, "winetest");
|
||||||
|
ok( ret, "AppendMenA has failed!\n");
|
||||||
|
gle = 0xdeadbeef;
|
||||||
|
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
|
||||||
|
ret = MyTrackPopupMenu( Ex, hmenu, 0x100, 100,100, hwnd, NULL);
|
||||||
|
gle = GetLastError();
|
||||||
|
ok( ret == 0, "TrackPopupMenu%s returned %d expected zero\n", Ex ? "Ex" : "", ret);
|
||||||
|
ok( gle == NO_ERROR
|
||||||
|
|| gle == ERROR_INVALID_MENU_HANDLE /* NT4, win2k and Vista in the TrackPopupMenuEx case */
|
||||||
|
|| broken (gle == 0xdeadbeef) /* win95 */
|
||||||
|
,"TrackPopupMenu%s error got %u expected %u or %u\n",
|
||||||
|
Ex ? "Ex" : "", gle, NO_ERROR, ERROR_INVALID_MENU_HANDLE);
|
||||||
|
ok( gflag_initmenupopup && gflag_entermenuloop && gflag_initmenu,
|
||||||
|
"missed expected message(s)%s%s%s\n",
|
||||||
|
!gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
|
||||||
|
!gflag_entermenuloop ? "WM_INITMENULOOP ": "",
|
||||||
|
!gflag_initmenu ? "WM_INITMENU": "");
|
||||||
|
DestroyMenu(hmenu);
|
||||||
|
}
|
||||||
|
/* clean up */
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(menu)
|
START_TEST(menu)
|
||||||
{
|
{
|
||||||
init_function_pointers();
|
init_function_pointers();
|
||||||
|
@ -2663,4 +2783,5 @@ START_TEST(menu)
|
||||||
test_menu_flags();
|
test_menu_flags();
|
||||||
|
|
||||||
test_menu_hilitemenuitem();
|
test_menu_hilitemenuitem();
|
||||||
|
test_menu_trackpopupmenu();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue