mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 14:50:48 +00:00
win32u: Move NtUserMenuItemFromPoint implementation from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
This commit is contained in:
parent
987d637e31
commit
95b76f5101
7 changed files with 110 additions and 20 deletions
|
@ -4321,19 +4321,9 @@ DWORD WINAPI GetMenuContextHelpId( HMENU menu )
|
|||
/**********************************************************************
|
||||
* MenuItemFromPoint (USER32.@)
|
||||
*/
|
||||
INT WINAPI MenuItemFromPoint(HWND hWnd, HMENU hMenu, POINT ptScreen)
|
||||
INT WINAPI MenuItemFromPoint( HWND hwnd, HMENU menu, POINT pt )
|
||||
{
|
||||
POPUPMENU *menu = grab_menu_ptr(hMenu);
|
||||
UINT pos;
|
||||
|
||||
/*FIXME: Do we have to handle hWnd here? */
|
||||
if (!menu) return -1;
|
||||
|
||||
if (MENU_FindItemByCoords( menu, ptScreen, &pos ) != ht_item)
|
||||
pos = -1;
|
||||
|
||||
release_menu_ptr(menu);
|
||||
return pos;
|
||||
return NtUserMenuItemFromPoint( hwnd, menu, pt.x, pt.y );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,15 @@ struct accelerator
|
|||
ACCEL table[1];
|
||||
};
|
||||
|
||||
enum hittest
|
||||
{
|
||||
ht_nowhere, /* outside the menu */
|
||||
ht_border, /* anywhere that's not an item or a scroll arrow */
|
||||
ht_item, /* a menu item */
|
||||
ht_scroll_up, /* scroll up arrow */
|
||||
ht_scroll_down /* scroll down arrow */
|
||||
};
|
||||
|
||||
/* maximum allowed depth of any branch in the menu tree.
|
||||
* This value is slightly larger than in windows (25) to
|
||||
* stay on the safe side. */
|
||||
|
@ -424,6 +433,76 @@ static UINT find_submenu( HMENU *handle_ptr, HMENU target )
|
|||
return NO_SELECTED_ITEM;
|
||||
}
|
||||
|
||||
/* Adjust menu item rectangle according to scrolling state */
|
||||
static void adjust_menu_item_rect( const POPUPMENU *menu, RECT *rect )
|
||||
{
|
||||
INT scroll_offset = menu->bScrolling ? menu->nScrollPos : 0;
|
||||
OffsetRect( rect, menu->items_rect.left, menu->items_rect.top - scroll_offset );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* find_item_by_coords
|
||||
*
|
||||
* Find the item at the specified coordinates (screen coords). Does
|
||||
* not work for child windows and therefore should not be called for
|
||||
* an arbitrary system menu.
|
||||
*
|
||||
* Returns a hittest code. *pos will contain the position of the
|
||||
* item or NO_SELECTED_ITEM. If the hittest code is ht_scroll_up
|
||||
* or ht_scroll_down then *pos will contain the position of the
|
||||
* item that's just outside the items_rect - ie, the one that would
|
||||
* be scrolled completely into view.
|
||||
*/
|
||||
static enum hittest find_item_by_coords( const POPUPMENU *menu, POINT pt, UINT *pos )
|
||||
{
|
||||
enum hittest ht = ht_border;
|
||||
MENUITEM *item;
|
||||
RECT rect;
|
||||
UINT i;
|
||||
|
||||
*pos = NO_SELECTED_ITEM;
|
||||
|
||||
if (!get_window_rect( menu->hWnd, &rect, get_thread_dpi() ) || !PtInRect( &rect, pt ))
|
||||
return ht_nowhere;
|
||||
|
||||
if (get_window_long( menu->hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) pt.x = rect.right - 1 - pt.x;
|
||||
else pt.x -= rect.left;
|
||||
pt.y -= rect.top;
|
||||
|
||||
if (!PtInRect( &menu->items_rect, pt ))
|
||||
{
|
||||
if (!menu->bScrolling || pt.x < menu->items_rect.left || pt.x >= menu->items_rect.right)
|
||||
return ht_border;
|
||||
|
||||
/* On a scroll arrow. Update pt so that it points to the item just outside items_rect */
|
||||
if (pt.y < menu->items_rect.top)
|
||||
{
|
||||
ht = ht_scroll_up;
|
||||
pt.y = menu->items_rect.top - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ht = ht_scroll_down;
|
||||
pt.y = menu->items_rect.bottom;
|
||||
}
|
||||
}
|
||||
|
||||
item = menu->items;
|
||||
for (i = 0; i < menu->nItems; i++, item++)
|
||||
{
|
||||
rect = item->rect;
|
||||
adjust_menu_item_rect( menu, &rect );
|
||||
if (PtInRect( &rect, pt ))
|
||||
{
|
||||
*pos = i;
|
||||
if (ht != ht_scroll_up && ht != ht_scroll_down) ht = ht_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ht;
|
||||
}
|
||||
|
||||
/* see GetMenu */
|
||||
HMENU get_menu( HWND hwnd )
|
||||
{
|
||||
|
@ -1040,6 +1119,21 @@ static HMENU get_sub_menu( HMENU handle, INT pos )
|
|||
return submenu;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NtUserMenuItemFromPoint (win32u.@)
|
||||
*/
|
||||
INT WINAPI NtUserMenuItemFromPoint( HWND hwnd, HMENU handle, int x, int y )
|
||||
{
|
||||
POINT pt = { .x = x, .y = y };
|
||||
POPUPMENU *menu;
|
||||
UINT pos;
|
||||
|
||||
if (!(menu = grab_menu_ptr(handle))) return -1;
|
||||
if (find_item_by_coords( menu, pt, &pos ) != ht_item) pos = -1;
|
||||
release_menu_ptr(menu);
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NtUserGetSystemMenu (win32u.@)
|
||||
*/
|
||||
|
@ -1823,13 +1917,6 @@ got_bitmap:
|
|||
NtGdiDeleteObjectApp( mem_hdc );
|
||||
}
|
||||
|
||||
/* Adjust menu item rectangle according to scrolling state */
|
||||
static void adjust_menu_item_rect( const POPUPMENU *menu, RECT *rect )
|
||||
{
|
||||
INT scroll_offset = menu->bScrolling ? menu->nScrollPos : 0;
|
||||
OffsetRect( rect, menu->items_rect.left, menu->items_rect.top - scroll_offset );
|
||||
}
|
||||
|
||||
/* Draw a single menu item */
|
||||
static void draw_menu_item( HWND hwnd, POPUPMENU *menu, HWND owner, HDC hdc,
|
||||
MENUITEM *item, BOOL menu_bar, UINT odaction )
|
||||
|
|
|
@ -151,6 +151,7 @@ static void * const syscalls[] =
|
|||
NtUserInternalGetWindowText,
|
||||
NtUserKillTimer,
|
||||
NtUserLockWindowUpdate,
|
||||
NtUserMenuItemFromPoint,
|
||||
NtUserNotifyWinEvent,
|
||||
NtUserOpenDesktop,
|
||||
NtUserOpenInputDesktop,
|
||||
|
|
|
@ -1078,7 +1078,7 @@
|
|||
@ stub NtUserMapPointsByVisualIdentifier
|
||||
@ stdcall NtUserMapVirtualKeyEx(long long long)
|
||||
@ stub NtUserMarkWindowForRawMouse
|
||||
@ stub NtUserMenuItemFromPoint
|
||||
@ stdcall -syscall NtUserMenuItemFromPoint(long long long long)
|
||||
@ stdcall NtUserMessageCall(long long long long long long long)
|
||||
@ stub NtUserMinInitialize
|
||||
@ stub NtUserMinMaximize
|
||||
|
|
|
@ -138,6 +138,7 @@
|
|||
SYSCALL_ENTRY( NtUserInternalGetWindowText ) \
|
||||
SYSCALL_ENTRY( NtUserKillTimer ) \
|
||||
SYSCALL_ENTRY( NtUserLockWindowUpdate ) \
|
||||
SYSCALL_ENTRY( NtUserMenuItemFromPoint ) \
|
||||
SYSCALL_ENTRY( NtUserNotifyWinEvent ) \
|
||||
SYSCALL_ENTRY( NtUserOpenDesktop ) \
|
||||
SYSCALL_ENTRY( NtUserOpenInputDesktop ) \
|
||||
|
|
|
@ -736,6 +736,16 @@ NTSTATUS WINAPI wow64_NtUserGetMenuItemRect( UINT *args )
|
|||
return NtUserGetMenuItemRect( hwnd, handle, item, rect );
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserMenuItemFromPoint( UINT *args )
|
||||
{
|
||||
HWND hwnd = get_handle( &args );
|
||||
HMENU handle = get_handle( &args );
|
||||
int x = get_ulong( &args );
|
||||
int y = get_ulong( &args );
|
||||
|
||||
return NtUserMenuItemFromPoint( hwnd, handle, x, y );
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI wow64_NtUserSetMenuContextHelpId( UINT *args )
|
||||
{
|
||||
HMENU menu = get_handle( &args );
|
||||
|
|
|
@ -620,6 +620,7 @@ BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format );
|
|||
BOOL WINAPI NtUserKillTimer( HWND hwnd, UINT_PTR id );
|
||||
BOOL WINAPI NtUserLockWindowUpdate( HWND hwnd );
|
||||
UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout );
|
||||
INT WINAPI NtUserMenuItemFromPoint( HWND hwnd, HMENU handle, int x, int y );
|
||||
LRESULT WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
|
||||
void *result_info, DWORD type, BOOL ansi );
|
||||
BOOL WINAPI NtUserMoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint );
|
||||
|
|
Loading…
Reference in a new issue