Jump to content
  • Advertisement
Sign in to follow this  
Miles Lombardi

How would I go about making a file menu bar?

This topic is 4804 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
the menu used by MS Word is actually a toolbar contained within a rebar, not your basic vanilla-flavored win32 HMENU.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!