System menu/Control menu

Every top level window contains a small menu which can be seen by right clicking on title bar or clicking on the icon visible at the left side on any application. This is called system menu or control menu. It contains menu items like maximize minimize close, move, size, restore etc. These menu items are to control system operations and these are provided by operating system. However we can modify these or can append some additional menus if needed.

GetSystemMenu

GetSystemMenu() gives access to the application to access this system menu. It returns handle to system menu which can be used to add additional menus. This can also be used to revert to original state.

Syntax

HMENU WINAPI GetSystemMenu(
    HWND hWnd,
    BOOL bRevert
);

Parameters

  • hWnd (HWND) A handle to the window that will own a copy of the window menu.
  • bRevert (BOOL) The action to be taken. If this parameter is FALSE, GetSystemMenu returns a handle to the copy of the window menu currently in use. The copy is initially identical to the window menu, but it can be modified. If this parameter is TRUE, GetSystemMenu resets the window menu back to the default state. The previous window menu, if any, is destroyed.

Return value

If the bRevert parameter is FALSE, the return value is a handle to a copy of the window menu (HMENU). If the bRevert parameter is TRUE, the return value is NULL.

AppendMenu

Appends a new item to the end of the specified menu bar, drop-down menu, submenu, or shortcut menu. You can use this function to specify the content, appearance, and behavior of the menu item.

Syntax

BOOL WINAPI AppendMenu(
        HMENU hMenu,
        UINT uFlags,
        UINT_PTR uIDNewItem,
        LPCTSTR lpNewItem
);

Parameters

  • hMenu (HMENU) A handle to the menu bar, drop-down menu, submenu, or shortcut menu to be changed.
  • uFlags (UINT) Controls the appearance and behavior of the new menu item. This parameter can be a combination of the following values. Value Meaning MF_BITMAP, MF_CHECKED, MF_DISABLED, MF_ENABLED, MF_GRAYED, MF_MENUBARBREAK, MF_MENUBREAK, MF_OWNERDRAW, MF_POPUP, MF_SEPARATOR, MF_STRING,MF_UNCHECKED
  • uIDNewItem (UINT_PTR) The identifier of the new menu item or, if the uFlags parameter is set to MF_POPUP, a handle to the drop-down menu or submenu.
  • lpNewItem (LPCTSTR) The content of the new menu item. The interpretation of lpNewItem depends on whether the uFlags parameter includes the following values. MF_BITMAP, MF_OWNERDRAW, MF_STRING

Return value

If the function succeeds, the return value is nonzero. If the function fails, the return value is zero/FALSE. To get extended error information, call GetLastError.

Source Code

Here is a source code to demonstrate GetSystemMenu() function. It creates an additional entry in system menu. It also installs menu handler for this. It prompts a message box to the user and user can further revert this system menu calling GetSystemMenu() with argument as TRUE.

GetSystemMenu Demo Application screen shot

#include <windows.h>
#define IDM_MYSYSTEM 1001
LRESULT CALLBACK WndProc(HWND hWnd,
                         UINT message, 
                         WPARAM wParam,
                         LPARAM lParam);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  WNDCLASS wc;
  MSG msg;
  HWND hWnd;
  HMENU hMenu;

  ZeroMemory(&wc, sizeof(WNDCLASS));

  wc.style           = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc     = (WNDPROC)WndProc;
  wc.hInstance       = hInstance;
  wc.hCursor         = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground   = (HBRUSH)(COLOR_BACKGROUND);
  wc.lpszClassName   = (LPCTSTR)"MyWin32Class";


  RegisterClass(&wc);

   hWnd = CreateWindow("MyWin32Class", "GetSystemMenu Demo", WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);
  /* Get Menu Handle to top window */
  hMenu = GetSystemMenu(hWnd, FALSE);
  if(hMenu != INVALID_HANDLE_VALUE) {
    /* Append one separator menu item */
    AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
    /* Append string type menu */
    AppendMenu(hMenu, MF_STRING, IDM_MYSYSTEM, "My System Menu");
  }
  while (GetMessage(&msg, NULL, 0, 0)) 
  {
    DispatchMessage(&msg);
  }
  return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  int nSel;
  switch (message) 
  {
    /* System command handler */
    case WM_SYSCOMMAND:
      /* Handling our menu item */
      if(wParam == IDM_MYSYSTEM) {
        nSel = MessageBox (hWnd, "My System Menu. Want to disable?", "System Menu", MB_YESNO);
        if (nSel == IDYES){
          /* If yes we revert to original menu */
          GetSystemMenu(hWnd, TRUE);
        }
      }
      DefWindowProc(hWnd, message, wParam, lParam);
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

About our authors: Team EQA

Further readings

Where is WinMain() function in MFC application ?

MFC hides WinMain in its framework and includes source file on WinMain(). This explains how framework calls global CWinApp::Initinstance() from entry WinMain.

What is the utility of CWinApp class?

This is constructed during global C++ objects are constructed and is already available when Windows calls the WinMain function, which is supplied by the ...

Basic steps in Win32 GUI Application with source code.

Define a custom Window class structure, Register the class name, CreateWindow, Show windows and write message get and dispatch loop statements. Define the Window CallBack procedure and write the handlers.

What is a Window CallBack procedure and what is its utility?

DispatchMessage() is a API which indirectly triggers the Window CallBack procedure. Message structure members from this function are passed to the CallBack procedure. CallBack procedure should implement event handlers depending on the need of the application.

What are LPARAM and WPARAM in window proc function?

LPARAM and WPARAM are the two parameters in Window CallBack procedure. They signifies parameters of various events. They are used in handing individual events.

What are the basic steps of a typical MFC based application?

We need to write WinMain and need to follow all these in a Win32 application. However we need not to write much if we are writing an application with MFC ...

#