Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Command Bars
  New Posts New Posts RSS Feed - Dynamic menus
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

Dynamic menus

 Post Reply Post Reply
Author
Message
hpesata View Drop Down
Groupie
Groupie


Joined: 16 July 2004
Status: Offline
Points: 60
Post Options Post Options   Thanks (0) Thanks(0)   Quote hpesata Quote  Post ReplyReply Direct Link To This Post Topic: Dynamic menus
    Posted: 21 December 2004 at 9:14am
Hi!

I am currentlx trying to use an existing VC++.NET MFC application with Xtreme Toolkit Pro.
my application loads its menu entries from a XML-file and creates the app-menu
dynamically. I couldnt find a way to use XTreme Tooklit Pro with this approach, altough
I browsed through this forum, reading all related topics.

how can I dynamically create a CXTPMenubar object and attach it to the CXTPCommandbars ?
how can I attach my MFC-CMenu information to the CXTPMenuBar object ?
I would like to use the xtpThemeOffice2003 style wijh my menus.

any hints and sample code on how to accomplish this would be greatly appreciated,
thanx in advance!

best regards,
Hans

Back to Top
Sera View Drop Down
Newbie
Newbie


Joined: 30 June 2005
Status: Offline
Points: 11
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sera Quote  Post ReplyReply Direct Link To This Post Posted: 30 June 2005 at 11:00am
I have the same problem.
How to initialize
CXTPCommandBars member: CXTPMenubar* m_pMenuBar;
not from resources, but dynamically?

class CXTPMenuBar has the only method:
BOOL LoadMenuBar(UINT nIDResource);
And it's even not virtual!
Back to Top
hpesata View Drop Down
Groupie
Groupie


Joined: 16 July 2004
Status: Offline
Points: 60
Post Options Post Options   Thanks (0) Thanks(0)   Quote hpesata Quote  Post ReplyReply Direct Link To This Post Posted: 30 June 2005 at 11:30am
Hi!

I did the following:

CXTPCommandBars* pCommandBars = GetCommandBars();
if ( pCommandBars )
{       
    // Create fixed XTP menubar
    CXTPMenuBar* pMenuBar = pCommandBars->SetMenu(_T("Menu Bar"), 0);
}

using "0" within SetMenu() allows you to create an empty menu-bar.

afterwards I use

pMenuBar -> LoadMenu(&mymenu, TRUE)

to convert my MFC-menu to an XTP-menu.

Hope this helps!

regrads,
Hans

Back to Top
spiderM9 View Drop Down
Newbie
Newbie
Avatar

Joined: 21 October 2003
Status: Offline
Points: 17
Post Options Post Options   Thanks (0) Thanks(0)   Quote spiderM9 Quote  Post ReplyReply Direct Link To This Post Posted: 30 June 2005 at 2:13pm
I'm doing this like crazy, all from XML.
Start with this, from inside your CXTPMDIFrameWnd (typically CMainFrame)

    CXTPCommandBars* pBars = GetCommandBars();
    CXTPCommandBar* pMenu = pBars->GetMenuBar();
    CXTPControls* pControls = pMenu->GetControls();

then, after gathering the menu hierarchy from XML, I set up a recursive call to add commands.  as a parameter to this call is a queue of command bars.  the top level bar (e.g. MainMenu, which typically contains only top level menus like File, Edit etc.) is pushed into the queue.

the first item from the queue is popped, and as you add items, if the item is another sub-menu, push it into the stack to be "Fixed Up".  assuming "current" is the menu being built (which on the first pass will be MainMenu and on the second will be "FileMenu" etc..., the following is a pseudo-code snippet of the operation...

HRESULT CCommandBarFixer::FixCommandBar(CXTPControls* pControls, [unique identifier from XML], [various other services])
{
    HRESULT hr;

    // push to start iteration
    //
    c_of_fixmenu fixmenu_q; // a std::list<CFixMenu>
    fixmenu_q.push_back(CFixMenu([menu identifier from xml], pControls));

    while (!fixmenu_q.empty())
    {
        CFixMenu current = fixmenu_q.front();
        fixmenu_q.pop_front();

        // collect the children of this command bar
        //
        [collection of your xml data] extracted = [extract children from XML](current.[menu identifier]);

        // this is a purely manifest driven menu, simply loop through the finished menu and add them all
        // (this code is similar to the short circuit code in FixBootstrapMenu)
        //
        int nInsertHere = 0;
        int i_ct = current.controls->GetCount();
        _ASSERT(0 == i_ct);
        if (0 == i_ct)
        {
            CXTPControls* pControls = current.controls;

            bool bFoundInterveningGroup = false;
            for ([collection of your xml data]::iterator ii = extracted.begin(); ii != extracted.end(); ++ii)
            {
                AddCommand(pControls, XTPControlFlags(0), nInsertHere /*byref*/, fixmenu_q /*byref*/, [various info pulled from ii]);
            }
        }
    }

    return S_OK;
}

where AddCommand basically calls pControls->Add(type, ...
then decorates the returned pControl with data gathered from the XML, like the icon, display name etc.  if the item added was a sub-menu, it pushes the identifier into the queue, and the driver loop continues until the queue is empty, which allows for arbitrarily deeply nested menu structures.

Another trick was dealing with the automatic generation of separators by having the XML definition just group commands together, which requires some extra logic to determine if you are at the beginning or end of a group of commands, and automatically inserting the separator.  With explicitly defined separators, it makes it difficult to dynamically add commands at a specific location (especially when there are multiple 3rd parties trying to extend the menu system).

Note that if you want true extensibility without clashes, I'd suggest having each command uniquely identified within a Guid namespace using a Guid+Id pair, and providing a dynamically created mapping between true unique identifiers and the UINT needed by Windows/CodeJock.

The XML approach is very nice, I've got key-bindings, extensions for dynamic walkout menus and custom widgets, but it takes a bit of work to coerce Xtreme toolkit since it is really set up for static definitions.

P.S., I had to do the same type of thing for docking panes, since we don't know at compile time which types of panes are going to be requested, so a simple numeric pane identifier is an impossiblity in an extensible system.



Back to Top
Sera View Drop Down
Newbie
Newbie


Joined: 30 June 2005
Status: Offline
Points: 11
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sera Quote  Post ReplyReply Direct Link To This Post Posted: 01 July 2005 at 7:25am
A lot of thanks!
That's really works. ^)

I'm just a newbie of codejoke, so cannot understand a lot of things.
Maybe you can explain me, how to work with menu and toolbar? I'm about changing state and style of them (at run time).
How to substitute functions:
CMenu::CheckMenuRadioItem,
CMenu::EnableMenuItem,
CToolBar::SetButtonStyle (enable/disable button)

thanks
Back to Top
Sera View Drop Down
Newbie
Newbie


Joined: 30 June 2005
Status: Offline
Points: 11
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sera Quote  Post ReplyReply Direct Link To This Post Posted: 01 July 2005 at 7:32am
and one more question.

What is about creating toolbar dynamically from CToolBar?
Maybe you know simple solution.

thanks a lot
Back to Top
Sera View Drop Down
Newbie
Newbie


Joined: 30 June 2005
Status: Offline
Points: 11
Post Options Post Options   Thanks (0) Thanks(0)   Quote Sera Quote  Post ReplyReply Direct Link To This Post Posted: 05 July 2005 at 4:41am
Now I know answers for my previous questions.
But I still have some problems.

Now i've created the toolbar dynamically. It's normal, but when using "chevron" "Add and remove buttons" -> "MyToolbar", in popup menu there are
a) items from not used resource toolbar;
b) my items (disabled).
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.109 seconds.