I have a large legacy application being updated to use newer CMFCRibbonBar. This application is large and the creation of the CMFCRibbonBar involves converting a lot of legacy icons and menu structures so is a bit complicated to extract and post here. I will add further details as people request them.
But the general gist is:
The application works fine and has a valid and working CMFCRibbonBar.
That ribbon bar has 11 categories across the top. With hundreds of panel buttons and menu buttons.
I have also recreated the same structure using CMFCRibbonButton to create a quick old style menu system which has been added to the m_wndRibbonBar via the AddToTabs. This give me a working drop down menu in the top right had corner. I believe there is a general web example which people may be familiar with which create a “window style” dropdown where you to change the MFC window manager style from windows 2000 through to windows7.
My menu is created from scratch at application startup and is not taken from a menu resource as this application predates this structure.
I use commands like the following to construct this menu:
pQuickMenu = new CMFCRibbonButton(ID_MENU++,TEXT("Quick Menu"),-1,-1,0);
pQuickButton = new CMFCRibbonButton(ID_MENU++,wMenuCommand,-1,-1,0);
The problem I am having is dynamically adding new buttons to this quick menu at a later date.
When I originally created this quick menu I kept the pointer to this structure that was used to add to the ribbon. Therefore I am able to add to the quickmenu.
pQuickBut = new CMFCRibbonButton(ID_MENU,wMenuCommand,NULL,0,hSmall,0,0);
If I add a new button to the existing stored top level quick menu using the stored pQuickMenu pointer, the button does appear. The text is correct and the button is selectable.
Except that the button is not operated upon when clicked.
If I add the button to the m_wndRibbonBar instead then it works so I know there is a valid command handler.
Down within the MFC code, clicking on my new quick access menu enters a routine called:
This extracts the command id correctly.
UINT uiID = GetNotifyID();
But it then checks for a valid ribbonbar.
CMFCRibbonBar* pRibbonBar = GetTopLevelRibbonBar();
This fails and returns a null pointer. Thus the command processing structure is exited.
As a test, if I call m_wndRibbonBar.AddToTabs(pQuickMenu) again for a second time adding the same menu to the RibbonBar a second time, then the origial becomes corrupt but the new command does work.
I am therefore assuming (guessing) that when the AddToTabs is called there is a ribbon handle stored with the commands. When I add directly to the existing structure after the original call to AddToTabs, a valid ribbon handle is not happening.
In the old style of things I would detach my quick menu, update it and then reattach. But I do not know how to do this (or even if it is nessesary) in the new CMFC classes.
The command: m_wndRibbonBar.removeallfromtabs(); deletes the whole of my pQuickMenu structure so I can not then add to it.
Is there anyone who can help explain how to dynamicaly add new buttons to an exising menu that has been added to a ribbonbar tab.
Any help appreciated.
Can anyone help me?
I am still unable to add to a ribbonbar “tab”.
Here is an example bit of code, which when added to a new MFC MDI basing ribbon example generated from the wizard works correctly until I add the bit at the bottom.
pQuickMenu = new CMFCRibbonButton(1000,TEXT("QuickMenu"),NULL,0,0,0,0);
pQuickMenu->AddSubItem(new CMFCRibbonButton(1001,TEXT("Do I work?"),NULL,0,0,0,0),-1);
void CMainFrame::DoIWork(UINT ID)
MessageBox(TEXT ("Yes I Do!"),TEXT("Do I Work?"), MB_ICONWARNING) ;
If I add the above strucutre to a ribbon based MDI MFC application, a new “QuicMenu” tab appears on the menu system. It works. If I click the “Do I work?” menu entry then it pops up a panel saying “yes I do!”
If I now add a button to the ribbonbar at time of initialisation, which when clicked will adds a new button to the “QuickMenu” menu then all is good. The additional button turns up and is selectable.
But when I select this new menu entry from the “quickmenu”, the click is registered but in the lower MFC code it fails to recognise a valid ribbonbar handle and exists without processing the message (see my first post for more info).
Can anyone help?
I am realy stuck and may have to scrap the ribbon and revert to basic menus only if I can not dynamicaly add to my quickmenu as rquired.
What am I missing or overlooking when I'm adding to my QuickMenu structure?
Here is a link to a visual studio project which demonstrates my issue. If anyone can explain why the clicking of the button on the ribbon generates a new menu entry which does not get acted upon I would be very grateful.
In my project I created object for class using new operator. After use I deleted that object and set that to NULL. But even after deletion, I could able to access and able to run other functions using that (deleted)object.
Please go through example:
CTemp *objTemp = new CTemp;
objTemp = NULL;
objTemp->Fun2(); // It is illegal still works, why?
It will only work when your CTemp::Fun2() function does not access non-static member variables or call other member functions that would do so. Then the implicit this pointer will be used which is NULL generating an access violation.
I am in the process of trying to code the transmission of floating point data over an ethernet cable. I decided to send two bytes, the first with the "whole" part and the second with the "fractional" part (but as an unsigned char). The first byte works fine, but the second (trivial) part is giving me a strange (to me) problem which is driving me nuts - I can't see WHAT I'm getting wrong. Here is the test code:-
What you should do to transfer the data (via serial or internet) is to transfer the exact bytes of the data, rather than trying to convert them to something else. So take the address of the number, cast that to an unsigned char* and send the four bytes thus pointed at. This will ensure that your receiver will get the exact data that you send.
That is not correct. The problem occurs when assigning 0.04 because the binary representation of floating point values can be slightly inexact. In your case flTest will be set to the value 0.0399999991. The following multiplication by 100 will not add another error so that flResult becomes 3.99999991.
Because there is no rounding when casting floating point values to integers, the result is 3. To avoid this, you can add 0.5 before casting:
ucResult = (unsigned char)(flResult + 0.5f);
Note that the above is for positive numbers only. With negative numbers, 0.5 must be subtracted.
First of all, apologies for not replying earlier !
WOW, I didn't think that a few lines of code could provoke so much discussion !!!
The technique that I am trying to employ is between a PC and an Arduino (via Com port - actually USB). I used it a few years ago to transfer floating point numbers, but in the OPPOSITE direction and it worked perfectly.
Anyway, thank you all for your comments - I am amazed that the "error" is actually in the assignment as pointed out by Jochen. In this particular application, the floating point numbers will be quite small, so I think that I'll have to go for the 4 byte transfer method to maintain accuracy - but I'll be doing a lot of testing !! Thank you all once again !
That's assuming that you have similar processors at both ends of the connection. While big-endian systems are rare these days, they're not non existent. Furthermore, be careful when going between 32-bit and 64-bit systems. On my x86 linux boxes, a long is 4 bytes, whereas on a x86_64 they're 8 bytes, x86 long-double is 12 bytes and x86_64 its 16.
I have a combobox in a mfc application. I created it at runtime with following code -
if (!m_sortBox.Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, rect, this, eSortBox))
Now the requirements, if user is selecting an item from combobox like , if combo box have focus & user is pressing up/down arrow key, it should NOT update the data.
If user is pressing enter key after selecting a item, it should update data.
So i didn't handled OnSelchange here.
For enter key requirement, I checked enter key event in preTranslateMsg & checking if combo box have focus, it should trigger the function, who will eventually update the data.
if (pMsg->message == WM_CHAR && pMsg->wParam == VK_RETURN)
CWnd pActiveWnd = CWnd::FromHandle(GetFocus()->GetSafeHwnd());
CWnd pcbSortBoxWnd = CWnd::FromHandle(m_sortBox.GetSafeHwnd());
//If sort combo box has focus and user press Enter key, it should trigger OnComboSelChange event
//Eventually it will update the data.
if (pcbSortBoxWnd == pActiveWnd)
I also handled ON_CBN_CLOSEUP(eSortBox, OnSortChange)
So that mouse functionality will work(because with mouse, data should get update)
Now my logic is working but its crashing in some cases.
Like - If I press Alt + Down arrow key, which will expand combobox, I select an item(with help of arrow keys) and press enter.
It must be "declared" as extern in the header file one time and "defined" one time as you said in the main.cpp.
It must not be defined again at any other file (source.cpp) unless extern is added
The dafault value must be placed in the main.cpp as you wrote
I do not like the solution very much because I have to be careful when changing the name of the variable to do in both sides.
Last Visit: 31-Dec-99 18:00 Last Update: 8-Aug-22 6:45