Click here to Skip to main content
15,925,309 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
GeneralRe: question on use of global scope operator Pin
digwizfox20-Jul-04 12:06
digwizfox20-Jul-04 12:06 
GeneralHooking Pin
gamitech19-Jul-04 12:13
gamitech19-Jul-04 12:13 
GeneralRe: Hooking Pin
User 665819-Jul-04 12:28
User 665819-Jul-04 12:28 
GeneralRe: Hooking Pin
bikram singh19-Jul-04 12:45
bikram singh19-Jul-04 12:45 
GeneralScripting for Game Mods... Pin
mztrjimmy19-Jul-04 12:10
mztrjimmy19-Jul-04 12:10 
GeneralRe: Scripting for Game Mods... Pin
Andrew Walker19-Jul-04 13:56
Andrew Walker19-Jul-04 13:56 
GeneralRe: Scripting for Game Mods... Pin
mztrjimmy19-Jul-04 15:09
mztrjimmy19-Jul-04 15:09 
GeneralDynamically Added Menu Items Greyed Pin
skonopa19-Jul-04 11:20
skonopa19-Jul-04 11:20 
Okay, here is a long-winded post, so bear with me.

I am in midst of writing a real-time data monitoring program using Visual C++ .NET (originally started out in VC++ 6 - only upgraded in the past couple months).

Anyway, the program includes a plot view showing points representing data collected at a given time. The plot view is a heavily modified version of Mark C. Malburg's OScope/Strip Chart control cribbed from this very site (http://www.codeproject.com/miscctrl/oscope.asp).

One of the major modifications is the ability to "pause/play", "rewind", and "fast-forward" the plot using a set of VCR-style button controls (with the typical "||", ">>", and "<<" type symbology) and a slider. Along with the ability to pause the plot is the ability to select and highlight the points in the plot (now THAT was fun to implement! Eek! | :eek: ). As a result, I am now implementing the ability for the user to right-click on a point in the plot to view the actual data. Since it is possible that more than one "data item" can be represented by a single point in the plot (it is at one-second granularity), I need the ability to dynamically generate the pop-up menu, with each menu item represented as a single data item to examine.

This is what I have so far:

In the function "OnContextMenu" in the CPlotView class:

// Convert the point where the right-click occurs
// to client coordinates
::ScreenToClient (this->m_hWnd, &clClickPoint);

// Setup a vector that will contain all the
// data points found at the coordinates of the
// right-click
CStripChartCtrl::pclDataPointVec pclDataPointsVec;

// Populate the vector to contain all the
// data points found at the place where the
// user right-clicked in the plot.
m_clStripChart.vGetDataPoint (clClickPoint, pclDataPointsVec);

// Check if the vector is empty (which would
// indicate no points found were the user
// right-clicked (a blank area of the plot,
// for example).
if (pclDataPointsVec.empty () == false)
{
// code to highlight the points (removed
// for brevity sake - basically just
// passed the data vector to a vHighlight
// method of the strip chart control class)

// Dynamically setup the menu showing the
// selectable data items.
CMenu clDataMenu;
vSetupViewDataMenu (pclDataPointsVec, clDataMenu);

// Append the data sub-menu to the
// menu loaded from resource under the
// "view data" option
HMENU hDataMenu = clDataMenu.Detach ();
clPopupMenu.AppendMenu (MF_STRING | MF_POPUP | MF_ENABLED, (UINT)hDataMenu, "View Data");
}
else
{
// if no data items found, then simply add
// a greyed out "view data" option
::GetCursorPos(&clMenuPoint);
clPopupMenu.AppendMenu (MF_STRING | MF_GRAYED, 0, "View Data");
}

// Code follows to setup and then make the menu appear using the "TrackPopupMenu" method of the clPopupMenu object.

The function "vSetupViewDataMenu" appears below in its entirty. Basically, it loops through the passed in data vector and "sorts" them by event type (which is represented by letters - future enhancement is to actually give them a name, but this program is still in its very early alpha/prototype stage). It then loops through the "sort" map and builds the cascading "view data" menus, the first level by event/data type, followed by an entry for each data item. As the menu is being built, each item is put into a map, indexed by menu ID (starting with "ID_PLOT_VIEWDATA"), so that the program will know which piece of data is represted by each menu item.

//--------------------------------------
void
CPlotView::vSetupViewDataMenu (
CStripChartCtrl::pclDataPointVec &pclDataVec,
CMenu &clMenu)
//--------------------------------------
// Description:
// This private function will dynamically
// setup the pop-up menu item to allow
// the user to view the data for the
// selected point.
//--------------------------------------
{
map<char, vector <CDataPoint *> > clDataMenuMap;
map<char, vector <CDataPoint *> >::iterator clDataMenuIter;

clMenu.CreatePopupMenu ();

m_pclMenuDataMap.clear ();

// loop through the passed in data vector
for (UINT i = 0 ; i < pclDataVec.size (); i++)
{
char cLetter = pclDataVec[i]->cGetPointChar();

clDataMenuMap[cLetter].push_back(pclDataVec[i]);

} // end for loop vector

// Now, iterate through the menu map and add each of the submenus
// into the passed in menu object

UINT uiMenuID = ID_PLOT_VIEWDATA;

for (clDataMenuIter = clDataMenuMap.begin ();
clDataMenuIter != clDataMenuMap.end ();
clDataMenuIter++ )
{
CString strMenuItem;

if (clDataMenuIter->first == 0)
strMenuItem = "View EP Information";
else
strMenuItem.Format ("View Event Type -> '%c'", clDataMenuIter->first);

CMenu clSubMenu;
clSubMenu.CreatePopupMenu ();

for (UINT i = 0; i < clDataMenuIter->second.size(); i++)
{
CString strSubItem;
strSubItem.Format ("Data Item %d", (i + 1));

clSubMenu.AppendMenu (MF_STRING | MF_ENABLED, uiMenuID, (LPCTSTR)strSubItem);
m_pclMenuDataMap[uiMenuID] = clDataMenuIter->second[i];
uiMenuID++;
}

// Detach the newly created sub-menu from the CMenu class and
// then append it to the passed in menu class
HMENU hSubMenu = clSubMenu.Detach ();
clMenu.AppendMenu (MF_STRING | MF_POPUP | MF_ENABLED, (UINT)(hSubMenu), (LPCTSTR)strMenuItem);
} // end for loop map

} // end private function vSetupViewDataMenu

