Thread: adding to the system menu

  1. #1
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401

    adding to the system menu

    i know how to make a window always on top now, but id also like to add the option of turning it on or off to the system menu (or whatever the very top left button on the window is called). any ideas on how to do this?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  2. #2
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396

    Shouldn't you just add this to a menu item!

    Do you mean the system menu (upper Right?) If this is really what you want to do I can't help you.

    I think you should add this function to a menu item like tools | options.

    That way your program will be more like other windows programs, user friendly.
    Last edited by Bajanine; 11-13-2002 at 12:45 AM.

  3. #3
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    sure, i could just add it to a menu, but where's the fun in that? and i do mean the top left. you know, the menu to the left of the window caption which includes restore, minimize, maximise, etc. i want it in there so that someone can easily access it through the task bar/startbar. is that too much to ask?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    The three boxes in the upper right are usually termed the system menu.


    WS_SYSMENU, WS_MINIMIZEBOX ect

    are styles to add / remove with

    SetWindowLong()
    "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

  5. #5
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    you know thats lovely novacain, but i REALLY would like to add to the top left, not the top right. you know when you hold ALT and hit the spacebar, a menu comes up? i've seen programs where that menu contains an option for switching on or off "Always on top". thats what id like to do, any ideas?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  6. #6
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Get a copy of the sytem menu (I think ms refer to it now as the 'window' menu just when everyone's used to calling it the system menu ), then use AppendMenu to add what you need. Then handle the WM_SYSCOMMAND and look for whatever cmd id you gave your extra menu item to generate whatever action you require. You may also wish to handle the WM_INITMENU message if you want to tweak the menu item by adding/removing a check mark or activated/graying the item, for example.

    eg.
    Code:
    HMENU hSysMenu=GetSystemMenu(hwnd,FALSE);
    TCHAR chMyItemTxt[]=TEXT("My System Menu Item...");
    if (hSysMenu)
      {
      AppendMenu(hMenu,MF_SEPARATOR,NULL,NULL); /*separator*/
      AppendMenu( hMenu, MF_STRING, IDSM_MY_MENU_ITEM,chMyItemTxt); /*your item*/
      }
    else
      {
      //error
      }
    Where IDSM_MY_MENU_ITEM is some #defined short int value (just like you would for a resource id) and hwnd is the handle of the window for which you want to adjust the system menu. Then in your WM_SYSCOMMAND handler you check the wParam for that value (read the specifics on msdn) to take whatever action you want for that menu item.

    Hope that helps.

    edit: formatting
    Last edited by Ken Fitlike; 11-13-2002 at 06:37 PM.

  7. #7
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    thanks ken. i added the menu item, but now im trying to capture it with WM_SYSCOMMAND, but if i return 0 after the code, no system commands work, ie, i cant open the menu, i cant close the window, i cant maximise, even with the control box at the right hand side of the window. what value do i return for it to go to the default code?
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  8. #8
    mustang benny bennyandthejets's Avatar
    Join Date
    Jul 2002
    Posts
    1,401
    dont worry, i found it. DefWindowProc().

    but, if say, i capture every WM_SYSCOMMAND and MessageBox the wParam, when the system/window menu is clicked, the menu doesn't come up after the messagebox is closed. it will only come up if, once captured, it is sent straight to the DefWindowProc().

    so far ive found that it only applies to that menu. you can move the window, close the window, and everything else, and the messagebox will come up, then the default procedure will begin. you can even press ALT+SPACEBAR and the menu will come up, but just not when you click it.

    do i have to call something to manually bring up the menu? thats a bit of a bother, but its tolerable.
    [email protected]
    Microsoft Visual Studio .NET 2003 Enterprise Architect
    Windows XP Pro

    Code Tags
    Programming FAQ
    Tutorials

  9. #9
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    return 0 for those user-defined commands you do process, for all others use DefWindowProc. If you still want default processing you can also call DefWindowProc before or after your own.

    If you are using a MessageBox just to display wParam for debugging purposes and it is giving you problems, try outputting the values to a file instead and see whether you still get the same (mis)behaviour. Better still, if you can step through your code with a debugger, do that instead.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  10. #10
    jasondoucette.com JasonD's Avatar
    Join Date
    Mar 2003
    Posts
    278
    Originally posted by Ken Fitlike
    Where IDSM_MY_MENU_ITEM is some #defined short int value (just like you would for a resource id) and hwnd is the handle of the window for which you want to adjust the system menu. Then in your WM_SYSCOMMAND handler you check the wParam for that value (read the specifics on msdn) to take whatever action you want for that menu item.
    I know this is an old thread, but I have a question, and instead of starting a new thread, I thought I'd add to the information in this one.

    When you add a menu item to the system (window) menu, what are the restrictions (if any) for the menu-item identifier (3rd parameter in AppendMenu(): UINT uIDNewItem)? I was under the impression that all privately defined messages must be >= WM_USER (0x0400). Am I correct?

    Also, while processing the WM_SYSCOMMAND message, I know you are supposed to ignore the lower four bits of uCmdType (wParam), by ANDing it with 0xFFF0. I assume this is not the case with a user defined menu item. Am I correct?

    The MSDN provides no information on the specifics of either question. Any help is appreciated.

  11. #11
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    I've only needed to do this a few times and mostly used mfc to do it but from memory the ID must be a multiple of 16. This is because the lower four bits are used by windows as some sort of set of status flags.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  12. #12
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Originally posted by JasonD
    When you add a menu item to the system (window) menu, what are the restrictions (if any) for the menu-item identifier (3rd parameter in AppendMenu(): UINT uIDNewItem)? I was under the impression that all privately defined messages must be >= WM_USER (0x0400). Am I correct?
    It's not a user-defined message, it's just an id tagged onto a copy of the system/window menu and relayed via WM_SYSCOMMAND.
    Originally posted by JasonD
    Also, while processing the WM_SYSCOMMAND message, I know you are supposed to ignore the lower four bits of uCmdType (wParam), by ANDing it with 0xFFF0. I assume this is not the case with a user defined menu item. Am I correct?

    The MSDN provides no information on the specifics of either question. Any help is appreciated.
    While it's true that its proper to &0xFFF0 i've found that ignoring that seems to do no harm (...infamous last words... ). On those rare occasions that I have done so I have tended to copy the wParam and &0xFFF0 with that; I seem to recall horrible things happening when just &'ing the neat wParam and then calling DefWindowProc.

    It might be an idea to use InsertMenuItem instead of AppendMenu; I seem to remember reading somewhere or other that AppendMenu has been superseded by it (could easily be wrong about that, though).

    >>I've only needed to do this a few times and mostly used mfc to do it <<

    Good idea: I think looking at some of the mfc auto-generated code for a dialog based application might be useful in this regard.

  13. #13
    jasondoucette.com JasonD's Avatar
    Join Date
    Mar 2003
    Posts
    278
    Originally posted by Ken Fitlike
    It's not a user-defined message, it's just an id tagged onto a copy of the system/window menu and relayed via WM_SYSCOMMAND.
    That's right, WM_COMMAND and WM_SYSCOMMAND are the messages, in which your own must be >= WM_USER. I knew I had something confused. But, the sample code I am looking at uses 1 as the id number, and knowing that this is supposed to be ANDed with 0xFFF0 made me think the programmer had it totally wrong. My mistake.

    Originally posted by Ken Fitlike
    While it's true that its proper to &0xFFF0 i've found that ignoring that seems to do no harm (...infamous last words... ). On those rare occasions that I have done so I have tended to copy the wParam and &0xFFF0 with that; I seem to recall horrible things happening when just &'ing the neat wParam and then calling DefWindowProc.

    It might be an idea to use InsertMenuItem instead of AppendMenu; I seem to remember reading somewhere or other that AppendMenu has been superseded by it (could easily be wrong about that, though).

    >>I've only needed to do this a few times and mostly used mfc to do it <<

    Good idea: I think looking at some of the mfc auto-generated code for a dialog based application might be useful in this regard.
    Yes, my copy of MSDN states: "The AppendMenu function has been superseded by the InsertMenuItem function. You can still use AppendMenu, however, if you do not need any of the extended features of InsertMenuItem." For most outdated functions, the MSDN states that 'newer applications should use xxxxx', so it seems that it is still ok to use AppendMenu, although it may be a good idea to upgrade to InsertMenuItem. I may take a look at some MFC code and see what it outputs... does anyone have any off hand that could show us?

    Thanks for the replies, btw.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What I've got so far, creating a menu system:
    By Shamino in forum Game Programming
    Replies: 4
    Last Post: 06-15-2007, 03:03 AM
  2. Replies: 4
    Last Post: 06-13-2005, 09:03 AM
  3. Replies: 3
    Last Post: 06-13-2005, 07:28 AM
  4. Menu Item Caption - /a for right aligned Accelerator?
    By JasonD in forum Windows Programming
    Replies: 6
    Last Post: 06-25-2003, 11:14 AM
  5. quick question about C Dos text menu pgm i was doing
    By Shadow in forum C Programming
    Replies: 2
    Last Post: 09-16-2001, 10:26 AM