Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 10-14-2006, 01:37 PM   #1 (permalink)
krisl100
krisl100
 
Join Date: Oct 2006
Location: Montreal
Posts: 34
krisl100 is on a distinguished road
C++ Menu

Ok, this is not even covered in the book I have, but someone was telling me about creating a menu system, & each menu item would then run a different or part of the same program. Example:

Menu
A

B

C

D

X: Quit program (go back to DOS/Windows)

He said you could write the menu as a seperate function, I have no clue where to even begin, so if someone could just help get started with the menu system, that would be great. Thanks.

(I still remember doing this in batch files using CHOICE
krisl100 is offline   Reply With Quote
Old 10-14-2006, 05:18 PM   #2 (permalink)
DJMaze
Senior Contributor
 
DJMaze's Avatar
 
Join Date: Mar 2005
Posts: 677
DJMaze is on a distinguished road
Code:
typedef void (*menufunc)();

typedef struct {
	char *title;
	char hotkey;
	menufunc *func;
} menuitem

void Aclicked()
{
	// do something
}

menuitem menuitems[5];
menuitems[0].title = "Choose A";
menuitems[0].hotkey = 'A';
menuitems[0].func = Aclicked;
__________________

UT: Ultra-kill... God like!
DJMaze is offline   Reply With Quote
Old 10-14-2006, 08:06 PM   #3 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Or how about something truly object oriented programming. This is the command design pattern. A menu can also hold menus, therefore it enables sub-menus to be created. A bit more advanced, I know, but this my style of making something really object oriented, like a menu subsystem.

And watch it. Strange things is happening to code here when copying and pasting... use your common sense.

main.cpp
Code:
#include "MenuManager.h"

int main()
{
  //Setup main menu first. Add submenu's here later.
  MenuManager MainMenu("Main Menu");
  
  //Setup a single sub menu.
  MenuManager* FileMenu = new MenuManager("File Menu");
  //Add concrete menu's to the sub menu.
  FileMenu->add(new PrintCmd);
  FileMenu->add(new ReturnCmd);
  //And add the sub menu to the main menu.
  MainMenu.add(FileMenu);
  //Also let's add a concrete quit command to the main menu to exit the app.
  MainMenu.add(new QuitCmd);
  //Run the menu.
  MainMenu.execute();
  
  return 0;
}
MenuCommand.h
Code:
#ifndef COMMAND_H
#define COMMAND_H

#include <vector>
#include <string>

using std::string;
using std::vector;

//Abstract.
class MenuCommand
{
public:
  MenuCommand(const string name);
  virtual ~MenuCommand();
  virtual bool execute() = 0;
  string get_name();
private:
  //Protect copy ctor and assignment.
  MenuCommand(const MenuCommand&);
  MenuCommand& operator=(const MenuCommand& rho);
  const string _sName;
};

//

class QuitCmd : public MenuCommand
{
public:
  QuitCmd();
  bool execute();
private:
  QuitCmd(const QuitCmd&);
  QuitCmd& operator=(const QuitCmd& rho);
};

//

class ReturnCmd : public MenuCommand
{
public:
  ReturnCmd();
  // if bool = false: return to previous level. 
  //If top level then quit app.
  bool execute();
private:
  ReturnCmd(const ReturnCmd&);
  ReturnCmd& operator=(const ReturnCmd& rho);
};

//

class PrintCmd : public MenuCommand
{
public:
  PrintCmd();
  bool execute();
private:
  PrintCmd(const PrintCmd&);
  PrintCmd& operator=(const PrintCmd& rho);
};

//

#endif  //COMMAND_H
MenuCommand.cpp
Code:
#include "MenuCommand.h"
#include "MenuManager.h"
#include <iostream>

using std::cout;
using std::endl;
using std::cin;

//---- CLASS MENUCOMMAND ----

MenuCommand::MenuCommand(const string name) :
  _sName(name)
{ }

MenuCommand::~MenuCommand()
{ }

string MenuCommand::get_name()
{
  return _sName;
}

//---- CLASS QUITCMD ----//

QuitCmd::QuitCmd() :
  MenuCommand("Quit Application")
{}

bool QuitCmd::execute()
{
  return false;
}

// CLASS RETURNCMD //

ReturnCmd::ReturnCmd() :
  MenuCommand("Return To Previous Menu")
{ }

bool ReturnCmd::execute()
{
  return false;
}

// CLASS PRINTCMD //

PrintCmd::PrintCmd() :
  MenuCommand("Print")
{}

bool PrintCmd::execute()
{
  cout<<"I am printing stuff :)"<<endl;
  return true;
}
MenuManager.h
Code:
#ifndef MENUMANAGER_H
#define MENUMANAGER_H

#include "MenuCommand.h"
#include <vector>
#include <string>

using std::vector;
using std::string;

class MenuManager : public MenuCommand
{
public:
  MenuManager(const string name);
  ~MenuManager();
 void add(MenuCommand* pCommand);
 bool execute();
private:
 MenuManager(const MenuManager&);
 MenuManager& operator=(const MenuManager& rho);
 MenuCommand* select(int index);
 void show();
 int get_user_input();
 vector<MenuCommand*> _vecMenuItemCommands;
};

#endif //MENUMANAGER_H
MenuManager.cpp
Code:
#include "MenuManager.h"
#include <algorithm>
#include <cstdlib> //size_t
#include <iostream>
#include <ios>

using std::cout;
using std::endl;
using std::cin;

//#define VERBOSE

//

MenuManager::MenuManager(const string name) :
    MenuCommand(name)
{ }

//

void MenuManager::add(MenuCommand* pCommand)
{
 _vecMenuItemCommands.push_back( pCommand );
}

//

bool MenuManager::execute()
{
  MenuCommand* pCmd;
  do
  {
    show();
    int userInput = get_user_input();
    pCmd = select( userInput );
  }
  while( pCmd->execute() );
  return true;
}

//

void MenuManager::show()
{
 cout << endl << "*** " << get_name() << " ***" << endl;
 std::size_t size = _vecMenuItemCommands.size();
 for(std::size_t i=0; i < size; ++i)
 {
    cout << i+1 << ". " << _vecMenuItemCommands[i]->get_name() << endl;
  }
}

//

MenuCommand* MenuManager::select(int index)
{
 return _vecMenuItemCommands[index-1];
}

//

int MenuManager::get_user_input()
{
  unsigned input = 0;
  while(input < 1 || input > ( _vecMenuItemCommands.size() ) )
  {
    cout << "Please select an item 1-" << (_vecMenuItemCommands.size()) << endl << ">";
    cin >> input;
  }
  return input;
}

//

struct Delete
{
   template <typename T>
   void operator()(const T* ptr) const
   {
#ifdef VERBOSE
     std::cout << "\tDeleting address: " << std::ios::hex  << ptr << std::endl;
#endif //VERBOSE
     delete ptr;
   }
};


//

MenuManager::~MenuManager()
{
#ifdef VERBOSE
  std::cout<<"Deleting: "<<get_name()<<std::endl;
#endif //VERBOSE
  std::for_each(_vecMenuItemCommands.begin(), _vecMenuItemCommands.end(), Delete() );
}
__________________
Valmont is offline   Reply With Quote
Old 10-15-2006, 05:14 AM   #4 (permalink)
krisl100
krisl100
 
Join Date: Oct 2006
Location: Montreal
Posts: 34
krisl100 is on a distinguished road
I tried typing both of these manually into my compiler, but I got errors. For the .h files, do I save those in my include directory?
krisl100 is offline   Reply With Quote
Old 10-15-2006, 10:28 AM   #5 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
No, you save both your cpp and h files in the project folder.

Currently, the bb code messed the c++ code up. Just copy and paste the code, but manuallly add the newlines.
__________________
Valmont is offline   Reply With Quote
Old 10-15-2006, 10:35 AM   #6 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
I have a better idea: I'll upload the files in a zip for you to download. See edit later.

---
edit
---
Link below:
http://home.tiscali.nl/valmont/cpp/d...manddesign.zip

- Create an empty project.
- Unpack these 5 files in your project folder.
- Add them to your project.
- Compile and run.

________________________
Don't post this code elsewhere without referring to this site and my name. Respect works both ways.
__________________
Valmont is offline   Reply With Quote
Old 10-16-2006, 06:34 AM   #7 (permalink)
Deliverance
C++ Beginner
 
Join Date: Jul 2005
Location: Ottawa
Posts: 73
Deliverance is on a distinguished road
Hey Valmont, I was just looking through your menu lib that you made, i haven't had a chance to unpack it and see what it actually does, just had a couple questions for you.

I notice in MenuCommand.h you make a destructor and the execute() command both virtual...could you elaborate on what the purpose of using virtual functions is (I've never covered this topic).

Second, going down to the MenuManager.cpp,
Code:
#ifdef VERBOSE
std::cout "something...or another"
#endif
I'm assuming this is placed in there because we don't know what type of application our user is building. If he/she were writing their program to accept command line arguments, and their program supported the -v (verbose) option (I'm not even sure if MS has such an option), then the menu could still operate under such an environment, and handle those options respectively?
Deliverance is offline   Reply With Quote
Old 10-16-2006, 10:36 AM   #8 (permalink)
toe_cutter
Code Monkey
 
Join Date: Aug 2002
Location: Boston, MA
Posts: 79
toe_cutter is on a distinguished road
Send a message via ICQ to toe_cutter Send a message via AIM to toe_cutter Send a message via Yahoo to toe_cutter
The #ifdef he is using is for debugging. If you have VERBOSE defined in your make or what ever MS has then it will include that code when you compile. If it is not set then it will nto be included during compilation.
__________________
toe_cutter is offline   Reply With Quote
Old 10-16-2006, 10:41 AM   #9 (permalink)
toe_cutter
Code Monkey
 
Join Date: Aug 2002
Location: Boston, MA
Posts: 79
toe_cutter is on a distinguished road
Send a message via ICQ to toe_cutter Send a message via AIM to toe_cutter Send a message via Yahoo to toe_cutter
I think the virtual destructor is used to call the derived classes destructor as well as it's own to make sure everything is cleaned up. This is of course a wild stab at a guess it has been a while since I did any C++.
__________________
toe_cutter is offline   Reply With Quote
Old 10-16-2006, 03:01 PM   #10 (permalink)
Deliverance
C++ Beginner
 
Join Date: Jul 2005
Location: Ottawa
Posts: 73
Deliverance is on a distinguished road
I think I found it:

Quote:
A virtual function is a function member of a class, declared using the "virtual" keyword. ...If the function is virtual and occurs both in the base class and in derived classes, then the right function will be picked up based on what the base class pointer "really" points at.
I guess in that example there were several execute() functions for the multiple classes
Deliverance is offline   Reply With Quote
Old 10-17-2006, 09:23 AM   #11 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
I was typing my fingers off, then I pressed my 5th mouse button and now I lost my big post!!
I need a cappucino first, then I start again.

But on the virtual destructors, I'll make a seperate "Quick Tutorial" in a new thread. Should serve as a "pilot" tutorial for the tutorial section when it passed the critical eye of our students and contributors .

When it comes to the zip file with the code:
Just compile it and run it. It's here only to demonstrate my own style. It's a nested Command Design Pattern. Some hate it, I love it, although it's right now clearly "over-engineering".

When it comes to the "VERBOSE" macro:
Remove the comment so the macro becomes active:
Code:
//#define VERBOSE //
becomes
Code:
#define VERBOSE
Compile and run again. Quit program. What do you see? Why would I want to see such feedback?
__________________
Valmont is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
DU command adapted in C Deliverance Standard C, C++ 3 12-03-2006 08:56 PM
How to use legacy C code in a C# application otakuj462 MS Technologies ( ASP, VB, C#, .NET ) 2 09-22-2005 07:18 PM
Kaat a talking bot in c nvictor Platform/API C++ 10 05-19-2005 01:16 PM
edit? anon Lounge 10 11-21-2002 03:02 PM


All times are GMT -8. The time now is 09:20 AM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting