void contextmenu_manager::win32_run_menu_popup(HWND parent,const POINT * pt) { enum {ID_CUSTOM_BASE = 1}; int cmd; { POINT p; if (pt) p = *pt; else GetCursorPos(&p); HMENU hmenu = CreatePopupMenu(); try { win32_build_menu(hmenu,ID_CUSTOM_BASE,-1); menu_helpers::win32_auto_mnemonics(hmenu); cmd = TrackPopupMenu(hmenu,TPM_RIGHTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD,p.x,p.y,0,parent,0); } catch(...) {DestroyMenu(hmenu); throw;} DestroyMenu(hmenu); } if (cmd>0) { if (cmd>=ID_CUSTOM_BASE) { execute_by_id(cmd - ID_CUSTOM_BASE); } } }
void contextmenu_manager::win32_build_menu(HMENU menu,contextmenu_node * parent,int base_id,int max_id)//menu item identifiers are base_id<=N<base_id+max_id (if theres too many items, they will be clipped) { if (parent!=0 && parent->get_type()==contextmenu_item_node::TYPE_POPUP) { pfc::string8_fastalloc temp; t_size child_idx,child_num = parent->get_num_children(); for(child_idx=0;child_idx<child_num;child_idx++) { contextmenu_node * child = parent->get_child(child_idx); if (child) { const char * name = child->get_name(); if (strchr(name,'&')) {fix_ampersand(name,temp);name=temp;} contextmenu_item_node::t_type type = child->get_type(); if (type==contextmenu_item_node::TYPE_POPUP) { HMENU new_menu = CreatePopupMenu(); uAppendMenu(menu,MF_STRING|MF_POPUP | flags_to_win32(child->get_display_flags()),(UINT_PTR)new_menu,name); win32_build_menu(new_menu,child,base_id,max_id); } else if (type==contextmenu_item_node::TYPE_SEPARATOR) { uAppendMenu(menu,MF_SEPARATOR,0,0); } else if (type==contextmenu_item_node::TYPE_COMMAND) { int id = child->get_id(); if (id>=0 && (max_id<0 || id<max_id)) { const unsigned flags = child->get_display_flags(); const UINT ID = base_id+id; uAppendMenu(menu,MF_STRING | flags_to_win32(flags),ID,name); if (flags & contextmenu_item_node::FLAG_RADIOCHECKED) CheckMenuRadioItem(menu,ID,ID,ID,MF_BYCOMMAND); } } } } } }
void menu_manager::win32_build_menu(HMENU menu,menu_node * parent,int base_id,int max_id)//menu item identifiers are base_id<=N<base_id+max_id (if theres too many items, they will be clipped) { if (parent!=0 && parent->get_type()==menu_node::TYPE_POPUP) { string8_fastalloc temp; int child_idx,child_num = parent->get_num_children(); for(child_idx=0;child_idx<child_num;child_idx++) { menu_node * child = parent->get_child(child_idx); if (child) { const char * name = child->get_name(); if (strchr(name,'&')) {fix_ampersand(name,temp);name=temp;} menu_node::type type = child->get_type(); if (type==menu_node::TYPE_POPUP) { HMENU new_menu = CreatePopupMenu(); uAppendMenu(menu,MF_STRING|MF_POPUP | flags_to_win32(child->get_display_flags()),(UINT)new_menu,name); win32_build_menu(new_menu,child,base_id,max_id); } else if (type==menu_node::TYPE_SEPARATOR) { uAppendMenu(menu,MF_SEPARATOR,0,0); } else if (type==menu_node::TYPE_COMMAND) { int id = child->get_id(); if (id>=0 && (max_id<0 || id<max_id)) { uAppendMenu(menu,MF_STRING | flags_to_win32(child->get_display_flags()),base_id+id,name); } } } } } }