Contextual / Popup Menus Appear at Wrong Location

Refactored for quick use

Just pass in the window it popup is on and it will work on all screens

Public Function PopupCUST(extends base as MenuItem) as MenuItem
  #if TargetMacOS then
    
    return base.PopUp()
    
  #else
    
    Declare function TrackPopupMenu lib "user32" (hMenu as integer,uFlags as uint32,x as integer, y as integer, nRes as integer, hWND as integer,prcRect as ptr) as integer
    Declare function GetCursorPos lib "user32" (mb as ptr) as Boolean
    declare function GetActiveWindow lib "user32" () as integer
    
    dim h as integer = GetActiveWindow()
    
    if h = 0 then return nil
    
    dim mb as new MemoryBlock(8)
    
    if not GetCursorPos(mb) then return nil
    
    dim x as integer = mb.Long(0)
    dim y as integer = mb.Long(4)
    
    //track popup and get result windows command ID or 0 for cancelled, flag &h100 sets this
    dim res as integer = TrackPopupMenu(base.Handle(menuitem.HandleType.WindowsParentHMENU),&h100,x,y,0,h,nil)
    
    if res = 0 then
      return nil
    end if
    
    return base.WINPOPUP_FindMenuItemByCommandID(res)
     
  #endif
End Function

And the recursive find the selected menu item function

Private Function WINPOPUP_FindMenuItemByCommandID(extends b as menuitem, cid as integer) as MenuItem
  #if TargetWindows then
    dim m as menuitem
    for i as integer = 0 to b.Count - 1
      m = b.MenuAt(i)
      if m.Handle(menuitem.HandleType.WindowsCommandID) = cid then 
        return m
      end if
      
      if m.Count > 0 then
        dim r as MenuItem = m.WINPOPUP_FindMenuItemByCommandID(cid)
        if r <> nil then return r
      end if
      
    next i
  #endif
  return nil
End Function

EDIT: Problems with System.mouse X / Y and window left top on Xojo 2019r1.1 so just showing it at mouse position seems to work for both xojo versions

EDIT 2: Why bother passing in the window when it’s the active window we want.

1 Like