Dynamic Items

without dynamic item

with dynamic items read from a file

With new items read from the same modified file

with Modal Application

without dynamic item

with dynamic items read from a file

With new items read from the same modified file

Environment: VC5, Windows 95, Windows NT

Introduction

Creating menus can be done by building the menu statically in resources, or creating it fully dynamicaly by using the CMenu creation operation. But how can we dynamically add items at runtime to a menu created in a resource? And how can we handle these items dynamically (if we don't know by advance how much they are)? Here is an easy solution.

My sample code shows you how to dynamically add and handle items to a menu in system tray, grabbing these items from an external file. The main advantage is that you can share this file on a network or elsewhere, and modify it at runtime all items that are in this file.

Method

  1. First of all, create your menu in resources, including only the static items :

    Menu in resources

    If you want no static items, but a full dynamic menu, just create a menu in the resource with dummy item like this:

    Dummy Menu in resources 

  2. Then, use the ClassWizard to create command handlers for the static items if they are some (ON_COMMAND and ON_UPDATE_COMMAND_UI if you want to do menu enabling).

    For example, from my sample code you have in the message map of the "MainFrame.cpp" file:

    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
      //{{AFX_MSG_MAP(CMainFrame)
      ON_WM_CREATE()
      ON_COMMAND(ID_POPUP_OPTIONS, OnPopupOptions)
      ...
      ON_COMMAND(ID_POPUP_EXIT, OnClose)
      //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
  3. In the "Mainframe.h" header file, add the following:

      #include "DynamicItems.h"
    to use DynamicItems class manager, and
      CDynamicItems m_DynamicItems;

    Still in "MainFrame.h", modify the message map as follows:

      //}}AFX_MSG
      afx_msg void OnExecuteDynamicMenu( UINT nID );
      DECLARE_MESSAGE_MAP()
    

    Now, imagine you want the ability to manage a maximum of 10 dynamic items. (This number is a maximum; you can have fewer items if you want, but no more than 10 will be handled :

    In the "Mainframe.cpp" file, add the following line in the message map:

    //}}AFX_MSG_MAP
      ON_COMMAND_RANGE( ID_POPUP_DynCmd01, ID_POPUP_DynCmd01 +
                        CDynamicMenu::GetNbMaxItems(),
                        OnExecuteDynamicMenu )
    END_MESSAGE_MAP()
    

    The CDynamicMenu::GetNbMaxItems() method returns the maximum numbers of items that can be handled simultaneously on the menu. You can increase this static value to be sure your menu will manage a very high number of items, but don't forget that you'll be limited by the size of your screen!

    This is a rarely-used but very powerful alternative message map macro, and this is the foundation of my dynamic items management.

  4. Then, in CMainframe.cpp, add, for example, the following code:

    void CMainFrame::OnExecuteDynamicMenu( UINT nID )
    {
      // Retrieve the selected dynamic item Name
      CString strItemText = m_DynamicItems.GetItemText(nID);
    
      // Retrieve the selected dynamic item associated comment
      CString strItemComment = m_DynamicItems.GetItemComment(nID);
    
      // Display it.
      CString strMsg="";
      strMsg.Format("Cmd %d selected.\nItem Name:
                     %s\nAssociated data: %s",
                     (nID -ID_POPUP_DynCmd01), strItemText,
                      strItemComment );
      AfxMessageBox(strMsg);
    }
    
    This method is called every time you click on a dynamic item in the menu. So, you have to modify this method to handle menu as you wish. In the sample code, you'll see that this method contains an easy but very powerful item management... Use it and enhance it as you want!

  5. When and where do I tell my app to load my items from a file?

    Loading items from the file and updating menu in memory is done in one line of code:

      UpdateDynamicItems(strFullFilePath);

    I have decorelated the process of physically updating data by reading a file, and the process of displaying menu for much easier use. You can call this method when you think it is necessary: using a timer to refresh items every X minutes, or when the user right-clicks an icon in the system-tray, and so forth... Whenever you want!

  6. Sample Code:

    There are two sample codes:

    1. A sample code that uses the system tray:

      It checks a file every X minutes using a timer to update the menu (the file to check and the duration between each check is customizable). You can modify the selected file at runtime, or use the two files given with the sample named "TestFile.txt" and "TestFile2.txt". The headers of these test files have comments on how to format datas. When you click on an item, a message box is displayed, telling you what is the name of the selected item, and what is its associated comment.

      Usage example: An application which use a shared file containing Name/E-mail of present people connected to the Internet

    2. A modal application that allows you to load/remove menus when you want:

      This sample code shows you how to load/remove menu items on a modal application. It is very easy to implement, and very easy to use; just have a look at the code...

      Usage example: Plugin list applications that can be enhanced just by modifying the menu, or shareware where you can add more menu items when user is regged by sending him the regged menu file, and so forth...

Conclusion

That's all. Your menu has now the ability to add and manage very easily dynamic items. Just have a look to the sample code to have an idea of how it works.

Use and enjoy. Please let me know of any bugs/mods/improvements that you have found/implemented and I will fix/incorporate them into this class in a future release.

E-mail:dexcoffier@yahoo.fr
My Official Web Site:http://www.excoffier.org
Participate in my marriage! Make a (small) donation and drop me a line to wish me success in my new life: http://www.sendmeaneuro.com

Acknowledgements

Thanks to Lionel Grenier (lionel.grenier@lebios.com) for ideas on improving this code.

Thanks also to Chris Maunder (cmaunder@mail.com) for his CSystemTray class used in this sample code.

Downloads

Download demo project (system tray) 65 Kb
Download demo project (modal app) 46 Kb
Download source 4 Kb

Posting History



Comments

  • aATQi WHa MpuA

    Posted by doSqhlZuOk on 11/15/2012 01:11am

    carisoprodol 350 mg buy cheap soma online no prescription - will soma show 10 panel drug test

    Reply
  • How to insert a CWnd object inside a menu?

    Posted by Legacy on 08/09/2003 12:00am

    Originally posted by: Vishal Mehta

    For your reference, I want to duplicate something of the kind MS Word provides. Inside "Format"-->"Background" menu, they display a "color-picker" along with normal menuitems. Any help    would be appreciated.
    
    

    Thanks in advance.

    Reply
  • A subtle bug exist here...

    Posted by Legacy on 07/28/2003 12:00am

    Originally posted by: truthADjuster

    There is a subtle bug that exist in this code. It has something to do with vector iterator pointer hanging.

    The other simpler bug is to avoid MF_POPUP bit flag in an item.

    I'm still tracing for the first bug.

    Reply
  • exanple code fixes plus debug assertion error

    Posted by Legacy on 03/02/2003 12:00am

    Originally posted by: John Marino

    The following changes should be made in order to run the 
    
    example code.

    change from:
    ON_COMMAND_RANGE( ID_POPUP_DynCmd01, ID_POPUP_DynCmd01 +
    CDynamicMenu::GetNbMaxItems(),
    OnExecuteDynamicMenu )
    to:
    ON_COMMAND_RANGE( ID_POPUP_DynCmd01, ID_POPUP_DynCmd01 +
    CDynamicItems::GetNbMaxItems(),
    OnExecuteDynamicMenu )


    Change from:
    // Retrieve the selected dynamic item Name
    CString strItemText = m_DynamicItems.GetItemText(nID);

    // Retrieve the selected dynamic item associated comment
    CString strItemComment = m_DynamicItems.GetItemComment(nID);

    to:
    // Retrieve the selected dynamic item Name
    CString strItemText = m_DynamicItems.GetItemText(nID).c_str();

    // Retrieve the selected dynamic item associated comment
    CString strItemComment = m_DynamicItems.GetItemComment(nID).c_str();


    The last major problem I had I have not been able to
    solve. When the TestFile.dat files have items that branch (in order words, submenus), I get the following debug
    assertion:
    File: afxwin1.inl
    Line: 1038

    Something about having a bad pointer to a menu item. Not
    smart enough to figure it out. However, if you delete the
    subitems from the data file, it will compile and run normally.

    Hopefully someone smartre than me can figure it out and
    post a fix. I've got enough information now to work around it I think.

    Reply
  • Great!

    Posted by Legacy on 11/10/2002 12:00am

    Originally posted by: Victor

    Thanks for your little tutorial!
    It's just what I needed for my plugin system.

    Thanks again!

    Reply
  • Dynamic Menu Builder

    Posted by Legacy on 09/09/2002 12:00am

    Originally posted by: dkrbhat

    How to do this in Visual Basic, by having resource in a table like folowing

    MenuId Number(4)
    MenuNm Char(25)
    MenuParentID Number(4)


    Model

    1000 File 0000
    1100 New 1000
    1200 Open 1000
    1210 Word 1200
    1220 PPT 1200


    so on..


    Read this table -> Build Menu

    Extend this table to provide Security ( Group Permission and so on )

    Reply
  • Menu Bar in Child window

    Posted by Legacy on 05/28/2002 12:00am

    Originally posted by: Ritu Singal

    Is it possible for child windows to have their own menu bar?? If yes then How??

    Reply
  • Good job, but not enough. Maybe someone can help me?

    Posted by Legacy on 12/06/2001 12:00am

    Originally posted by: Amit

    Good job, but not enough:
    I will appreciate much more a solution that is not limited to up to x items. But I am not sure it is possible.

    Actually I want to build on the fly a menu. Lets say 'Macro' menu that is located on the menu bar. Each time I pop it down, I will see the list of files in 'Macros' folder. Selecting an item from that menu will return the item-text.

    I thought about creating a menu 'Macro' by resourcr with one memeber 'emmpty'. To handle poping that menu at: OnUpdateMacro(CCmdUI* pCmdUI). I have a call each time I pop, I even enumarte all files from folder 'Macros'.
    But... I fail to build the menu and to temporarely replace it with the predefined empty one.

    If someone can conribure a small example, I will eppreciate it.

    Tnx.
    Amit.

    Reply
  • dynamic number of menu items

    Posted by Legacy on 10/11/2001 12:00am

    Originally posted by: sally

    that is all fair and well if you want 10 or 20 items in your menu, but the next week there is another requirement for 21 and so on. We could go on changing our source code and recomiling (for clients maybe) every such time. Wouldn't it be nicer if we could handle the menu dynamically? Anyone knwo how to do this?

    Thanks,
    Sally

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • Information is data with context. The era of Big Data has begun demonstrating to information security that there is more that can, and must, be done to identify threats, reduce risk, address fraud, and improve compliance monitoring activities by bringing better context to data and thereby creating information for actionable intelligence. This analyst report sets the stage and provides insights into IT and information security practitioners' perceptions of the impediments to, and the solutions necessary for, …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds