Как узнать, когда был нажат пункт меню?

#windows #user-interface #winapi #rust #win32gui

Вопрос:

Я использую winsafe ящик и хочу знать, когда в окне был нажат пункт меню.

flags amp; MF_MOUSESELECT as u16 должно быть 1 , если да, а 0 если нет, но это всегда 32768 происходит каждый раз, когда запускается событие, даже если пользователь просто наводит курсор на пункт меню или даже щелкает, чтобы закрыть его.

Почему?

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

    0
  }
});
 

Меню генерируется ресурсным скриптом, который скомпилирован и встроен в программу:

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

Комментарии:

1. Было бы полезно, если бы вы также описали, как вы создали меню.

2. @frankenapps Я добавил соответствующий скрипт ресурса. Вы можете увидеть полный код на Github: github.com/GirkovArpa/verpatch-gui-win32

3. MF_MOUSESELECT равно 32768, поэтому flags amp; MF_MOUSESELECT as u16 может быть только 0 или 32768.

4. Да, это правильный способ проверить наличие флага в битовом поле.

5. В любом случае, WM_MENUSELECT это не говорит вам, когда пользователь на самом деле вызывает пункт меню, WM_(SYS)COMMAND вместо этого скажите вам это. WM_MENUSELECT сообщает вам, когда пользователь выбрал (т. Е. Выделил) пункт меню, но еще не вызвал его. Выбор и вызов — это не одно и то же. И, кроме того, MF_MOUSESELECT просто сообщает вам, использовал ли пользователь мышь для выбора пункта меню (т. Е. горячее отслеживание прокрутки), но вместо этого пункт меню также может быть выбран с помощью клавиатуры (т. Е. с помощью клавиш со стрелками), и в этом случае MF_MOUSESELECT флаг будет равен 0.

Ответ №1:

Ты должен справиться WM_COMMAND . На самом деле существует встроенная функциональность для меню. Просто введите идентификатор, указанный в файле ресурсов, чтобы проверить, когда будет нажат соответствующий пункт меню.

Замените прослушиватель событий этими:

 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.")
  }
});