Since there is no message map generated for this, I was going to override the "OnCmdMsg" as shown below. Right now, I was going to have the program simply display a message box to indicate that an item was succesfully selected and found (before getting into the technicalities of the actual data retrieval - that is whole 'nother topic with this program - yeesh! This program is to process many megabytes of data per SECOND, thus all kinds of crazy caching schemes and storing to temp files and such in an effort to make it efficient in both memory and speed as possible)

This is what I currently have in the "OnCmdMsg" function:

//--------------------------------------
BOOL
CPlotView::OnCmdMsg(
UINT nID,
int nCode,
void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
//--------------------------------------
// Description:
// This function handles the command messages
// that are sent when the user selects an
// item from the dynamically built view
// data menus.
//--------------------------------------
{
// TODO: Add your specialized code here and/or call the base class
if (pHandlerInfo == NULL)
{
if ( (nID >= ID_PLOT_VIEWDATA) &&
(nID < ID_PLOT_VIEWDATA +
m_pclMenuDataMap.size ()) )
{
if (nCode == CN_COMMAND)
{
CString strMessage;
strMessage.Format ("Selected Menu Item: %d", nID);

AfxMessageBox ((LPCTSTR)strMessage);
}
else if (nCode == CN_UPDATE_COMMAND_UI)
{
CCmdUI* pCmdUI = (CCmdUI*)pExtra;
pCmdUI->Enable (TRUE);
}
return TRUE;
}
}

return CFormView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

After all that, the problem is that all of the items in the sub-menus appear as greyed out. I tried several things such as using the ON_COMMAND_RANGE macro in a message map (with a block of command ID's 1000 apart, since it is very unlikely there will be that many data items represtented by one plot point in realistic usage), and no such luck. I determined it is because all those ID's are not part of the resources of this application, thus Windows does not "know" about them, since they are generated at run time. How can I get Windows to recognize those ID's at runtime, thus enabling those dynamically added menu items so the user can click on them?

When Windows won't do it, use Unix!
GeneralRe: Dynamically Added Menu Items Greyed Pin
Michael Dunn19-Jul-04 12:10
sitebuilderMichael Dunn19-Jul-04 12:10 
GeneralRe: Dynamically Added Menu Items Greyed Pin
skonopa20-Jul-04 5:15
skonopa20-Jul-04 5:15 
GeneralCurrent Working Directory Pin
alexdevmaster19-Jul-04 11:00
alexdevmaster19-Jul-04 11:00 
GeneralRe: Current Working Directory Pin
vcplusplus19-Jul-04 11:20
vcplusplus19-Jul-04 11:20 
GeneralRe: Current Working Directory Pin
Ivan Cachicatari19-Jul-04 18:07
Ivan Cachicatari19-Jul-04 18:07 
GeneralRe: Current Working Directory Pin
Ivan Cachicatari26-Jul-04 18:52
Ivan Cachicatari26-Jul-04 18:52 
GeneralMouse Cursor Drawing Resolution Pin
User 1278219-Jul-04 8:23
User 1278219-Jul-04 8:23 
GeneralRe: Mouse Cursor Drawing Resolution Pin
Alexander Wiseman19-Jul-04 10:22
Alexander Wiseman19-Jul-04 10:22 
GeneralRe: Mouse Cursor Drawing Resolution Pin
User 1278219-Jul-04 10:39
User 1278219-Jul-04 10:39 
GeneralRe: Mouse Cursor Drawing Resolution Pin
bikram singh19-Jul-04 11:11
bikram singh19-Jul-04 11:11 
GeneralRe: Mouse Cursor Drawing Resolution Pin
User 1278219-Jul-04 11:46
User 1278219-Jul-04 11:46 
GeneralRe: Mouse Cursor Drawing Resolution Pin
bikram singh19-Jul-04 12:31
bikram singh19-Jul-04 12:31 
GeneralRe: Mouse Cursor Drawing Resolution Pin
User 1278219-Jul-04 13:24
User 1278219-Jul-04 13:24 
GeneralRe: Mouse Cursor Drawing Resolution Pin
Alexander Wiseman19-Jul-04 15:47
Alexander Wiseman19-Jul-04 15:47 
GeneralRe: Mouse Cursor Drawing Resolution Pin
Alexander Wiseman19-Jul-04 15:56
Alexander Wiseman19-Jul-04 15:56 
GeneralRe: Mouse Cursor Drawing Resolution Pin
User 1278220-Jul-04 11:28
User 1278220-Jul-04 11:28 
GeneralRe: Mouse Cursor Drawing Resolution Pin
Alexander Wiseman20-Jul-04 11:34
Alexander Wiseman20-Jul-04 11:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.