Thread: Create a very simple menu

  1. #1
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582

    Question Create a very simple menu

    The details that the Platform SDK gives are very confusing for something very simple. All I'm trying to do is create a basic menu. I, so far, just want a menu called "Test" with 3 options - 7, 15, and 40, all as strings without any special "eye candy". "Test" is like "file", "edit", and the related, always visible at the top. The other options appear only when I click on the "Test" menu. Upon selecting one, a variable gets set to this value. I'm stumped with just understanding what the SDK is stating, especially setting up the "MENUITEMINFO" structure.

    I have no idea if anything is set up properly or not as I'm also getting an error (and I'm doing what the SDK says). Note: I'm using C for programming, not C++.

    Code:
    // at the top
    HMENU MenuHandle;
    MENUITEMINFO TestMenuInfo;
    
    // in my WinMain function right after window creation
    	MenuHandle = CreateMenu(); // assign the handle to the menu
    
    	// fill in the MENUITEMINFO structure
    	TestMenuInfo.cbSize = sizeof(MENUITEMINFO); // error - cannot convert
    	TestMenuInfo.fMask = MIIM_TYPE; // not sure what I need here
    	TestMenuInfo.fType = MFT_MENUBREAK | MFT_STRING; // not sure what I need here
    	TestMenuInfo.dwTypeData = "Test"; // The menu should be called "test"
    	TestMenuInfo.cch = sizeof(TestMenuInfo.dwTypeData)++; // String size plus 1
    	
    	InsertMenuItem(MenuHandle, 0, 1, TestMenuInfo); // add the "Test" menu
    The error that shows up is "error C2440: 'function' : cannot convert from 'MENUITEMINFO' to 'LPCMENUITEMINFOA'", if that helps. For the options that appear, I'll obviously need the "MFT_RADIOCHECK" flag for fType and I'll also need to use fState. How close am I though?
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    check your menu HWND is not NULL

    zero the struct (ZeroMemory(&TestMenuInfo,sizeof(MENUITEMINFO))

    add an ID so you can get the 'clicked' msgs

    the mask is the items you want to set, so you need all the 'bits' you are filling in.
    MIIM_TYPE|MIIM_ID|MIIM_DATA

    type is MFT_STRING

    cch = lstrlen("Test");


    It needs a pointer to the struct, not the struct itself. (LP means 'long pointer')

    InsertMenuItem(MenuHandle, 0, 1, &TestMenuInfo);
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    I know what the LP and PTR things stand for. I just read the reported line number incorrectly so the error was in a different spot than I was checking which caused me to not notice this. It's just a dumb mistake.... I've changed my code, now I have a new questioned areas. The window handle and menu handle are both fine, even without the check, but it's quite wise to have them in the first place.

    Code:
    MenuHandle = CreateMenu(); // assign the handle to the menu
    	
    	if (MenuHandle != 0) // menu creation successful
    	{
    		// fill in the MENUITEMINFO structure
    		TestMenuInfo.cbSize = sizeof(MENUITEMINFO);
    		TestMenuInfo.fMask = MIIM_TYPE | MIIM_ID | MIIM_DATA; // not sure what I need here
    		TestMenuInfo.fType = MFT_STRING; // not sure what I need here
    		TestMenuInfo.wID = 0x0800; // what do I use here or does it matter?
    		TestMenuInfo.dwItemData = "Test"; // what is this element needed for?
    		TestMenuInfo.dwTypeData = "Test"; // The menu should be called "test"
    		TestMenuInfo.cch = lstrlen(TestMenuInfo.dwTypeData); // I didn't know about lstrlen
    		
    		InsertMenuItem(MenuHandle, 0, 1, &TestMenuInfo); // add the "Test" menu
    	}
    	
    	else // menu creation failed
    	{
    		MessageBox(hwnd, WarningString, "Menu creation failed!", MB_OK | MB_ICONEXCLAMATION);
    	}
    These are my questioned parts:

    1. Why zero the struct? What do you mean by that?
    2. What do I use in "wID"? I just picked something kind of random.
    3. Why do I need dwItemData - what does it do and what do I use?

    Edit: I've got the text to display and I added the first of the menu options, but instead of being found under the "test" menu, it's a whole new menu so I've got a menu called "7". How do I get it so that this option, 7, is found only when click on "test", listed downward instead of across? The documentation doesn't really seem to specify how to control whether something is a new menu header or a new menu option.... It's too vague on this.
    Last edited by ulillillia; 03-20-2009 at 10:46 PM. Reason: Progress report and new problem mentioned
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  4. #4
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    I've now ironed out every detail. It took a while, but I finally got the menus working. Thanks for helping me get started - that was the main thing I needed.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  5. #5
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by ulillillia View Post
    These are my questioned parts:

    1. Why zero the struct? What do you mean by that?
    In debug mode the complier inits the struct to all zeros.

    In release it does not.

    It is good practice to zero the struct to avoid any issues caused by random values in a struct member.

    Quote Originally Posted by ulillillia View Post
    2. What do I use in "wID"? I just picked something kind of random.
    Sorry my bad. You don't.

    Quote Originally Posted by ulillillia View Post
    3. Why do I need dwItemData - what does it do and what do I use?
    Item data is addional values stored about the item.

    Storing DB object reference, array index or pointer are common uses.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  6. #6
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    It seems like I do need the wID element. This way, I can, in the Windows message WS_COMMAND, filter various actions based on this and this wID element makes this easier:

    Code:
    if ((wParam & 0x0000FFFF) == 0x00000810)
    {
        // the 7 option from the test menu is chosen - do stuff based on this
    }
    With defines, I can replace the 0x00000810 with something more useful such as:

    Code:
    #define MenuTest7 0x00000810
    
    ...
    if ((wParam & 0x0000FFFF) == MenuTest7)
    It was a pain to change the state of menu elements though. I tried directly changing the fState element of the struct but nothing happened. Example:

    Code:
    TestMenu7.fState ^= MFS_CHECKED; // toggle this flag
    TestMenu15.fState &= (0xFFFFFFFF - MFS_CHECKED); // clear the flag - there's likely
    TestMenu40.fState &= (0xFFFFFFFF - MFS_CHECKED); // a better way to do this
    Oddly, the radio button never vanished or moved. ModifyMenu wasn't working (again, the documentation is too vague and unclear - those last two elements are messing me up - the menu options disappear when its used making the menu completely unusable.

    Given your description of dwItemData, then I don't need it. I don't know how to make program-related databases (Using Microsoft Access is questioned, but that's something different.). I just don't see any use with that. The wID element seems more useful, knowing the use of WS_COMMAND for this.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  7. #7
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    I will stop posting on weekends......


    You do need ID but not ItemData.

    You have to be careful that no two controls on the same window have the same ID#.

    Usually I hack the resource.h file.
    Add my ID in and, for menus, change the 'next command value'. Then the compiler ensures there are no collisions in ID#s.

    You can use WM_USER (1024) ie

    I sometimes use WM_APP (32768) as these are out of range of those in resource.h

    Either way you end up with something like

    #define IDM_SOME_MENU_ITEM WM_APP+1

    EDIT:

    I use the HIWORD() and LOWORD() macros

    Code:
    case WM_COMMAND:
    int iID=LOWORD(wParam);
    switch(iID)
    {
         case IDM_SOME_MENU_ITEM:
    Last edited by novacain; 03-21-2009 at 08:24 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  8. #8
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    What, do you tend to make more mistakes than normal on weekends? For the ID, I just use a system that resembles bit masking, in a sense:

    0xF000 - the menu bar, the top part - allows for up to 16 items here
    0x0F00 - the options that appear upon clicking a menu - a maximum limit of 16.
    0x00E0 - any submenus within a menu within a bar - 8 items again.
    0x001F - any variations of the menu element - 32 maximum.
    0x0010 - whether or not the element is checked (on) or unchecked (off)
    0x0008 - whether or not the element is enabled (on) or grayed (off)
    0x0007 - other variations for strings (8 maximum)

    For the ID of 0x3151, it would be the fourth menu on the menu bar, the second element in the list, the third item in the submenu, it's checked, it's enabled, and I'm using the first of the possible string (or other) variations.
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  9. #9
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Quote Originally Posted by ulillillia View Post
    What, do you tend to make more mistakes than normal on weekends?
    It would appear so.

    Probably because I turn my brain off after 5pm Friday.

    A mistake during the week can cost up to Au$10 mill / day and leave a 3km long train in the dirt.

    This tends to keep me well focused........
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to create a drop down menu?
    By arian in forum C# Programming
    Replies: 5
    Last Post: 03-29-2009, 11:42 PM
  2. create menu with do while loop advice pls
    By ali_1 in forum C++ Programming
    Replies: 1
    Last Post: 04-23-2006, 09:34 PM
  3. Button handler
    By Nephiroth in forum Windows Programming
    Replies: 8
    Last Post: 03-12-2006, 06:23 AM
  4. Delet Frequency in linked list
    By swishiat.com in forum C Programming
    Replies: 16
    Last Post: 12-13-2003, 02:05 AM
  5. Context Menu cursor problem
    By dWorkVan in forum Windows Programming
    Replies: 4
    Last Post: 07-14-2003, 11:42 AM

Tags for this Thread