How would I go about making a file menu bar?

Started by
13 comments, last by GameDev.net 18 years, 7 months ago
How would I go about creating a file menu bar? (Like the ones in FF, word, etc) I'm using windows for the programme, so some windows 32 API stuff would be good... Thanks in advance.
Advertisement
You will have to create a menu resource (if you'r using Visual Studio this can be easily done with the resource editor) and load it using the Win32 API function LoadMenu.
Then you have a handle to the menu (HMENU) that you can either use with the CreateWindow function or (if you already have a window created) with the SetMenu function.

Hope that helps!
AppendMenu
the menu used by MS Word is actually a toolbar contained within a rebar, not your basic vanilla-flavored win32 HMENU.
Fine anonymous poster, I don't know EVERYTHING, unlike you...
Anyway thanks guys this is really useful, but unfortunately 2 things:-
A) I'm using Dev-Cpp
B) I'm using the allegro library.

So I wouldn't know how to make a menu resource, or the menu handler.
Help please.


P.S. Why does the appendmenu link go to LoadMenu?
You can also create a menu without using resources:

- Create a new Menu using CreateMenu
- Insert new menu items using either InsertMenu or AppendMenu
- Alternatively you can also insert a whole sub-menu to your menu using InsertMenuItem
- Finally, associate the menu with your window using SetMenu

Hope that helps!
You're basically screwed unless you buy microsofts 2000 dollar ide. Too much of that stuff is automated my VS and it's really hard to find out how to go around their rip-off ide(since all their books etc rely on their IDE and so do many tutorials)
I somehow never got around to writing a clean version of this, so the following is hacked out of two separate projects (each having slightly different functionality). I'm afraid I don't have time to test it right now so there are bound to be errors. If you can't get it working I'll try and fix it up tomorrow (checks clock) err, later today [smile].
// menuitem.h#if !defined(nENIGMA_nWUICPP_cMENU_cITEM)	#define nENIGMA_nWUICPP_cMENU_cITEM	#include <windows.h>	#include <boost/function.hpp>namespace enigma{	namespace wuicpp	{		class MenuItem		{			private:				class MenuItemState;			public:				static MenuItemState const disabled;				static MenuItemState const enabled;				MenuItem();				MenuItem(std::string name, char acceleratorKey, MenuItemState const & state);				MenuItem(std::string name, char acceleratorKey, boost::function0< void > const & function = nullFunction, MenuItemState const & state = MenuItem::enabled);			private:				class MenuItemState				{					public:						MenuItemState(unsigned char id);						bool operator==(MenuItemState const & menuItemState) const;					private:						unsigned char id_;				};				virtual void appendMenu(HMENU menu) const;				std::string decoratedName() const;				static void noop();				std::string name_;				char acceleratorKey_;				boost::function0< void > function_;				MenuItemState state_;				static boost::function0< void > const nullFunction;		};	}}#endif// menuitem.cpp#include "MenuItem.h"#include <boost/function_equal.hpp>namespace enigma{	namespace wuicpp	{		MenuItem::MenuItemState const MenuItem::disabled = MenuItem::MenuItemState(0);		MenuItem::MenuItemState const MenuItem::enabled = MenuItem::MenuItemState(1);		MenuItem::MenuItem()			:			shortcut_(Keycode::none),			state_(MenuItem::enabled)		{		}		MenuItem::MenuItem(std::string name, char acceleratorKey, MenuItem::MenuItemState const & state)			:			name_(name),			acceleratorKey_(acceleratorKey),			state_(state)		{		}		MenuItem::MenuItem(std::string name, char acceleratorKey, boost::function0< void > const & function, MenuItem::MenuItemState const & state)			:			name_(name),			acceleratorKey_(acceleratorKey),			function_(function),			state_(&function != &MenuItem::nullFunction ? state : MenuItem::disabled)		{		}		MenuItem::MenuItemState::MenuItemState(unsigned char id)			:			id_(id)		{		}		bool MenuItem::MenuItemState::operator==(MenuItemState const & menuItemState) const		{			return id_ == menuItemState.id_;		}		std::string MenuItem::decoratedName() const		{			std::string decoratedName = name_;			std::string::size_type acceleratorKeyIndex = decoratedName.find(acceleratorKey_);			if (acceleratorKeyIndex != std::string::npos)			{				decoratedName.insert(decoratedName.begin() + acceleratorKeyIndex, '&');			}			return decoratedName;		}		void MenuItem::noop()		{			// no-op		}		void MenuItem::appendMenu(HMENU menu)		{			AppendMenu(menu, (state_ == MenuItem::enabled ? MF_STRING : MF_STRING | MF_GRAYED), reinterpret_cast< unsigned int * >(this), decoratedName().c_str());		}		boost::function0< void > const MenuItem::nullFunction = MenuItem::noop;	}}// menu.h#if !defined(nENIGMA_nWUICPP_cMENU)	#define nENIGMA_nWUICPP_cMENU	#include <list>	#include <boost/shared_ptr.hpp>	#include "MenuItem.h"namespace enigma{	namespace wuicpp	{		class Menu			:			public MenuItem		{			private:				class MenuItemSeparator;			public:				static MenuItemSeparator const separator;				Menu();				Menu(std::string name, char acceleratorKey);				void addMenuItem(Menu const & menuItem);				void addMenuItem(MenuItem const & menuItem);				void addMenuItem(MenuItemSeparator const & menuItem);				void set(HWND windowHandle) const;			private:				virtual void appendMenu(HMENU menu) const;				std::list< boost::shared_ptr< MenuItem > > menuItems_;				class MenuItemSeparator					:					public MenuItem				{					public:						virtual void appendMenu(HMENU menu) const;				};		};	}}#endif// menu.cpp#include "Menu.h"#include <boost/bind.hpp>#include "MouseState.h"namespace enigma{	namespace wuicpp	{		Menu::MenuItemSeparator const Menu::separator;		Menu::Menu()		{		}		Menu::Menu(std::string name, char acceleratorKey)			:			MenuItem(name, acceleratorKey, MenuItem::enabled)		{		}		void Menu::addMenuItem(Menu const & menuItem)		{			menuItems_.push_back(boost::shared_ptr< MenuItem >(new Menu(menuItem)));		}		void Menu::addMenuItem(MenuItem const & menuItem)		{			menuItems_.push_back(boost::shared_ptr< MenuItem >(new MenuItem(menuItem)));		}		void Menu::addMenuItem(Menu::MenuItemSeparator const & menuItem)		{			menuItems_.push_back(boost::shared_ptr< MenuItem >(new Menu::MenuItemSeparator(menuItem)));		}		void Menu::set(HWND windowHandle) const		{			HMENU windowsMenu = CreateMenu();			std::for_each(menuItems_.begin(), menuItems_.end(), boost::bind(&MenuItem::appendMenu, _1, windowsMenu));			SetMenu(windowsMenu);		}		void Menu::appendMenu(HMENU menu) const		{			HMENU subMenu = CreatePopupMenu();			std::for_each(menuItems_.begin(), menuItems_.end(), boost::bind(&MenuItem::appendMenu, _1, subMenu));			AppendMenu(menu, (state_ == MenuItem::enabled ? MF_POPUP | MF_STRING : MF_POPUP | MF_STRING | MF_GRAYED), reinterpret_cast< unsigned int * >(subMenu), decoratedName().c_str());		}		void Menu::MenuItemSeparator::appendMenu(HMENU menu) const		{			AppendMenu(menu, MF_SEPARATOR, reinterpret_cast< unsigned int * >(this), "");		}	}}

