title: Menubar disappears when system colors are changed while the window is minimized
body: <p>My application has a toolbar type menu. I sub-classed the window procedure to allow visual enhancement, which means my application is painting the menubar.  When the application window is minimized and restored, the menu repaints just fine.</p>
  
  <p>But, if the system colors are changed while the application window is minimized, then the menubar disappears when the application window is restored. I found that when system colors change while the application window is minimized, <code>WM_PAINT</code> is not sent to the menubar after the window is restored.</p>
  
  <p>I tried the following:</p>
  
  <ol>
  <li><p>Force sending <code>WM_PAINT</code> to the menubar by calling <code>InvalidateRect()</code> in response to <code>WM_SIZE</code>, but it did not cause a <code>WM_PAINT</code> to be sent.</p></li>
  <li><p>Force sending <code>WM_PAINT</code> to the menubar by calling <code>RedrawWindow()</code> with the <code>RDW_INTERNALPAINT</code> flag. It succeeded in sending <code>WM_PAINT</code>, and the procedure for painting the menu is called. But still the menu does not show.</p></li>
  <li><p>Restore the window when the system colors change, by calling <code>ShowWindow()</code> in response to <code>WM_SYSCOLORCHANGE</code>. It worked. <code>WM_PAINT</code> is sent to the menubar and the menu shows up. However, I think it is rude to cause my window to popup suddenly, interrupting whatever the user is doing with some other program.</p></li>
  </ol>
  
  <p>Can anyone advise me how to keep the menubar painting correctly without restoring the window?</p>
  
  <p>Below is how I tried to do it.</p>
  
  <p>In the main window procedure:</p>
  
  <pre><code>LRESULT CALLBACK DlgWndProc (HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
  {
   static  int          HighContrastOn ;
   static  HWND         hwndMenuBar ;
   static  HINSTANCE    hThisInst ;
   static  NMTOOLBAR    nmtb = { NULL , IDC_MENUBAR , TBN_DROPDOWN , 0 } ;
   static  HIGHCONTRAST HighContrast = { sizeof (HIGHCONTRAST) , 0 , 0 } ;
  
   switch (msg) {
  
      case WM_CREATE :
          hThisInst = ((LPCREATESTRUCT) lParam)-&gt;hInstance ;
          SystemParametersInfo (SPI_GETHIGHCONTRAST,0,&amp;HighContrast,0) ;
          HighContrastOn = HighContrast.dwFlags &amp; HCF_HIGHCONTRASTON ;
          return 0 ;
  
      case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
  
      case WM_CLOSE :
          DestroyMenu (hMenu) ;
          DestroyWindow (hDlg);
          return 0 ;
  
      case WM_SYSCOLORCHANGE :
          ShowWindow (hDlg,SW_NORMAL) ;
          SendMessage (hwndMenuBar,WM_SYSCOLORCHANGE,0,0) ;
          return 0 ;
  
      case WM_SETTINGCHANGE :
          // Catch change in HighContrast status missed by WM_SYSCOLORCHANGE  
          SystemParametersInfo (SPI_GETHIGHCONTRAST,0,&amp;HighContrast,0) ;
          if (HighContrastOn == (HighContrast.dwFlags &amp; HCF_HIGHCONTRASTON))
              return 0 ;
          HighContrastOn = HighContrast.dwFlags &amp; HCF_HIGHCONTRASTON ;
          SendMessage (hwndMenuBar,WM_SYSCOLORCHANGE,0,0) ;
          return 0 ;
  
      case WM_NOTIFY :
          OnNotify (hDlg,wParam,lParam) ;
          break ;
  
      case WM_COMMAND :
          OnCommand (hDlg,wParam,lParam) ;
          break ;
  
      case WM_INITMENUPOPUP :
          int SubMenu ;
          SubMenu = (int) SendMessage (hwndMenuBar,TB_GETHOTITEM,0,0) ;
          for (int i = 0 ; i &lt; 5 ; i++) {
              if (GetSubMenu (hMenu,i) == (HMENU) wParam)
                  SendMessage (hwndMenuBar,WM_INITMENUPOPUP,SubMenu,0) ;
          } /* for (int i = 0 ; i &lt; 5 ; i++) */
          InitMenuPopup ((HMENU) wParam,SubMenu) ;
          return 0 ;
  
      case WM_UNINITMENUPOPUP :
          int i ;
          // Find out whther the closing menu is sub menu or sub-sub menu
          for (i = 0 ; i &lt; 5 ; i++) {
              if ((HMENU) wParam == GetSubMenu (hMenu,i))
                  break ;
          } /* for (i = 0 ; i &lt; 5 ; i++) */
          if (i &lt; 5) {
              UnhookWindowsHookEx (DefaultMsgHook) ;
              SendMessage (hDlg,WM_NOTIFY,IDC_MENUBAR,(LPARAM) &amp;nmtb) ;
              SendMessage (hwndMenuBar,WM_UNINITMENUPOPUP,0,0) ;
          } /* if (i &lt; 5) */
          return 0 ;
  
      case IDM_INIT :
          InitDialog (hDlg) ;
  
          hMenu = LoadMenu (hThisInst,"MyProgram") ;
          hwndMenuBar = GetDlgItem (hDlg,IDC_MENUBAR) ;
          nmtb.hdr.hwndFrom = hwndMenuBar ;
          SetWindowSubclass (hwndMenuBar,MenuBarProc,0,0) ;
          SendMessage (hwndMenuBar,WM_NULL,0,0) ;
          return 0 ;
  
  } /* switch (msg) */
  
  /* Pass unprocessed messages to DefDlgProc */
  return DefDlgProc (hDlg,msg,wParam,lParam) ;
  
  } /* DlgWndProc */
  
  
  LRESULT WINAPI MenuBarMsgHook (int Code,WPARAM wParam,LPARAM lParam)
  {
  static NMTOOLBAR nmtb ;
  
  switch (Code) {
  
      case MSGF_MENU :
          #define Msg ((LPMSG) lParam)
          HWND hwndMenuBar ;
          hwndMenuBar = GetDlgItem (Msg-&gt;hwnd,IDC_MENUBAR) ;
  
          switch (Msg-&gt;message) {
              POINT pt ;
  
              case WM_LBUTTONDOWN :
              case WM_RBUTTONDOWN :
                  pt = Msg-&gt;pt ;
                  ScreenToClient (hwndMenuBar,(LPPOINT) &amp;pt) ;
                  SendMessage (hwndMenuBar,Msg-&gt;message,wParam,
                               (LPARAM) MAKELONG (pt.x,pt.y)) ;
                  break ;
  
              case WM_MOUSEMOVE :
                  pt = Msg-&gt;pt ;
                  ScreenToClient (hwndMenuBar,(LPPOINT) &amp;pt) ;
                  SendMessage (hwndMenuBar,WM_MOUSEMOVE,wParam,
                               (LPARAM) MAKELONG (pt.x,pt.y)) ;
                  break ;
          } /* switch (Msg-&gt;message) */
          #undef Msg
  } /* switch (Code) */
  
  return CallNextHookEx (NULL,Code,wParam,lParam) ;
  
  } /* MenuBarMsgHook */
  
  
  LRESULT CALLBACK MenuBarProc (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam,
                                UINT_PTR uIdSubclass,DWORD_PTR dwRefData)
  {
  static  bool    BtnDown ;
  static  int     HighContrastOn ;
  static  int     yc ;
  static  int     xr ;
  static  int     yb ;
  static  int     HBtn = -1 ;
  static  char*   Text[] = {"File","Edit","Settings","Design","Help"} ;
  static  RECT    Rect[5] ;
  static  HFONT   Font ;
  static  HPEN    Pen ;
  static  HPEN    HPen ;
  static  HPEN    SPen ;
  static  HBRUSH  Brush ;
  static  HBRUSH  HBrush ;
  static  HBRUSH  SBrush ;
  static  COLORREF  BtnTextColor     = GetSysColor (COLOR_BTNTEXT) ;
  static  COLORREF  MenuColor        = GetSysColor (COLOR_MENUBAR) ;
  static  COLORREF  HotLightColor    = GetSysColor (COLOR_HOTLIGHT) ;
  static  COLORREF  HighLightColor   = GetSysColor (COLOR_HIGHLIGHT) ;
  static  COLORREF  HiLightTextColor = GetSysColor (COLOR_HIGHLIGHTTEXT) ;
  static  COLORREF  WindowFrameColor = GetSysColor (COLOR_WINDOWFRAME) ;
  
  static  HIGHCONTRAST HighContrast = { sizeof (HIGHCONTRAST) , 0 , 0 } ;
  static  TRACKMOUSEEVENT  tme = {sizeof (TRACKMOUSEEVENT),TME_LEAVE,NULL,
                                  HOVER_DEFAULT} ;
  HDC     hDC ;
  
  switch (msg) {
  
      case WM_NULL :
          SystemParametersInfo (SPI_GETHIGHCONTRAST,0,&amp;HighContrast,0) ;
          HighContrastOn = HighContrast.dwFlags &amp; HCF_HIGHCONTRASTON ;
  
          Font   = CreateMenuFont (hwnd) ;
          Pen    = (HPEN) GetStockObject (NULL_PEN) ;
          Brush  = CreateSolidBrush (MenuColor) ;
  
          if (HighContrastOn) {
              HPen   = CreatePen (PS_SOLID,0,WindowFrameColor) ;
              SPen   = CreatePen (PS_SOLID,0,WindowFrameColor) ;
              HBrush = CreateSolidBrush (HighLightColor) ;
              SBrush = CreateSolidBrush (HighLightColor) ;
          } /* if (HighContrastOn) */
          else {
              HPen   = CreatePen (PS_SOLID,0,0xF87400) ;
              SPen   = CreatePen (PS_SOLID,0,HotLightColor) ;
              HBrush = CreateSolidBrush (0xFFF4E6) ;
              SBrush = CreateSolidBrush (0xFED8B0) ;
          } /* else */
          for (int Btn = 0 ; Btn &lt; 5 ; Btn++)
              SendMessage (hwnd,TB_GETRECT,IDM_FILEMENU + Btn,(LPARAM) (Rect + Btn)) ;
  
          hDC = GetDC (hwnd) ;
          TEXTMETRIC  tm ;
          GetTextMetrics (hDC,&amp;tm) ;
          ReleaseDC (hwnd,hDC) ;
          yc = (Rect[0].bottom - Rect[0].top - tm.tmHeight) / 2 + tm.tmAscent - 1 ;
          xr = Rect[4].right ;
          yb = Rect[0].bottom ;
          tme.hwndTrack = hwnd ;
          return 0 ;
  
      case WM_PAINT :
          if (! GetUpdateRect (hwnd,NULL,false))
              break ;
          #define rc (Rect[Btn])
          PAINTSTRUCT ps ;
          hDC = BeginPaint (hwnd,&amp;ps) ;
  
          SelectObject (hDC,Font) ;
          SelectObject (hDC,Pen) ;
          SelectObject (hDC,Brush) ;
          SetTextAlign (hDC,TA_BASELINE | TA_CENTER) ;
          SetTextColor (hDC,BtnTextColor) ;
          SetBkMode (hDC,TRANSPARENT) ;
  
          for (int Btn = 0 ; Btn &lt; 5 ; Btn++) { 
              Rectangle (hDC,rc.left,rc.top,rc.right,rc.bottom) ;
              if (Btn == HBtn)
                  continue ;
              int xc = (rc.right + rc.left) / 2 ;
              ExtTextOut (hDC,xc,yc,ETO_NUMERICSLATIN,&amp;rc,Text[Btn],
                          (UINT) strlen (Text[Btn]),NULL) ;
          } /* for (int Btn = 0 ; Btn &lt; 5 ; Btn++) */
          #undef rc
  
          #define rc (Rect[HBtn])
          if (HBtn &gt; -1) {
              SelectObject (hDC,BtnDown ? SPen : HPen) ;
              SelectObject (hDC,BtnDown ? SBrush : HBrush) ;
              SetTextColor (hDC,HighContrastOn ? HiLightTextColor : BtnTextColor) ;
              RoundRect (hDC,rc.left + 1,rc.top + 1,rc.right - 1,rc.bottom - 2,2,2) ;
              int xc = (rc.right + rc.left) / 2 ;
              ExtTextOut (hDC,xc,yc,ETO_NUMERICSLATIN,&amp;rc,Text[HBtn],
                          (UINT) strlen (Text[HBtn]),NULL) ;
          } /* if (HBtn &gt; -1) */
          #undef rc
  
          EndPaint (hwnd,&amp;ps) ;
          return 0 ;
  
      case WM_SYSCOLORCHANGE :
          DeleteObject (HPen) ;
          DeleteObject (SPen) ;
          DeleteObject (Brush) ;
          DeleteObject (HBrush) ;
          DeleteObject (SBrush) ;
          HighLightColor   = GetSysColor (COLOR_HIGHLIGHT) ;
          WindowFrameColor = GetSysColor (COLOR_WINDOWFRAME) ;
          HotLightColor    = GetSysColor (COLOR_HOTLIGHT) ;
          HiLightTextColor = GetSysColor (COLOR_HIGHLIGHTTEXT) ;
          BtnTextColor     = GetSysColor (COLOR_BTNTEXT) ;
          MenuColor        = GetSysColor (COLOR_MENUBAR) ;
          SystemParametersInfo (SPI_GETHIGHCONTRAST,0,&amp;HighContrast,0) ;
          HighContrastOn = HighContrast.dwFlags &amp; HCF_HIGHCONTRASTON ;
          if (HighContrastOn) {
              HPen   = CreatePen (PS_SOLID,0,WindowFrameColor) ;
              SPen   = CreatePen (PS_SOLID,0,WindowFrameColor) ;
              HBrush = CreateSolidBrush (HighLightColor) ;
              SBrush = CreateSolidBrush (HighLightColor) ;
          } /* if (HighContrastOn) */
          else {
              HPen   = CreatePen (PS_SOLID,0,0xF87400) ;
              SPen   = CreatePen (PS_SOLID,0,HotLightColor) ;
              HBrush = CreateSolidBrush (0xFFF4E6) ;
              SBrush = CreateSolidBrush (0xFED8B0) ;
          } /* else */
          Brush  = CreateSolidBrush (MenuColor) ;
          return 0 ;
  
      case WM_NCDESTROY:
          DeleteObject (Font) ;
          DeleteObject (HPen) ;
          DeleteObject (SPen) ;
          DeleteObject (Brush) ;
          DeleteObject (HBrush) ;
          DeleteObject (SBrush) ;
          RemoveWindowSubclass (hwnd,MenuBarProc,0) ;
          break ;
  
      case WM_INITMENUPOPUP :
          HBtn = (int) wParam ;
          BtnDown = true ;
          InvalidateRect (hwnd,NULL,true) ;
          break ;
  
      case WM_UNINITMENUPOPUP :
          HBtn = -1 ;
          BtnDown = false ;
          InvalidateRect (hwnd,NULL,true) ;
          break ;
  
      case WM_MOUSEMOVE :
          #define rc (Rect[Btn])
          int x ;
          int y ;
          x = LOWORD (lParam) ;
          y = HIWORD (lParam) ;
          if (HBtn &gt; -1 &amp;&amp; x &gt; xr &amp;&amp; ! BtnDown) {
              HBtn = -1 ;
              InvalidateRect (hwnd,NULL,true) ;
              break ;
          } /* if (HBtn &gt; -1 &amp;&amp; x &gt; xr &amp;&amp; ! BtnDown) */
          for (int Btn = 0 ; Btn &lt; 5 ; Btn++) {
              if (y &lt; rc.bottom &amp;&amp; x &gt; rc.left &amp;&amp; x &lt; rc.right) {
                  if (Btn == HBtn)
                      break ;
                  HBtn = Btn ;
                  InvalidateRect (hwnd,NULL,true) ;
                  break ;
              } /* if (y &lt; rc.bottom &amp;&amp; x &gt; rc.left &amp;&amp; x &lt; rc.right) */
          } /* for (int Btn = 0 ; Btn &lt; 5 ; Btn++) */
          TrackMouseEvent (&amp;tme) ;
          #undef rc
          break ;
  
      case WM_MOUSELEAVE :
          if (! BtnDown) {
              HBtn = -1 ;
              InvalidateRect (hwnd,NULL,true) ;
          } /* if (! BtnDown) */
          return 0 ;
  
  } /* switch (msg) */
  
  return DefSubclassProc (hwnd,msg,wParam,lParam) ;
  
  } /* MenuBarProc */
  </code></pre>
  
  <p>Here is an extract of fn. InitDialog() showing initialization of menubar</p>
  
  <pre><code>#define  NUMBUTTONS   5
  
  static TBBUTTON  tbButtons[NUMBUTTONS] =
      {{I_IMAGENONE, IDM_FILEMENU   , TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_AUTOSIZE, {0}, 0,(INT_PTR) " File"} ,
       {I_IMAGENONE, IDM_EDITMENU   , TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_AUTOSIZE, {0}, 0,(INT_PTR) " Edit"} ,
       {I_IMAGENONE, IDM_SETTINGSMENU,TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_AUTOSIZE, {0}, 0,(INT_PTR) " Settings"} ,
       {I_IMAGENONE, IDM_DESIGNMENU , TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_AUTOSIZE, {0}, 0,(INT_PTR) " Design"} ,
       {I_IMAGENONE, IDM_HELPMENU   , TBSTATE_ENABLED, BTNS_DROPDOWN | BTNS_AUTOSIZE, {0}, 0,(INT_PTR) " Help"}} ;
  
  HFONT MenuFont = CreateMenuFont (hwndMenuBar) ;
  SendMessage (hwndMenuBar,WM_SETFONT,(WPARAM) MenuFont,false) ;
  SendMessage (hwndMenuBar,TB_BUTTONSTRUCTSIZE,(WPARAM) sizeof(TBBUTTON),0) ;
  SendMessage (hwndMenuBar,TB_ADDBUTTONS, (WPARAM) NUMBUTTONS, 
               (LPARAM) (LPTBBUTTON) &amp;tbButtons) ;
  
  SendMessage (hwndMenuBar,TB_AUTOSIZE,0,0) ;
  SendMessage (hwndMenuBar,TB_SETINDENT,2,0) ;
  ShowWindow (hwndMenuBar,SW_SHOW) ;
  
  SetWindowSubclass (hwndMenuBar,MenuBarProc,0,0) ;
  SendMessage (hwndMenuBar,WM_NULL,0,0) ;
  DeleteObject (MenuFont) ;
  </code></pre>
  
  <p>The menubar is defined in the dialog box resource as follows</p>
  
  <pre><code>CONTROL   " ",IDC_MENUBAR,"ToolbarWindow32",TBSTYLE_FLAT | TBSTYLE_LIST | WS_CLIPCHILDREN,0,0,0,0,0,HIDC_MENUBAR
  </code></pre>