Search code examples
windowsuser-interfacewinapirustwin32gui

How to know when a menu item has been clicked?


I'm using the winsafe crate and want to know when a menu item's been clicked in a window.

flags & MF_MOUSESELECT as u16 should be 1 if so and 0 if not, but it's always 32768 everytime the event is fired, even if it's just from the user hovering a menu item, or even clicking away to make it close.

Why?

self.wnd.on().wm(winsafe::co::WM::MENUSELECT, {
  move |params| {
    let wparam = params.wparam;
    let lparam = params.lparam;
    let flags = (wparam >> 16 & 0xffff) as u16;
    let MF_MOUSESELECT = 0x00008000 as u32;
    
    println!("{}", flags & MF_MOUSESELECT as u16);
    // always 32768

    0
  }
});

The menu is generated by a resource script which is compiled and embedded in the program:

1 MENU
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
{
  POPUP "&File"
  {
    MENUITEM "&Open",  1
    MENUITEM "&Save",  2
  }
  POPUP "&Help"
  {
    MENUITEM "&About",  3
  }
}

Solution

  • You should handle WM_COMMAND. There is actually built in functionality for menus. Simply provide the id you specified in your resource file to check when the correponding menu item is clicked.

    Replace your event listener with these:

    self.wnd.on().wm_command(co::CMD::Menu, 1, {
      move || {
        println!("Open clicked.")
      }
    });
    
    self.wnd.on().wm_command(co::CMD::Menu, 2, {
      move || {
        println!("Save clicked.")
      }
    });
    
    self.wnd.on().wm_command(co::CMD::Menu, 3, {
      move || {
        println!("About clicked.")
      }
    });