static int menubar_create(menubar_t* mb, CREATESTRUCT *cs) { MENUBAR_TRACE("menubar_create(%p, %p)", mb, cs); if(MC_ERR(MENUBAR_SENDMSG(mb->win, WM_CREATE, 0, cs) != 0)) { MC_TRACE_ERR("menubar_create: CallWindowProc() failed"); return -1; } MENUBAR_SENDMSG(mb->win, TB_SETPARENT, mb->win, 0); MENUBAR_SENDMSG(mb->win, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); MENUBAR_SENDMSG(mb->win, TB_SETBITMAPSIZE, 0, MAKELONG(0, -2)); MENUBAR_SENDMSG(mb->win, TB_SETPADDING, 0, MAKELONG(10, 6)); MENUBAR_SENDMSG(mb->win, TB_SETDRAWTEXTFLAGS, MENUBAR_DTFLAGS, MENUBAR_DTFLAGS); /* Add some styles we consider default */ SetWindowLongPtr(mb->win, GWL_STYLE, cs->style | TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | CCS_NODIVIDER); if(cs->lpCreateParams != NULL) { if(MC_ERR(menubar_set_menu(mb, (HMENU) cs->lpCreateParams, FALSE) != 0)) { MC_TRACE("menubar_create: menubar_set_menu() failed."); return -1; } } menubar_update_ui_state(mb, FALSE); return 0; }
static cb_ret_t menubar_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data) { WMenuBar *menubar = MENUBAR (w); switch (msg) { /* We do not want the focus unless we have been activated */ case MSG_FOCUS: if (!menubar->is_active) return MSG_NOT_HANDLED; /* Trick to get all the mouse events */ w->lines = LINES; /* Trick to get all of the hotkeys */ widget_want_hotkey (w, 1); menubar_draw (menubar); return MSG_HANDLED; /* We don't want the buttonbar to activate while using the menubar */ case MSG_HOTKEY: case MSG_KEY: if (menubar->is_active) { menubar_handle_key (menubar, parm); return MSG_HANDLED; } return MSG_NOT_HANDLED; case MSG_CURSOR: /* Put the cursor in a suitable place */ return MSG_NOT_HANDLED; case MSG_UNFOCUS: return menubar->is_active ? MSG_NOT_HANDLED : MSG_HANDLED; case MSG_DRAW: if (menubar->is_visible) { menubar_draw (menubar); return MSG_HANDLED; } /* fall through */ case MSG_RESIZE: /* try show menu after screen resize */ send_message (w, sender, MSG_FOCUS, 0, data); return MSG_HANDLED; case MSG_DESTROY: menubar_set_menu (menubar, NULL); return MSG_HANDLED; default: return widget_default_callback (w, sender, msg, parm, data); } }
WMenuBar * menubar_new (int y, int x, int cols, GList * menu) { WMenuBar *menubar; menubar = g_new0 (WMenuBar, 1); init_widget (&menubar->widget, y, x, 1, cols, menubar_callback, menubar_event); widget_want_cursor (menubar->widget, FALSE); menubar->is_visible = TRUE; /* by default */ menubar_set_menu (menubar, menu); return menubar; }
WMenuBar * menubar_new (int y, int x, int cols, GList * menu, gboolean visible) { WMenuBar *menubar; Widget *w; menubar = g_new0 (WMenuBar, 1); w = WIDGET (menubar); widget_init (w, y, x, 1, cols, menubar_callback, menubar_event); menubar->is_visible = visible; widget_want_cursor (w, FALSE); menubar_set_menu (menubar, menu); return menubar; }
static LRESULT CALLBACK menubar_proc(HWND win, UINT msg, WPARAM wp, LPARAM lp) { menubar_t* mb = (menubar_t*) GetWindowLongPtr(win, extra_offset); switch(msg) { case MC_MBM_REFRESH: lp = (LPARAM)mb->menu; /* no break */ case MC_MBM_SETMENU: return (menubar_set_menu(mb, (HMENU)lp, (msg == MC_MBM_REFRESH)) == 0 ? TRUE : FALSE); case TB_SETPARENT: case CCM_SETNOTIFYWINDOW: { HWND old = mb->notify_win; mb->notify_win = (wp ? (HWND) wp : GetAncestor(win, GA_PARENT)); return (LRESULT) old; } case WM_COMMAND: MENUBAR_TRACE("menubar_proc(WM_COMMAND): code=%d; wid=%d; control=%p", (int)HIWORD(wp), (int)LOWORD(wp), (HWND)lp); if(lp == 0 && HIWORD(wp) == 0) /* msg came from the menu */ return MC_SEND(mb->notify_win, msg, wp, lp); break; case WM_NOTIFY: { NMHDR* hdr = (NMHDR*) lp; if(hdr->hwndFrom == win) return menubar_notify(mb, hdr); break; } case WM_ENTERMENULOOP: case WM_EXITMENULOOP: case WM_CONTEXTMENU: case WM_INITMENU: case WM_INITMENUPOPUP: case WM_UNINITMENUPOPUP: case WM_MENUSELECT: case WM_MENUCHAR: case WM_MENURBUTTONUP: case WM_MENUCOMMAND: case WM_MENUDRAG: case WM_MENUGETOBJECT: case WM_MEASUREITEM: case WM_DRAWITEM: return MC_SEND(mb->notify_win, msg, wp, lp); case WM_KEYDOWN: case WM_SYSKEYDOWN: if(menubar_key_down(mb, wp, lp)) return 0; break; case WM_GETDLGCODE: return MENUBAR_SENDMSG(win, msg, wp, lp) | DLGC_WANTALLKEYS | DLGC_WANTARROWS; case WM_NCCREATE: if(MC_ERR(MENUBAR_SENDMSG(win, msg, wp, lp) == FALSE)) { MC_TRACE_ERR("menubar_proc: MENUBAR_SENDMSG(WM_NCCREATE) failed"); return FALSE; } mb = menubar_nccreate(win, (CREATESTRUCT*) lp); if(MC_ERR(mb == NULL)) return FALSE; SetWindowLongPtr(win, extra_offset, (LONG_PTR)mb); return TRUE; case WM_SETFOCUS: MENUBAR_TRACE("menubar_proc(WM_SETFOCUS): old focus %p", (HWND) wp); if(win != (HWND) wp) mb->old_focus = (HWND) wp; active_menubar = mb; break; case WM_KILLFOCUS: MENUBAR_TRACE("menubar_proc: WM_KILLFOCUS"); mb->old_focus = NULL; MENUBAR_SENDMSG(mb->win, TB_SETHOTITEM, -1, 0); menubar_update_ui_state(mb, FALSE); active_menubar = NULL; break; case WM_CREATE: return menubar_create(mb, (CREATESTRUCT*) lp); case WM_DESTROY: menubar_destroy(mb); break; case WM_NCDESTROY: if(mb) { menubar_ncdestroy(mb); mb = NULL; } break; /* Disable those standard toolbar messages, which modify contents of * the toolbar, as it is our internal responsibility to set it * according to the menu. */ case TB_ADDBITMAP: case TB_ADDSTRING: MC_TRACE("menubar_proc: Suppressing message TB_xxxx (%d)", msg); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return -1; case TB_ADDBUTTONS: case TB_BUTTONSTRUCTSIZE: case TB_CHANGEBITMAP: case TB_DELETEBUTTON: case TB_ENABLEBUTTON: case TB_HIDEBUTTON: case TB_INDETERMINATE: case TB_INSERTBUTTON: case TB_LOADIMAGES: case TB_MARKBUTTON: case TB_MOVEBUTTON: case TB_PRESSBUTTON: case TB_REPLACEBITMAP: case TB_SAVERESTORE: case TB_SETANCHORHIGHLIGHT: case TB_SETBITMAPSIZE: case TB_SETBOUNDINGSIZE: case TB_SETCMDID: case TB_SETDISABLEDIMAGELIST: case TB_SETHOTIMAGELIST: case TB_SETIMAGELIST: case TB_SETINSERTMARK: case TB_SETPRESSEDIMAGELIST: case TB_SETSTATE: MC_TRACE("menubar_proc: Suppressing message TB_xxxx (%d)", msg); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return 0; /* FALSE == NULL == 0 */ case TB_CUSTOMIZE: /* Actually we suppress TB_CUSTOMIZE as the message above (i.e. * not passing it into the original proc), but we also misuse * is for our internal purpose of showing the popup menu. */ menubar_perform_dropdown(mb); return 0; } return MENUBAR_SENDMSG(win, msg, wp, lp); }