Usage:
WindowMenu menu;WindowMenu fileSubMenu("File", 'F');fileSubMenu.append(WindowMenuItem("Open...", 'O', boost::bind(&Application::open, this)));fileSubMenu.append(WindowMenuItem("Play", 'P', boost::bind(&Application::play, this), MenuItem::disabled));fileSubMenu.append(WindowMenuItemSeparator());fileSubMenu.append(WindowMenuItem("Exit", 'x', boost::bind(&Application::exit, this)));WindowMenu helpSubMenu("Help", 'H');helpSubMenu.append(WindowMenuItem("About", 'A', boost::bind(&Application::about, this)));menu.append(fileSubMenu);menu.append(helpSubMenu);menu.set(windowHandle);

Enigma
If you are going towards the last post, you can also look at the WinMenu code inside DWinLib. The sample project compiles under Dev-C++, and can be found on the http://www.codeproject.com/library/DWinLib.asp page. (Look at how the WinMainO unit, MenuMain unit, and WinMenu classes interact.)

David
As beautiful as that code looks, and it certainly looks easy to use, I would rather make something myself (mainly as I don't like using stuff I don't understand).

I'm looking through the appendMenu function at the moment, and I'm not entirely sure what to do with it. Well mainly the third argument - uIDNewItem. What the hell do I do with that?

The manual says this about it:

Quote:[in] Specifies either the identifier of the new menu item or, if the uFlags parameter is set to MF_POPUP, a handle to the drop-down menu or submenu.


But I don't really know what to do with it, as far as I can tell if I want it to be a drop down menu I have to put the pointer to the drop down in there, but what if I want it to do something when clicked? :S

Help someone.

This topic is closed to new replies.

Advertisement