如何自定义创建windows的右键弹出菜单(C++)

在进行windows编程时,很多人都会想到使用自定义的邮件弹出菜单。先上代码

实现文件:

//------------------------------------------------------------------------------
// File    : NewMenu.cpp
// Version : 1.25
// Date    : 25. June 2005
// Author  : Bruno Podetti
// Email   : Podetti@gmx.net
// Web     : www.podetti.com/NewMenu
// Systems : VC6.0/7.0 and VC7.1 (Run under (Window 98/ME), Windows Nt 2000/XP)
//           for all systems it will be the best when you install the latest IE
//           it is recommended for CNewToolBar
//
// For bugreport please add following informations
// - The CNewMenu version number (Example CNewMenu 1.16)
// - Operating system Win95 / WinXP and language (English / Japanese / German etc.)
// - Installed service packs
// - Version of internet explorer (important for CNewToolBar)
// - Short description how to reproduce the bug
// - Pictures/Sample are welcome too
// - You can write in English or German to the above email-address.
// - Have my compiled examples the same effect?
//------------------------------------------------------------------------------
//
// Special
// Compiled version with visual studio V7.0/7.1 doesn't run correctly on
// WinNt 4.0 nor Windows 95. For those platforms, you have to compile it with
// visual studio V6.0.
// (It may run with 7.0/7.1, but you must be sure to have all required and newest
//  dll from the MFC installed => otherwise menu painting problems)
// Keep in mind you should have installed latest service-packs to the operating-
// system too! (And a new IE because some fixes of common components were made)
//------------------------------------------------------------------------------
//
// ToDo's
// checking GDI-Leaks, are there some more?
// Shade-Drawing, when underground is changing
// Border repainting after menu closing!!!
// Shade painting problems? On Chinese or Japanese systems?
// supporting additional bitmap in menu with ownerdrawn style
//
// 25. June 2005 (Version 1.25)
// added compatibility for new security enhancement in CRT (MFC 8.0)
//
// 16. May 2005 (Version 1.24) 
// added tranparency to menu
// added some more information for visualtudio work better with messagemaps 
// safer handling of limitted HDC's
// added new function CreateBitmapMask
// - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
//   corrected background and highlight colors for XP styles.  Read comments dated May-05-2005 below for more information
//
// 23. January 2005 (Version 1.23) - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
// added another LoadToolbar() function to map a 16 color toolbar to a 256 color bitmap
// created CNewMenuThreadHook class to be instantiated and destroyed in a thread to setup and release the menu hook
// Bruno: Now we subclass only NewMenu (Drawing border etc.)
//
// 11. September 2004 (Version 1.22)
// added helperfunction for forcing compiler to export templatefunction
// better support for Hebrew or Arabic (MFT_RIGHTORDER)
// added new support for multiple monitors
// added some more details to errorhandling of CNewMenu ShowLastError only debug
// Changed AddTheme for compatibility to VisualStudio 2005
//
// 27. June 2004 (Version 1.21)
// colorsheme for office 2003 style changed and more like real office 2003
// enabled keyboardcues in style office 2003
// Old colorscheme from office 2003 is now called STYLE_COLORFUL
//
// 1. May 2004 (Version 1.20)
// additionally drawing for menubar
// added some compatibility issue with wine
// shading window (only test)
// changed the colorscheme with more theme support
// corected the menubar detection
//
// 6. February 2004 (Version 1.19)
// Icy and standard menu: systemmenu now with symbols
// underline enabling and disabling added, thanks to Robin Leatherbarrow
// make it compatible to 64-bit windows, thanks to David Pritchard
// added accelerator support to menu, thanks to Iain Clarke
// Corrected functions names SetXpBlendig/GetXpBlendig to SetXpBlending/GetXpBlending
// removed 3d-look from office 2003 style menu (now like real office 2003 menu)
// Handling of a normal menu-item in menubar changed
//
// 30. November 2003 (Version 1.18)
// minor changes for CNewToolBar
//
// 11. September 2003 Bug Fixes or nice hints from 1.16
// Better handling of menubar brushes (never destroy) Style_XP and STYLE_XP_2003
// Drawing of menuicons on WinNt 4.0 fixed
// spelling & initializing & unused brushes fixed, thanks to John Zegers
//
// 12. July 2003 Bug Fixes or nice hints from 1.15
// Added gradient-Dockbar (CNewDockBar) for office 2003 style
// (you need to define USE_NEW_DOCK_BAR)
// fixed menu checkmarks with bitmaps (Selection-with is not correct on all styles)
// Drawing to a memory-DC minimizing flickering
// with of menu-bar-item without & now better
//
// 22. June 2003 Bug Fixes or nice hints from 1.14
// Shortkey-handling for ModifyODMenu and InsertODMenu
// Change os identifer for OS>5.0 to WinXP
// Color scheme for Office menu changed and updating menubarcolor too
// Gradientcolor for Office 2003 bar
// XP-changing settings Border Style => fixed border painting without restarting
//
// 23. April 2003 Bug Fixes or nice hints from 1.13
// Fixed the window menu with extreme width, thanks to Voy
// Fix bug about shortkey for added menu item with AppendMenu, thanks to Mehdy Bohlool(Zy)
// Measureitem for default item corrected, thanks to LordLiverpool
// New menu style office 2003, but color schema is not tested, changing of menubar color
// on win95 and WinNt is not possible
// Menubardrawing on deactivated app corrected for win95 & WinNt4.0
//
// 23. January 2003 Bug Fixes or nice hints from 1.12
// Fixed SetMenuText, thanks to Eugene Plokhov
// Easier for having an other menu font, but on your own risk ;)
// Added new function SetNewMenuBorderAllMenu for borderhandling off non CNewMenu
//
// 22. December 2002 Bug Fixes or nice hints from 1.11
// Added some new tracing stuffs
// fixed SetMenuText
// XP-Style menu more office style and better handling with less 256 color, thanks to John Zegers
// Close window button disabling under XP with theme fixed
// Menubar color with theme fixed, thanks to Luther Weeks
//
// (9. November) Bug Fixes or nice hints from 1.11b
// Some new function for bleaching bitmaps, thanks to John Zegers
// GetSubMenu(LPCTSTR) , thanks to George Menhorn
// Menu animation under Win 98 fixed
// Borderdrawing a little better also under win 98
// Added new menustyle ICY
//
// (21. August 2002) Bug Fixes or nice hints from 1.10
// Bugfix for Windows NT 4.0 System Bitmaps, thanks to Christoph Weber
//
// (30. July 2002) Bug Fixes or nice hints from 1.03
// Color of checked icons / selection marks more XP-look
// Updating images 16 color by changing systems colors
// Icon drawing with more highlighting and half transparency
// Scroller for large menu correcting (but the overlapping border is not corrected)
// Resource-problem on windows 95/98/ME?, when using too much bitmaps in menus
//  changing the kind of storing bitmaps (images list)
// Calculating the size for a menuitem (specially submenuitem) corrected.
// Recentfilelist corrected (Seperator gots a wrong ID number)
//
// (25. June 2002) Bug Fixes or nice hints from 1.02
// Adding removing menu corrected for drawing the shade in menubar
// Draw the menuborder corrected under win 98 at the bottom side
// Highlighting under 98 for menu corrected (Assert), Neville Franks
//  Works also on Windows 95
// Changing styles on XP menucolor of the bar now corrected.
//
// (18. June 2002) Bug Fixes or nice hints from 1.01
// Popup menu which has more items than will fit, better
// LoadMenu changed for better languagessuport, SnowCat
// Bordercolor & Drawing of XP-Style-Menu changed to more XP-Look
// Added some functions for setting/reading MenuItemData and MenuData
// Menubar highlighting now supported under 98/ME (NT 4.0 and 95?)
// Font for menutitle can be changed
// Bugs for popupmenu by adding submenu corrected, no autodestroy
//
// (6. June 2002) Bug Fixes or nice hints from 1.00
// Loading Icons from a resource dll expanded (LoadToolBar) Jonathan de Halleux, Belgium.
// Minimized resource leak of User and Gdi objects
// Problem of disabled windows button on 98/Me solved
// Gradient-drawing without Msimg32.dll now supported especially for win 95
// Using solid colors for drawing menu items
// GetSubMenu changed to const
// Added helper function for setting popup-flag for popup menu (centered text)
// Redraw menu bar corrected after canceling popup menu in old style menu
//
// (23. Mai 2002) Bug Fixes and portions of code from previous version supplied by:
// Brent Corkum, Ben Ashley, Girish Bharadwaj, Jean-Edouard Lachand-Robert,
// Robert Edward Caldecott, Kenny Goers, Leonardo Zide, Stefan Kuhr,
// Reiner Jung, Martin Vladic, Kim Yoo Chul, Oz Solomonovich, Tongzhe Cui,
// Stephane Clog, Warren Stevens, Damir Valiulin
//
// You are free to use/modify this code but leave this header intact.
// This class is public domain so you are free to use it any of your
// applications (Freeware, Shareware, Commercial).
// All I ask is that you let me know so that if you have a real winner I can
// brag to my buddies that some of my code is in your app. I also wouldn't
// mind if you sent me a copy of your application since I like to play with
// new stuff.
//------------------------------------------------------------------------------

#include "stdafx.h"        // Standard windows header file
#include "NewMenu.h"       // CNewMenu class declaration

// Those two following constants should be only defined for tracing.
// Normally they are commented out.
//#define _TRACE_MENU_
//#define _TRACE_MENU_LOGFILE

//#define _NEW_MENU_USER_FONT
// For using an userfont you can set the define. It does not work right in the
// systemmenu nor in the menubar. But when you like to use the new menu only in
// popups then it will work, but it is newer a good idea to set or change the
// menufont.
// I do not support this mode, you use it on your own risk. :)
#ifdef _NEW_MENU_USER_FONT
static  LOGFONT MENU_USER_FONT = {20, 0, 0, 0, FW_NORMAL,
                                  0, 0, 0, DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,
                                  CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
                                  DEFAULT_PITCH,_T("Comic Sans MS")};
#endif

#ifdef _TRACE_MENU_
#include "MyTrace.h"
#endif

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
#endif

#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(hh) (HIWORD(hh)==NULL)
#endif

#define GAP 2

#ifndef COLOR_MENUBAR
#define COLOR_MENUBAR       30
#endif

#ifndef SPI_GETDROPSHADOW
#define SPI_GETDROPSHADOW   0x1024
#endif

#ifndef SPI_GETFLATMENU
#define SPI_GETFLATMENU     0x1022
#endif

#ifndef ODS_NOACCEL
#define ODS_NOACCEL         0x0100
#endif

#ifndef DT_HIDEPREFIX
#define DT_HIDEPREFIX  0x00100000
#endif

#ifndef DT_PREFIXONLY
#define DT_PREFIXONLY  0x00200000
#endif

#ifndef SPI_GETKEYBOARDCUES
#define SPI_GETKEYBOARDCUES                 0x100A
#endif

#ifndef _WIN64

#ifdef SetWindowLongPtrA
#undef SetWindowLongPtrA
#endif
inline LONG_PTR SetWindowLongPtrA( HWND hWnd, int nIndex, LONG_PTR dwNewLong )
{
  return( ::SetWindowLongA( hWnd, nIndex, LONG( dwNewLong ) ) );
}

#ifdef SetWindowLongPtrW
#undef SetWindowLongPtrW
#endif
inline LONG_PTR SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLong )
{
  return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) );
}

#ifdef GetWindowLongPtrA
#undef GetWindowLongPtrA
#endif
inline LONG_PTR GetWindowLongPtrA( HWND hWnd, int nIndex )
{
  return( ::GetWindowLongA( hWnd, nIndex ) );
}

#ifdef GetWindowLongPtrW
#undef GetWindowLongPtrW
#endif
inline LONG_PTR GetWindowLongPtrW( HWND hWnd, int nIndex )
{
  return( ::GetWindowLongW( hWnd, nIndex ) );
}

#ifndef GWLP_WNDPROC
#define GWLP_WNDPROC        (-4)
#endif

#ifndef SetWindowLongPtr
#ifdef UNICODE
#define SetWindowLongPtr  SetWindowLongPtrW
#else
#define SetWindowLongPtr  SetWindowLongPtrA
#endif // !UNICODE
#endif //SetWindowLongPtr

#ifndef GetWindowLongPtr
#ifdef UNICODE
#define GetWindowLongPtr  GetWindowLongPtrW
#else
#define GetWindowLongPtr  GetWindowLongPtrA
#endif // !UNICODE
#endif // GetWindowLongPtr

#endif //_WIN64


// Count of menu icons normal gloomed and grayed
#define MENU_ICONS    3

BOOL bHighContrast = FALSE;
BOOL bWine = FALSE;

typedef BOOL (WINAPI* FktGradientFill)( IN HDC, IN PTRIVERTEX, IN ULONG, IN PVOID, IN ULONG, IN ULONG);
typedef BOOL (WINAPI* FktIsThemeActive)();
typedef HRESULT (WINAPI* FktSetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList);

FktGradientFill pGradientFill = NULL;
FktIsThemeActive pIsThemeActive = NULL;
FktSetWindowTheme pSetWindowTheme = NULL;

BOOL GUILIBDLLEXPORT IsMenuThemeActive()
{
  return pIsThemeActive?pIsThemeActive():FALSE;
}


/
// Helper datatypes
class CToolBarData
{
public:
  WORD wVersion;
  WORD wWidth;
  WORD wHeight;
  WORD wItemCount;
  //WORD aItems[wItemCount]
  WORD* items()
  { return (WORD*)(this+1); }
};

class CNewMenuIconInfo
{
public:
  WORD wBitmapID;
  WORD wWidth;
  WORD wHeight;

  WORD* ids(){ return (WORD*)(this+1); }
};

// Helpers for casting
__inline HMENU UIntToHMenu(const unsigned int ui )
{
  return( (HMENU)(UINT_PTR)ui );
}

__inline HMENU HWndToHMenu(const HWND hWnd )
{
  return( (HMENU)hWnd );
}

__inline HWND HMenuToHWnd(const HMENU hMenu)
{
  return( (HWND)hMenu );
}

__inline UINT HWndToUInt(const HWND hWnd )
{
  return( (UINT)(UINT_PTR) hWnd);
}

__inline HWND UIntToHWnd(const UINT hWnd )
{
  return( (HWND)(UINT_PTR) hWnd);
}

__inline UINT HMenuToUInt(const HMENU hMenu )
{
  return( (UINT)(UINT_PTR) hMenu);
}

__inline LONG_PTR LongToPTR(const LONG value )
{
  return( LONG_PTR)value;
}

#ifdef _DEBUG
static void ShowLastError(LPCTSTR pErrorTitle=NULL)
{
  if(pErrorTitle==NULL)
{
    pErrorTitle=_T("Error from Menu");
  }
  DWORD error = GetLastError();
  if(error)
  {
    LPVOID lpMsgBuf=NULL;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      error,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
      (LPTSTR) &lpMsgBuf,
      0,
      NULL );
    if(lpMsgBuf)
    {
      // Display the string.
      MessageBox( NULL, (LPCTSTR)lpMsgBuf, pErrorTitle, MB_OK | MB_ICONINFORMATION );
      // Free the buffer.
      LocalFree( lpMsgBuf );
    }
    else
    {
      CString temp;
      temp.Format(_T("Error message 0x%lx not found"),error);
      // Display the string.
      MessageBox( NULL,temp, pErrorTitle, MB_OK | MB_ICONINFORMATION );
    }
  }
}
#else
#define ShowLastError(sz)
#endif


// this is a bad code! The timer 31 will be restartet, when it was used!!!!
UINT GetSafeTimerID(HWND hWnd, const UINT uiElapse)
{
  UINT nNewTimerId = NULL;
  if(IsWindow(hWnd))
  { // Try to start with TimerID 31, normaly is used 1, 10, or 100
    for(UINT nTimerId=31; nTimerId<100 && nNewTimerId==NULL; nTimerId++)
    { // Try to set a timer each uiElapse ms
      nNewTimerId = (UINT)::SetTimer(hWnd,nTimerId,uiElapse,NULL);
    }
    // Wow you have more than 69 timers!!!
    // Try to increase nTimerId<100 to nTimerId<1000;
    ASSERT(nNewTimerId);
  }
  return nNewTimerId;
}

WORD NumBitmapColors(LPBITMAPINFOHEADER lpBitmap)
{
  if ( lpBitmap->biClrUsed != 0)
    return (WORD)lpBitmap->biClrUsed;

  switch (lpBitmap->biBitCount)
  {
  case 1:
    return 2;
  case 4:
    return 16;
  case 8:
    return 256;
  }
  return 0;
}

int NumScreenColors()
{
  static int nColors = 0;
  if (!nColors)
  {
    // DC of the desktop
    CClientDC myDC(NULL);
    nColors = myDC.GetDeviceCaps(NUMCOLORS);
    if (nColors == -1)
    {
      nColors = 64000;
    }
  }
  return nColors;
}

HBITMAP LoadColorBitmap(LPCTSTR lpszResourceName, HMODULE hInst, int* pNumcol)
{
  if(hInst==0)
  {
    hInst = AfxFindResourceHandle(lpszResourceName, RT_BITMAP);
  }
  HRSRC hRsrc = ::FindResource(hInst,MAKEINTRESOURCE(lpszResourceName),RT_BITMAP);
  if (hRsrc == NULL)
    return NULL;

  // determine how many colors in the bitmap
  HGLOBAL hglb;
  if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
    return NULL;

  LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
  if (lpBitmap == NULL)
    return NULL;
  WORD numcol = NumBitmapColors(lpBitmap);
  if(pNumcol)
  {
    *pNumcol = numcol;
  }

  UnlockResource(hglb);
  FreeResource(hglb);

  return LoadBitmap(hInst,lpszResourceName);
 
}

HBITMAP CreateBitmapMask(HBITMAP hbmColour, COLORREF crTransparent)
{
  HBITMAP hbmMask = NULL;
  BITMAP bm = {0};
  if(GetObject(hbmColour, sizeof(BITMAP), &bm))
  {
    hbmMask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);
    if(hbmMask)
    {
      // Get some HDCs that are compatible with the display driver
      HDC hdcMem = CreateCompatibleDC(0);
      HDC hdcMem2 = CreateCompatibleDC(0);

      SelectObject(hdcMem, hbmColour);
      SelectObject(hdcMem2, hbmMask);

      // Set the background colour of the colour image to the colour
      // you want to be transparent.
      SetBkColor(hdcMem, crTransparent);

      // Copy the bits from the colour image to the B+W mask... everything
      // with the background colour ends up white while everythig else ends up
      // black...Just what we wanted.
      BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

      // Take our new mask and use it to turn the transparent colour in our
      // original colour image to black so the transparency effect will
      // work right.
      BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCINVERT);

      // Clean up.
      DeleteDC(hdcMem);
      DeleteDC(hdcMem2);
    }
  }
  return hbmMask;
}


COLORREF MakeGrayAlphablend(CBitmap* pBitmap, int weighting, COLORREF blendcolor)
{
  CDC myDC;
  // Create a compatible bitmap to the screen
  myDC.CreateCompatibleDC(0);
  // Select the bitmap into the DC
  CBitmap* pOldBitmap = myDC.SelectObject(pBitmap);

  BITMAP myInfo = {0};
  GetObject((HGDIOBJ)pBitmap->m_hObject,sizeof(myInfo),&myInfo);

  for (int nHIndex = 0; nHIndex < myInfo.bmHeight; nHIndex++)
  {
    for (int nWIndex = 0; nWIndex < myInfo.bmWidth; nWIndex++)
    {
      COLORREF ref = myDC.GetPixel(nWIndex,nHIndex);

      // make it gray
      DWORD nAvg =  (GetRValue(ref) + GetGValue(ref) + GetBValue(ref))/3;

      // Algorithme for alphablending
      //dest' = ((weighting * source) + ((255-weighting) * dest)) / 256
      DWORD refR = ((weighting * nAvg) + ((255-weighting) * GetRValue(blendcolor))) / 256;
      DWORD refG = ((weighting * nAvg) + ((255-weighting) * GetGValue(blendcolor))) / 256;;
      DWORD refB = ((weighting * nAvg) + ((255-weighting) * GetBValue(blendcolor))) / 256;;

      myDC.SetPixel(nWIndex,nHIndex,RGB(refR,refG,refB));
    }
  }
  COLORREF topLeftColor = myDC.GetPixel(0,0);
  myDC.SelectObject(pOldBitmap);
  return topLeftColor;
}

class CNewLoadLib
{
public:

  HMODULE m_hModule;
  void* m_pProg;

  CNewLoadLib(LPCTSTR pName,LPCSTR pProgName)
  {
    m_hModule = LoadLibrary(pName);
    m_pProg = m_hModule ? (void*)GetProcAddress (m_hModule,pProgName) : NULL;
  }

  ~CNewLoadLib()
  {
    if(m_hModule)
    {
      FreeLibrary(m_hModule);
      m_hModule = NULL;
    }
  }
};



#if(WINVER < 0x0500)

DECLARE_HANDLE(HMONITOR);

typedef struct tagMONITORINFO
{
  DWORD  cbSize;
  RECT   rcMonitor;
  RECT   rcWork;
  DWORD  dwFlags;
} MONITORINFO, *LPMONITORINFO;

BOOL GetMonitorInfo( HMONITOR hMonitor, LPMONITORINFO lpmi)
{
#ifdef UNICODE
  static CNewLoadLib menuInfo(_T("user32.dll"),"GetMonitorInfoW");
#else
  static CNewLoadLib menuInfo(_T("user32.dll"),"GetMonitorInfoA");
#endif
  if(menuInfo.m_pProg)
  {
    typedef BOOL (WINAPI* FktGetMonitorInfo)( HMONITOR,  LPMONITORINFO);
    return ((FktGetMonitorInfo)menuInfo.m_pProg)(hMonitor,lpmi);
  }
  return FALSE;
}

#define MONITOR_DEFAULTTONULL       0x00000000
#define MONITOR_DEFAULTTOPRIMARY    0x00000001
#define MONITOR_DEFAULTTONEAREST    0x00000002

#define MONITORINFOF_PRIMARY        0x00000001

HMONITOR MonitorFromWindow(
  HWND hwnd,       // handle to a window
  DWORD dwFlags    // determine return value
)
{
  static CNewLoadLib menuInfo(_T("user32.dll"),"MonitorFromWindow");
  if(menuInfo.m_pProg)
  {
    typedef HMONITOR (WINAPI* FktMonitorFromWindow)( HWND,  DWORD);
    return ((FktMonitorFromWindow)menuInfo.m_pProg)(hwnd,dwFlags);
  }
  return NULL;
}

HMONITOR MonitorFromRect(
  LPCRECT lprc,    // rectangle
  DWORD dwFlags    // determine return value
)
{
  static CNewLoadLib menuInfo(_T("user32.dll"),"MonitorFromRect");
  if(menuInfo.m_pProg)
  {
    typedef HMONITOR (WINAPI* FktMonitorFromRect)( LPCRECT,  DWORD);
    return ((FktMonitorFromRect)menuInfo.m_pProg)(lprc,dwFlags);
  }
  return NULL;
}


BOOL GetMenuInfo( HMENU hMenu, LPMENUINFO pInfo)
{
  static CNewLoadLib menuInfo(_T("user32.dll"),"GetMenuInfo");
  if(menuInfo.m_pProg)
  {
    typedef BOOL (WINAPI* FktGetMenuInfo)(HMENU, LPMENUINFO);
    return ((FktGetMenuInfo)menuInfo.m_pProg)(hMenu,pInfo);
  }
  return FALSE;
}

BOOL SetMenuInfo( HMENU hMenu, LPCMENUINFO pInfo)
{
  static CNewLoadLib menuInfo(_T("user32.dll"),"SetMenuInfo");
  if(menuInfo.m_pProg)
  {
    typedef BOOL (WINAPI* FktSetMenuInfo)(HMENU, LPCMENUINFO);
    return ((FktSetMenuInfo)menuInfo.m_pProg)(hMenu,pInfo);
  }
  return FALSE;
}

DWORD GetLayout(HDC hDC)
{
  static CNewLoadLib getLayout(_T("gdi32.dll"),"GetLayout");
  if(getLayout.m_pProg)
  {
    typedef DWORD (WINAPI* FktGetLayout)(HDC);
    return ((FktGetLayout)getLayout.m_pProg)(hDC);
  }
  return NULL;
}

DWORD SetLayout(HDC hDC, DWORD dwLayout)
{
  static CNewLoadLib setLayout(_T("gdi32.dll"),"SetLayout");
  if(setLayout.m_pProg)
  {
    typedef DWORD (WINAPI* FktSetLayout)(HDC,DWORD);
    return ((FktSetLayout)setLayout.m_pProg)(hDC,dwLayout);
  }
  return NULL;
}

#define WS_EX_LAYERED 0x00080000
#define LWA_ALPHA    2 // Use bAlpha to determine the opacity of the layer

BOOL SetLayeredWindowAttributes(HWND hWnd, COLORREF cr, BYTE bAlpha, DWORD dwFlags)
{
  static CNewLoadLib setLayout(_T("User32.dll"),"SetLayeredWindowAttributes");
  if(setLayout.m_pProg)
  {
    typedef  BOOL (WINAPI *lpfnSetLayeredWindowAttributes) (HWND hWnd, COLORREF cr, BYTE bAlpha, DWORD dwFlags);
    return ((lpfnSetLayeredWindowAttributes)setLayout.m_pProg)(hWnd, cr, bAlpha, dwFlags);
  }
  return false;
}



#endif

void MenuDrawText(HDC hDC ,LPCTSTR lpString,int nCount,LPRECT lpRect,UINT uFormat)
{
  if(nCount==-1)
  {
    nCount = lpString?(int)_tcslen(lpString):0;
  }
  LOGFONT logfont = {0};
  if(!GetObject(GetCurrentObject(hDC, OBJ_FONT),sizeof(logfont),&logfont))
  {
    logfont.lfOrientation = 0;
  }
  size_t bufSizeTChar = nCount + 1;
  TCHAR* pBuffer = (TCHAR*)_alloca(bufSizeTChar*sizeof(TCHAR));
  _tcsncpy_s(pBuffer,bufSizeTChar,lpString,nCount);
  pBuffer[nCount] = 0;

  UINT oldAlign =  GetTextAlign(hDC);

  const int nBorder=4;
  HGDIOBJ hOldFont = NULL;
  CFont TempFont;

  TEXTMETRIC textMetric;
  if (!GetTextMetrics(hDC, &textMetric))
  {
    textMetric.tmOverhang = 0;
    textMetric.tmAscent = 0;
  }
  else if ((textMetric.tmPitchAndFamily&(TMPF_VECTOR|TMPF_TRUETYPE))==0 )
  {
    // we have a bitmapfont it is not possible to rotate
    if(logfont.lfOrientation || logfont.lfEscapement)
    {
      hOldFont = GetCurrentObject(hDC,OBJ_FONT);
      _tcscpy_s(logfont.lfFaceName,ARRAY_SIZE(logfont.lfFaceName),_T("Arial"));
      // we need a truetype font for rotation
      logfont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
      // the font will be destroyed at the end by destructor
      TempFont.CreateFontIndirect(&logfont);
      // we select at the end the old font
      SelectObject(hDC,TempFont);
      GetTextMetrics(hDC, &textMetric);
    }
  }

  DWORD dwLayout = GetLayout(hDC);
  if(dwLayout&LAYOUT_RTL)
  {
    SetTextAlign (hDC,TA_RIGHT|TA_TOP|TA_UPDATECP);
  }
  else
  {
    SetTextAlign (hDC,TA_LEFT|TA_TOP|TA_UPDATECP);
  }
  CPoint pos(lpRect->left,lpRect->top);

  if( (uFormat&DT_VCENTER) &&lpRect)
  {
    switch(logfont.lfOrientation%3600)
    {
    default:
    case 0:
      logfont.lfOrientation = 0;
      pos.y = (lpRect->top+lpRect->bottom-textMetric.tmHeight)/2;
      if(dwLayout&LAYOUT_RTL)
      {
        pos.x = lpRect->right - nBorder;
      }
      else
      {
        pos.x = lpRect->left + nBorder;
      }
      break;

    case 1800:
    case -1800:
      logfont.lfOrientation = 1800;
      pos.y = (lpRect->top+textMetric.tmHeight +lpRect->bottom)/2;
      if(dwLayout&LAYOUT_RTL)
      {
        pos.x = lpRect->left + nBorder;
      }
      else
      {
        pos.x = lpRect->right - nBorder;
      }
      break;

    case 900:
    case -2700:
      logfont.lfOrientation = 900;
      pos.x = (lpRect->left+lpRect->right-textMetric.tmHeight)/2;
      pos.y = lpRect->bottom - nBorder;
      if(dwLayout&LAYOUT_RTL)
      {
        pos.y = lpRect->top + nBorder;
      }
      else
      {
        pos.y = lpRect->bottom - nBorder;
      }
      break;

    case -900:
    case 2700:
      logfont.lfOrientation = 2700;
      pos.x = (lpRect->left+lpRect->right+textMetric.tmHeight)/2;
      if(dwLayout&LAYOUT_RTL)
      {
        pos.y = lpRect->bottom - nBorder;
      }
      else
      {
        pos.y = lpRect->top + nBorder;
      }
      break;
    }
  }

  CPoint oldPos;
  MoveToEx(hDC,pos.x,pos.y,&oldPos);

  while(nCount)
  {
    TCHAR *pTemp =_tcsstr(pBuffer,_T("&"));
    if(pTemp)
    {
      // we found &
      if(*(pTemp+1)==_T('&'))
      {
        // the different is in character unicode and byte works
        int nTempCount = DWORD(pTemp-pBuffer)+1;
        ExtTextOut(hDC,pos.x,pos.y,ETO_CLIPPED,lpRect,pBuffer,nTempCount,NULL);
        nCount -= nTempCount+1;
        pBuffer = pTemp+2;
      }
      else
      {
        // draw underline the different is in character unicode and byte works
        int nTempCount = DWORD(pTemp-pBuffer);
        ExtTextOut(hDC,pos.x,pos.y,ETO_CLIPPED,lpRect,pBuffer,nTempCount,NULL);
        nCount -= nTempCount+1;
        pBuffer = pTemp+1;
        if(!(uFormat&DT_HIDEPREFIX) )
        {
          CSize size;
          GetTextExtentPoint(hDC, pTemp+1, 1, &size);
          GetCurrentPositionEx(hDC,&pos);

          COLORREF oldColor = SetBkColor(hDC, GetTextColor(hDC));
          LONG cx = size.cx - textMetric.tmOverhang / 2;
          LONG nTop;
          CRect rc;
          switch(logfont.lfOrientation)
          {
          case 0:
            // Get height of text so that underline is at bottom.
            nTop = pos.y + textMetric.tmAscent + 1;
            // Draw the underline using the foreground color.
            if(dwLayout&LAYOUT_RTL)
            {
              rc.SetRect(pos.x-cx+2, nTop, pos.x+1, nTop+1);
            }
            else
            {
              rc.SetRect(pos.x, nTop, pos.x+cx, nTop+1);
            }
            ExtTextOut(hDC, pos.x, nTop, ETO_OPAQUE, &rc, _T(""), 0, NULL);
            break;

          case 1800:
            // Get height of text so that underline is at bottom.
            nTop = pos.y -(textMetric.tmAscent + 1);
            // Draw the underline using the foreground color.
            if(dwLayout&LAYOUT_RTL)
            {
              rc.SetRect(pos.x-1, nTop-1, pos.x+cx-1, nTop);
            }
            else
            {
              rc.SetRect(pos.x-cx, nTop-1, pos.x, nTop);
            }
            ExtTextOut(hDC, pos.x, nTop, ETO_OPAQUE, &rc, _T(""), 0, NULL);
            break;

          case 900:
            // draw up
            // Get height of text so that underline is at bottom.
            nTop = pos.x + (textMetric.tmAscent + 1);
            // Draw the underline using the foreground color.
            if(dwLayout&LAYOUT_RTL)
    {
              rc.SetRect(nTop-1, pos.y, nTop, pos.y+cx-2);
    }
    else
    {
              rc.SetRect(nTop, pos.y-cx, nTop+1, pos.y);
            }
            ExtTextOut(hDC, nTop, pos.y, ETO_OPAQUE, &rc, _T(""), 0, NULL);
            break;

          case 2700:
            // draw down
            // Get height of text so that underline is at bottom.
            nTop = pos.x -(textMetric.tmAscent + 1);
            // Draw the underline using the foreground color.
            if(dwLayout&LAYOUT_RTL)
            {
              rc.SetRect(nTop, pos.y-cx+1 , nTop+1, pos.y);
    }
            else
            {
              rc.SetRect(nTop-1, pos.y, nTop, pos.y+cx);
  }
            ExtTextOut(hDC, nTop, pos.y, ETO_OPAQUE, &rc, _T(""), 0, NULL);
            break;
}
          SetBkColor(hDC, oldColor);
          // corect the actual drawingpoint
          MoveToEx(hDC,pos.x,pos.y,NULL);
    }
  }
}
    else
{
      // draw the rest of the string
      ExtTextOut(hDC,pos.x,pos.y,ETO_CLIPPED,lpRect,pBuffer,nCount,NULL);
      break;
    }
  }
  // restore old point
  MoveToEx(hDC,oldPos.x,oldPos.y,NULL);
  // restore old align
  SetTextAlign(hDC,oldAlign);

  if(hOldFont!=NULL)
  {
    SelectObject(hDC,hOldFont);
  }
}


CRect GUILIBDLLEXPORT GetScreenRectFromWnd(HWND hWnd)
{
  CRect rect;
  HMONITOR hMonitor = MonitorFromWindow(hWnd,MONITOR_DEFAULTTONEAREST);
  MONITORINFO monitorinfo={0};
  monitorinfo.cbSize = sizeof(monitorinfo);
  if(hMonitor!=NULL && GetMonitorInfo(hMonitor,&monitorinfo))
  {
    rect = monitorinfo.rcWork;
  }
  else
    {
    rect.SetRect(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
    }
  return rect;
}

CRect GUILIBDLLEXPORT GetScreenRectFromRect(LPCRECT pRect)
{
  CRect rect;
  HMONITOR hMonitor = MonitorFromRect(pRect,MONITOR_DEFAULTTONEAREST);
  MONITORINFO monitorinfo={0};
  monitorinfo.cbSize = sizeof(monitorinfo);
  if(hMonitor!=NULL && GetMonitorInfo(hMonitor,&monitorinfo))
  {
    rect = monitorinfo.rcWork;
  }
  else
  {
    rect.SetRect(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
  }
  return rect;
}

 BOOL GUILIBDLLEXPORT TrackPopupMenuSpecial(CMenu *pMenu, UINT uFlags, CRect rcTBItem, CWnd *pWndCommand, BOOL bOnSide)
{
   CRect rect = GetScreenRectFromRect(rcTBItem);
   CPoint CenterPoint = rect.CenterPoint();
   CNewMenu* pNewMenu = DYNAMIC_DOWNCAST(CNewMenu,pMenu);

   if(bOnSide)
   {
     if(CenterPoint.x<rcTBItem.right)
     {
       // menu on the right side of the screen
       if(rcTBItem.left<=rect.left){rcTBItem.left=rect.left+1;}
       if(rcTBItem.top<rect.top){rcTBItem.top=rect.top;}
       if(IsMirroredWnd(pWndCommand->GetSafeHwnd()))
  {
        return pMenu->TrackPopupMenu(TPM_LEFTBUTTON|uFlags, rcTBItem.left-1, rcTBItem.top+1,pWndCommand,NULL);
       }
       else
    {
        return pMenu->TrackPopupMenu(TPM_LEFTBUTTON|TPM_RIGHTALIGN|uFlags, rcTBItem.left-1, rcTBItem.top+1,pWndCommand,NULL);
       }
    }
     else
     {
       if(rcTBItem.right<=rect.left){rcTBItem.right=rect.left+1;}
       if(rcTBItem.top<rect.top){rcTBItem.top=rect.top;}
       return pMenu->TrackPopupMenu(TPM_LEFTBUTTON|uFlags, rcTBItem.right-1, rcTBItem.top+1,pWndCommand,NULL);
  }
}
   else
{
     int nMenuHeight = 0;
     if(pNewMenu)
  {
       CSize size = pNewMenu->GetIconSize();
       // calculate more or less the height, seperators and titles may be wrong
       nMenuHeight = pNewMenu->GetMenuItemCount()*size.cy;
  }

     bool bMenuAbove = CenterPoint.y<rcTBItem.top;
     if(bMenuAbove && nMenuHeight)
  {
       if((rcTBItem.bottom+nMenuHeight)<rect.bottom)
    {
         bMenuAbove = false;
    }
  }

     if(bMenuAbove)
     {
       // bottom of the screen
       if(rcTBItem.left<rect.left){rcTBItem.left=rect.left;}
       if(rcTBItem.top>rect.bottom){rcTBItem.top=rect.bottom;}
       if(IsMirroredWnd(pWndCommand->GetSafeHwnd()))
{
        return pMenu->TrackPopupMenu(TPM_LEFTBUTTON|TPM_BOTTOMALIGN|TPM_RIGHTALIGN|uFlags, rcTBItem.left, rcTBItem.top,pWndCommand,rcTBItem);
       }
       else
  {
        return pMenu->TrackPopupMenu(TPM_LEFTBUTTON|TPM_BOTTOMALIGN|uFlags, rcTBItem.left, rcTBItem.top,pWndCommand,rcTBItem);
  }
}
     else
     {
       // top of the screen
       if(rcTBItem.left<rect.left){rcTBItem.left=rect.left;}
       if(rcTBItem.bottom<rect.top){rcTBItem.bottom=rect.top;}
       if(IsMirroredWnd(pWndCommand->GetSafeHwnd()))
{
        return pMenu->TrackPopupMenu(TPM_LEFTBUTTON|TPM_RIGHTALIGN|uFlags, rcTBItem.left, rcTBItem.bottom,pWndCommand,rcTBItem);
       }
       else
  {
        return pMenu->TrackPopupMenu(TPM_LEFTBUTTON|uFlags, rcTBItem.left, rcTBItem.bottom,pWndCommand,rcTBItem);
       }
     }
  }
}

class CNewBrushList : public CObList
{
public:
  CNewBrushList(){}
  ~CNewBrushList()
  {
    while(!IsEmpty())
    {
      delete RemoveTail();
    }
  }
};

class CNewBrush : public CBrush
{
public:
  UINT m_nMenuDrawMode;
  COLORREF m_BarColor;
  COLORREF m_BarColor2;

  CNewBrush(UINT menuDrawMode, COLORREF barColor, COLORREF barColor2):m_nMenuDrawMode(menuDrawMode),m_BarColor(barColor),m_BarColor2(barColor2)
  {
    if (g_Shell!=WinNT4 &&
        g_Shell!=Win95 &&
        (menuDrawMode==CNewMenu::STYLE_XP_2003 || menuDrawMode==CNewMenu::STYLE_COLORFUL))
    {
      // Get the desktop hDC...
      HDC hDcDsk = GetWindowDC(0);
      CDC* pDcDsk = CDC::FromHandle(hDcDsk);

      CDC clientDC;
      clientDC.CreateCompatibleDC(pDcDsk);

      CRect rect(0,0,(GetSystemMetrics(SM_CXFULLSCREEN)+16)&~7,20);

      CBitmap bitmap;
      bitmap.CreateCompatibleBitmap(pDcDsk,rect.Width(),rect.Height());
      CBitmap* pOldBitmap = clientDC.SelectObject(&bitmap);

      int nRight = rect.right;
      if(rect.right>700)
      {
        rect.right  = 700;
        DrawGradient(&clientDC,rect,barColor,barColor2,TRUE,TRUE);
        rect.left = rect.right;
        rect.right = nRight;
        clientDC.FillSolidRect(rect, barColor2);
      }
      else
      {
        DrawGradient(&clientDC,rect,barColor,barColor2,TRUE,TRUE);
      }
      clientDC.SelectObject(pOldBitmap);

      // Release the desktopdc
      ReleaseDC(0,hDcDsk);

      CreatePatternBrush(&bitmap);
    }
    else
    {
      CreateSolidBrush(barColor);
    }
  }
};

CBrush* GetMenuBarBrush()
{
  // The brushes will be destroyed at program-end => Not a memory-leak
  static CNewBrushList brushList;
  static CNewBrush* lastBrush = NULL;

  COLORREF menuBarColor;
  COLORREF menuBarColor2;  //JUS

  UINT nMenuDrawMode = CNewMenu::GetMenuDrawMode();

  switch(nMenuDrawMode)
  {
  case CNewMenu::STYLE_XP_2003 :
  case CNewMenu::STYLE_XP_2003_NOBORDER :
    {
      CNewMenu::GetMenuBarColor2003(menuBarColor, menuBarColor2);
      if (NumScreenColors()>=256 && !bHighContrast)
      {
        nMenuDrawMode = CNewMenu::STYLE_XP_2003;
      }
      else
      {
       menuBarColor = menuBarColor2 = GetSysColor(COLOR_3DFACE);
       nMenuDrawMode = CNewMenu::STYLE_XP;
      }
    }
    break;

  case CNewMenu::STYLE_COLORFUL :
  case CNewMenu::STYLE_COLORFUL_NOBORDER :
    {
      CNewMenu::GetMenuBarColor2003(menuBarColor, menuBarColor2);
      if (NumScreenColors()>=256 && !bHighContrast)
      {
        nMenuDrawMode = CNewMenu::STYLE_COLORFUL;
      }
      else
      {
        nMenuDrawMode = CNewMenu::STYLE_XP;
      }
    }
    break;

  case CNewMenu::STYLE_XP :
  case CNewMenu::STYLE_XP_NOBORDER :
    menuBarColor = menuBarColor2 = GetSysColor(COLOR_3DFACE);
    nMenuDrawMode = CNewMenu::STYLE_XP;
    break;

  default:
    return NULL;
  }

  // check if the last brush the one which we want
  if(lastBrush!=NULL &&
     lastBrush->m_nMenuDrawMode==nMenuDrawMode &&
     lastBrush->m_BarColor==menuBarColor &&
     lastBrush->m_BarColor2==menuBarColor2)
  {
    return lastBrush;
  }

  // Check if the brush is allready created
  POSITION pos = brushList.GetHeadPosition();
  while (pos)
  {
    lastBrush = (CNewBrush*)brushList.GetNext(pos);
    if(lastBrush!=NULL &&
      lastBrush->m_nMenuDrawMode==nMenuDrawMode &&
      lastBrush->m_BarColor==menuBarColor &&
      lastBrush->m_BarColor2==menuBarColor2)
    {
      return lastBrush;
    }
  }
  // create a new one and insert into the list
  brushList.AddHead(lastBrush = new CNewBrush(nMenuDrawMode,menuBarColor,menuBarColor2));
  return lastBrush;
}

void UpdateMenuBarColor(HMENU hMenu)
{
  CBrush* pBrush = GetMenuBarBrush();

  // for WindowsBlind activating it's better for not to change menubar background
  if(!pBrush /* || (pIsThemeActive && pIsThemeActive()) */ )
  {
    // menubackground hasn't been set
    return;
  }

  MENUINFO menuInfo = {0};
  menuInfo.cbSize = sizeof(menuInfo);
  menuInfo.hbrBack = *pBrush;
  menuInfo.fMask = MIM_BACKGROUND;

  // Change color only for CNewMenu and derived classes
  if(IsMenu(hMenu) && DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(hMenu))!=NULL)
  {
    SetMenuInfo(hMenu,&menuInfo);
  }

  CWinApp* pWinApp = AfxGetApp();
  // Update menu from template
  if(pWinApp)
  {
    CDocManager* pManager = pWinApp->m_pDocManager;
    if(pManager)
    {
      POSITION pos = pManager->GetFirstDocTemplatePosition();
      while(pos)
      {
        CDocTemplate* pTemplate = pManager->GetNextDocTemplate(pos);
        CMultiDocTemplate* pMultiTemplate = DYNAMIC_DOWNCAST(CMultiDocTemplate,pTemplate);
        if(pMultiTemplate)
        {
          // Change color only for CNewMenu and derived classes
          if(DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(pMultiTemplate->m_hMenuShared))!=NULL)
          {
            // need for correct menubar color
            SetMenuInfo(pMultiTemplate->m_hMenuShared,&menuInfo);
          }
        }

        /*      // does not work with embeded menues
        if(pTemplate)
        {
        // Change color only for CNewMenu and derived classes
        // need for correct menubar color
        if(DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(pTemplate->m_hMenuInPlace))!=NULL)
        {
        // menu & accelerator resources for in-place container
        SetMenuInfo(pTemplate->m_hMenuInPlace,&menuInfo);
        }
        if(DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(pTemplate->m_hMenuEmbedding))!=NULL)
        {
        // menu & accelerator resource for server editing embedding
        SetMenuInfo(pTemplate->m_hMenuEmbedding,&menuInfo);
        }
        if(DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(pTemplate->m_hMenuInPlaceServer))!=NULL)
        {
        // menu & accelerator resource for server editing in-place
        SetMenuInfo(pTemplate->m_hMenuInPlaceServer,&menuInfo);
        }
        }
        */
      }
    }
  }
}

BOOL DrawMenubarItem(CWnd* pWnd,CMenu* pMenu, UINT nItemIndex,UINT nState)
{
  CRect itemRect;
  if (nItemIndex!=UINT(-1) && GetMenuItemRect(pWnd->m_hWnd,pMenu->m_hMenu, nItemIndex, &itemRect))
  {
    MENUITEMINFO menuInfo = {0};
    menuInfo.cbSize = sizeof(menuInfo);
    menuInfo.fMask = MIIM_DATA|MIIM_TYPE|MIIM_ID;
    if(pMenu->GetMenuItemInfo(nItemIndex,&menuInfo,TRUE))
    {
      // Only ownerdrawn were allowed
      if(menuInfo.fType&MF_OWNERDRAW)
      {
        CWindowDC dc(pWnd);

        CFont fontMenu;
        LOGFONT logFontMenu;

#ifdef _NEW_MENU_USER_FONT
        logFontMenu =  MENU_USER_FONT;
#else
        NONCLIENTMETRICS nm = {0};
        nm.cbSize = sizeof (NONCLIENTMETRICS);
        VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
        logFontMenu =  nm.lfMenuFont;
#endif

        fontMenu.CreateFontIndirect (&logFontMenu);
        CFont* pOldFont = dc.SelectObject(&fontMenu);

        CRect wndRect;
        GetWindowRect(*pWnd,wndRect);
        itemRect.OffsetRect(-wndRect.TopLeft());

        // Bugfix for wine
        if(bWine)
        {
          if(!(GetWindowLongPtr(*pWnd, GWL_STYLE)&WS_THICKFRAME) )
          {
            itemRect.OffsetRect(-GetSystemMetrics(SM_CXFIXEDFRAME),
                                -(GetSystemMetrics(SM_CYMENU)+GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYFIXEDFRAME)+1));
          }
          else
          {
            itemRect.OffsetRect(-GetSystemMetrics(SM_CXFRAME),
                                -(GetSystemMetrics(SM_CYMENU)+GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYFRAME)+1));
          }
        }

        DRAWITEMSTRUCT drwItem = {0};
        drwItem.CtlType = ODT_MENU;
        drwItem.hwndItem = HMenuToHWnd(pMenu->m_hMenu);
        drwItem.itemID = menuInfo.wID;
        drwItem.itemData = menuInfo.dwItemData;
        drwItem.rcItem = itemRect;
        drwItem.hDC = dc.m_hDC;
        drwItem.itemState = nState;
        drwItem.itemAction = ODA_DRAWENTIRE;

        ASSERT(menuInfo.dwItemData);

        CNewMenu::m_dwLastActiveItem = (DWORD)menuInfo.dwItemData;

        CPoint windowOrg;
        SetWindowOrgEx(dc.m_hDC,0,0,&windowOrg);
        SendMessage(pWnd->GetSafeHwnd(),WM_DRAWITEM,NULL,(LPARAM)&drwItem);
        SetWindowOrgEx(dc.m_hDC,windowOrg.x,windowOrg.y,NULL);

        dc.SelectObject(pOldFont);

        return TRUE;
      }
    }
  }
  return FALSE;
}

Win32Type IsShellType()
{
  OSVERSIONINFO osvi = {0};
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

  DWORD winVer=GetVersion();
  if(winVer<0x80000000)
  {/*NT */
    if(!GetVersionEx(&osvi))
    {
      ShowLastError(_T("Error from Menu: GetVersionEx NT"));
    }
    if(osvi.dwMajorVersion==4L)
    {
      return WinNT4;
    }
    else if(osvi.dwMajorVersion==5L && osvi.dwMinorVersion==0L)
    {
      return Win2000;
    }
    // thanks to John Zegers
    else if(osvi.dwMajorVersion>=5L)// && osvi.dwMinorVersion==1L)
    {
      return WinXP;
    }
    return WinNT3;
  }
  else if (LOBYTE(LOWORD(winVer))<4)
  {
    return Win32s;
  }

  if(!GetVersionEx(&osvi))
  {
    ShowLastError(_T("Error from Menu: GetVersionEx"));
  }
  if(osvi.dwMajorVersion==4L && osvi.dwMinorVersion==10L)
  {
    return Win98;
  }
  else if(osvi.dwMajorVersion==4L && osvi.dwMinorVersion==90L)
  {
    return WinME;
  }
  return Win95;
}

BOOL IsShadowEnabled()
{
  BOOL bEnabled = FALSE;
  if(SystemParametersInfo(SPI_GETDROPSHADOW,0,&bEnabled,0))
  {
    return bEnabled;
  }
  return FALSE;
}

COLORREF DarkenColorXP(COLORREF color)
{
  return RGB( MulDiv(GetRValue(color),7,10),
    MulDiv(GetGValue(color),7,10),
    MulDiv(GetBValue(color)+55,7,10));
}

// Function splits a color into its RGB components and
// transforms the color using a scale 0..255
COLORREF DarkenColor( long lScale, COLORREF lColor)
{
  long red   = MulDiv(GetRValue(lColor),(255-lScale),255);
  long green = MulDiv(GetGValue(lColor),(255-lScale),255);
  long blue  = MulDiv(GetBValue(lColor),(255-lScale),255);

  return RGB(red, green, blue);
}

COLORREF MixedColor(COLORREF colorA,COLORREF colorB)
{
  // ( 86a + 14b ) / 100
  int red   = MulDiv(86,GetRValue(colorA),100) + MulDiv(14,GetRValue(colorB),100);
  int green = MulDiv(86,GetGValue(colorA),100) + MulDiv(14,GetGValue(colorB),100);
  int blue  = MulDiv(86,GetBValue(colorA),100) + MulDiv(14,GetBValue(colorB),100);

  return RGB( min(red,0xff),min(green,0xff), min(blue,0xff));
}

COLORREF MidColor(COLORREF colorA,COLORREF colorB)
{
  // (7a + 3b)/10
  int red   = MulDiv(7,GetRValue(colorA),10) + MulDiv(3,GetRValue(colorB),10);
  int green = MulDiv(7,GetGValue(colorA),10) + MulDiv(3,GetGValue(colorB),10);
  int blue  = MulDiv(7,GetBValue(colorA),10) + MulDiv(3,GetBValue(colorB),10);

  return RGB( min(red,0xff),min(green,0xff), min(blue,0xff));
}

COLORREF GrayColor(COLORREF crColor)
{
  int Gray  = (((int)GetRValue(crColor)) + GetGValue(crColor) + GetBValue(crColor))/3;

  return RGB( Gray,Gray,Gray);
}

BOOL IsLightColor(COLORREF crColor)
{
  return (((int)GetRValue(crColor)) + GetGValue(crColor) + GetBValue(crColor))>(3*128);
}

COLORREF GetXpHighlightColor()
{
  if(bHighContrast)
  {
    return GetSysColor(COLOR_HIGHLIGHT);
  }

  if (NumScreenColors() > 256)
  {
    // May-05-2005 - Mark P. Peterson (mpp@rhinosoft.com) - Changed to use "MixedColor1()" instead when not using XP Theme mode.
    // It appears that using MidColor() in many non XP Themes cases returns the wrong color, this needs to be much more like the
    // highlight color as the user has selected in Windows.  If the highlight color is YELLOW, for example, and the COLOR_WINDOW
    // value is WHITE, using MidColor() the function returns a dark blue color making the menus too hard to read.
    if ((! IsMenuThemeActive()) && (IsLightColor(GetSysColor(COLOR_HIGHLIGHT))))
      return MixedColor(GetSysColor(COLOR_WINDOW),GetSysColor(COLOR_HIGHLIGHT));
    else
      return MidColor(GetSysColor(COLOR_WINDOW),GetSysColor(COLOR_HIGHLIGHT));
	// as released by Bruno
//    return MidColor(GetSysColor(COLOR_WINDOW),GetSysColor(COLOR_HIGHLIGHT));
  }
  return GetSysColor(COLOR_WINDOW);
}

// Function splits a color into its RGB components and
// transforms the color using a scale 0..255
COLORREF LightenColor( long lScale, COLORREF lColor)
{
  long R = MulDiv(255-GetRValue(lColor),lScale,255)+GetRValue(lColor);
  long G = MulDiv(255-GetGValue(lColor),lScale,255)+GetGValue(lColor);
  long B = MulDiv(255-GetBValue(lColor),lScale,255)+GetBValue(lColor);

  return RGB(R, G, B);
}

COLORREF BleachColor(int Add, COLORREF color)
{
  return RGB( min (GetRValue(color)+Add, 255),
              min (GetGValue(color)+Add, 255),
              min (GetBValue(color)+Add, 255));
}

COLORREF GetAlphaBlendColor(COLORREF blendColor, COLORREF pixelColor,int weighting)
{
  if(pixelColor==CLR_NONE)
  {
    return CLR_NONE;
  }
  // Algorithme for alphablending
  //dest' = ((weighting * source) + ((255-weighting) * dest)) / 256
  DWORD refR = ((weighting * GetRValue(pixelColor)) + ((255-weighting) * GetRValue(blendColor))) / 256;
  DWORD refG = ((weighting * GetGValue(pixelColor)) + ((255-weighting) * GetGValue(blendColor))) / 256;;
  DWORD refB = ((weighting * GetBValue(pixelColor)) + ((255-weighting) * GetBValue(blendColor))) / 256;;

  return RGB(refR,refG,refB);
}


void DrawGradient(CDC* pDC,CRect& Rect,
                  COLORREF StartColor,COLORREF EndColor,
                  BOOL bHorizontal,BOOL bUseSolid)
{
  int Count = pDC->GetDeviceCaps(NUMCOLORS);
  if(Count==-1)
    bUseSolid = FALSE;

  // for running under win95 and WinNt 4.0 without loading Msimg32.dll
  if(!bUseSolid && pGradientFill )
  {
    TRIVERTEX vert[2];
    GRADIENT_RECT gRect;

    vert [0].y = Rect.top;
    vert [0].x = Rect.left;

    vert [0].Red    = COLOR16(COLOR16(GetRValue(StartColor))<<8);
    vert [0].Green  = COLOR16(COLOR16(GetGValue(StartColor))<<8);
    vert [0].Blue   = COLOR16(COLOR16(GetBValue(StartColor))<<8);
    vert [0].Alpha  = 0x0000;

    vert [1].y = Rect.bottom;
    vert [1].x = Rect.right;

    vert [1].Red    = COLOR16(COLOR16(GetRValue(EndColor))<<8);
    vert [1].Green  = COLOR16(COLOR16(GetGValue(EndColor))<<8);
    vert [1].Blue   = COLOR16(COLOR16(GetBValue(EndColor))<<8);
    vert [1].Alpha  = 0x0000;

    gRect.UpperLeft  = 0;
    gRect.LowerRight = 1;

    if(bHorizontal)
    {
      pGradientFill(pDC->m_hDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_H);
    }
    else
    {
      pGradientFill(pDC->m_hDC,vert,2,&gRect,1,GRADIENT_FILL_RECT_V);
    }
  }
  else
  {
    BYTE StartRed   = GetRValue(StartColor);
    BYTE StartGreen = GetGValue(StartColor);
    BYTE StartBlue  = GetBValue(StartColor);

    BYTE EndRed    = GetRValue(EndColor);
    BYTE EndGreen  = GetGValue(EndColor);
    BYTE EndBlue   = GetBValue(EndColor);

    int n = (bHorizontal)?Rect.Width():Rect.Height();

    // only need for the rest, can be optimized
    {
      if(bUseSolid)
      {
        // We need a solid brush (can not be doted)
        pDC->FillSolidRect(Rect,pDC->GetNearestColor(EndColor));
      }
      else
      {
        // We need a brush (can be doted)
        CBrush TempBrush(EndColor);
        pDC->FillRect(Rect,&TempBrush);
      }
    }
    int dy = 2;
    n-=dy;
    for(int dn=0;dn<=n;dn+=dy)
    {
      BYTE ActRed   = (BYTE)(MulDiv(int(EndRed)  -StartRed,  dn,n)+StartRed);
      BYTE ActGreen = (BYTE)(MulDiv(int(EndGreen)-StartGreen,dn,n)+StartGreen);
      BYTE ActBlue  = (BYTE)(MulDiv(int(EndBlue) -StartBlue,  dn,n)+StartBlue);

      CRect TempRect;
      if(bHorizontal)
      {
        TempRect = CRect(CPoint(Rect.left+dn,Rect.top),CSize(dy,Rect.Height()));
      }
      else
      {
        TempRect = CRect(CPoint(Rect.left,Rect.top+dn),CSize(Rect.Width(),dy));
      }
      if(bUseSolid)
      {
        pDC->FillSolidRect(TempRect,pDC->GetNearestColor(RGB(ActRed,ActGreen,ActBlue)));
      }
      else
      {
        CBrush TempBrush(RGB(ActRed,ActGreen,ActBlue));
        pDC->FillRect(TempRect,&TempBrush);
      }
    }
  }
}


/
// CNewMenuHook important class for subclassing menus!

class CNewMenuHook
{
  friend class CNewMenuThreadHook;
public:
  class CMenuHookData
  {
  public:
    CMenuHookData(HWND hWnd,BOOL bSpecialWnd)
      : m_dwData(bSpecialWnd),m_bDrawBorder(FALSE),m_Point(0,0),
      m_hRgn((HRGN)1),m_bDoSubclass(TRUE)
      //, m_hRightShade(NULL),m_hBottomShade(NULL),m_TimerID(0)
    {
      // Safe actual menu
      SetMenu(CNewMenuHook::m_hLastMenu);
      // Reset for the next menu
      CNewMenuHook::m_hLastMenu = NULL;

      // Save actual border setting etc.
      m_dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE);
      m_dwExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);

      //if(pSetWindowTheme)pSetWindowTheme(hWnd,L" ",L" ");
    }

    ~CMenuHookData()
    {
      if(m_hRgn!=(HRGN)1)
      {
        DeleteObject(m_hRgn);
        m_hRgn = (HRGN)1;
      }
    }

    BOOL SetMenu(HMENU hMenu)
    {
      m_hMenu = hMenu;
      if(!CNewMenu::GetNewMenuBorderAllMenu() &&
        !DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(hMenu)))
      {
        m_bDoSubclass = FALSE;
      }
      else
      {
        m_bDoSubclass = TRUE;
      }
      // When I change the backgroundcolor the borderdrawing well be wrong (scrollmenu)
      //if(IsMenu(hMenu) &&
      //    CNewMenu::GetMenuDrawMode()==CNewMenu::STYLE_XP ||
      //    CNewMenu::GetMenuDrawMode()==CNewMenu::STYLE_XP_NOBORDER )
      //{
      //  MENUINFO menuInfo;
      //  ZeroMemory(&menuInfo,sizeof(menuInfo));
      //  menuInfo.cbSize = sizeof(menuInfo);
      //  menuInfo.hbrBack = g_MenuBrush;
      //  menuInfo.fMask = MIM_BACKGROUND;
      //  ::SetMenuInfo(hMenu,&menuInfo);
      //}
      return m_bDoSubclass;
    }
    LONG_PTR m_dwStyle;
    LONG_PTR m_dwExStyle;

    CPoint m_Point;
    DWORD m_dwData; //  1=Sepcial WND, 2=Styles Changed,4=VK_ESCAPE, 8=in Print

    BOOL m_bDrawBorder;
    HMENU m_hMenu;

    CBitmap m_Screen;
    HRGN m_hRgn;

    BOOL m_bDoSubclass;

    //HWND m_hRightShade;
    //HWND m_hBottomShade;
    //UINT m_TimerID;
  };

public:
  CNewMenuHook();
  ~CNewMenuHook();

public:
  static CMenuHookData* GetMenuHookData(HWND hWnd);

  static BOOL AddTheme(CMenuTheme*);
  static CMenuTheme* RemoveTheme(DWORD dwThemeId);
  static CMenuTheme* FindTheme(DWORD dwThemeId);

private:
  static LRESULT CALLBACK NewMenuHook(int code, WPARAM wParam, LPARAM lParam);
  static BOOL CheckSubclassing(HWND hWnd,BOOL bSpecialWnd);
  static LRESULT CALLBACK SubClassMenu(HWND hWnd,  UINT uMsg, WPARAM wParam,  LPARAM lParam );
  static void UnsubClassMenu(HWND hWnd);

  static BOOL SubClassMenu2(HWND hWnd,  UINT uMsg, WPARAM wParam,  LPARAM lParam, DWORD* pResult);

public:
  static HMENU m_hLastMenu;
  static DWORD m_dwMsgPos;
  static DWORD m_bSubclassFlag;

private:
  static HMODULE m_hLibrary;
  static HMODULE m_hThemeLibrary;
  static HHOOK HookOldMenuCbtFilter;

#ifdef _TRACE_MENU_LOGFILE
  static HANDLE m_hLogFile;
#endif //_TRACE_MENU_LOGFILE

  // an map of actual opened Menu and submenu
  static CTypedPtrMap<CMapPtrToPtr,HWND,CMenuHookData*> m_MenuHookData;
  // Stores list of all defined Themes
  static CTypedPtrList<CPtrList, CMenuTheme*>* m_pRegisteredThemesList;
};

/
// CNewMenuIconLock Helperclass for reference-counting !

class CNewMenuIconLock
{
  CNewMenuIcons* m_pIcons;

public:
  CNewMenuIconLock(CNewMenuIcons* pIcons):m_pIcons(pIcons)
  {
    m_pIcons->AddRef();
  }

  ~CNewMenuIconLock()
  {
    m_pIcons->Release();
  }
  operator CNewMenuIcons*(){return m_pIcons;}
};

//
// Construction/Destruction
//

IMPLEMENT_DYNAMIC(CNewMenuIcons,CObject);

CNewMenuIcons::CNewMenuIcons()
: m_lpszResourceName(NULL),
m_hInst(NULL),
m_hBitmap(NULL),
m_nColors(0),
m_crTransparent(CLR_NONE),
m_dwRefCount(0)
{
}

CNewMenuIcons::~CNewMenuIcons()
{
  if(m_lpszResourceName && !IS_INTRESOURCE(m_lpszResourceName))
  {
    delete (LPTSTR)m_lpszResourceName;
  }
}

int CNewMenuIcons::AddRef()
{
  if(this==NULL)
    return NULL;

  return ++m_dwRefCount;
}

int CNewMenuIcons::Release()
{
  if(this==NULL)
    return NULL;

  DWORD dwCount = --m_dwRefCount;
  if(m_dwRefCount==0)
  {
    if(CNewMenu::m_pSharedMenuIcons)
    {
      POSITION pos = CNewMenu::m_pSharedMenuIcons->Find(this);
      if(pos)
      {
        CNewMenu::m_pSharedMenuIcons->RemoveAt(pos);
      }
    }
    delete this;
  }
  return dwCount;
}

#if defined(_DEBUG) || defined(_AFXDLL)
// Diagnostic Support
void CNewMenuIcons::AssertValid() const
{
  CObject::AssertValid();
}

void CNewMenuIcons::Dump(CDumpContext& dc) const
{
  CObject::Dump(dc);
  dc << _T("NewMenuIcons: ") << _T("\n");
}
#endif

BOOL CNewMenuIcons::DoMatch(LPCTSTR lpszResourceName, HMODULE hInst)
{
  if(hInst==m_hInst && lpszResourceName)
  {
    if(IS_INTRESOURCE(m_lpszResourceName))
    {
      return (lpszResourceName==m_lpszResourceName);
    }

    return (_tcscmp(lpszResourceName,m_lpszResourceName)==0);
  }
  return FALSE;
}

BOOL CNewMenuIcons::DoMatch(HBITMAP hBitmap, CSize size, UINT* pID)
{
  if(pID && m_hBitmap==hBitmap)
  {
    CSize iconSize = GetIconSize();
    if(iconSize==size)
    {
      int nCount = (int)m_IDs.GetSize();
      for(int nIndex=0 ; nIndex<nCount ; nIndex++,pID++)
      {
        if( (*pID)==0 || m_IDs.GetAt(nIndex)!=(*pID) )
        {
          return FALSE;
        }
      }
      return TRUE;
    }
  }
  return FALSE;
}

BOOL CNewMenuIcons::DoMatch(WORD* pIconInfo, COLORREF crTransparent)
{
  if(m_crTransparent==crTransparent && pIconInfo!=NULL)
  {
    CNewMenuIconInfo* pInfo = (CNewMenuIconInfo*)pIconInfo;

    // Check for the same resource ID
    if( pInfo->wBitmapID && IS_INTRESOURCE(m_lpszResourceName) &&
      ((UINT)(UINT_PTR)m_lpszResourceName)==pInfo->wBitmapID)
    {
      int nCount = (int)m_IDs.GetSize();
      WORD* pID = pInfo->ids();
      for(int nIndex=0 ; nIndex<nCount ; nIndex++,pID++)
      {
        if( (*pID)==0 || m_IDs.GetAt(nIndex)!=(*pID) )
        {
          return FALSE;
        }
      }
      return TRUE;
    }
  }
  return FALSE;
}

int CNewMenuIcons::FindIndex(UINT nID)
{
  int nIndex = (int)m_IDs.GetSize();
  while(nIndex--)
  {
    if(m_IDs.GetAt(nIndex)==nID)
    {
      return nIndex*MENU_ICONS;
    }
  }
  return -1;
}

BOOL CNewMenuIcons::GetIconSize(int* cx, int* cy)
{
  return ::ImageList_GetIconSize(m_IconsList,cx,cy);
}

CSize CNewMenuIcons::GetIconSize()
{
  int cx=0;
  int cy=0;
  if(::ImageList_GetIconSize(m_IconsList,&cx,&cy))
  {
    return CSize(cx,cy);
  }
  return CSize(0,0);
}

void CNewMenuIcons::OnSysColorChange()
{
  if(m_lpszResourceName!=NULL)
  {
    int cx=16,cy=16;
    if(GetIconSize(&cx, &cy) && LoadBitmap(cx,cy,m_lpszResourceName,m_hInst))
    {
      MakeImages();
    }
  }
}

BOOL CNewMenuIcons::LoadBitmap(int nWidth, int nHeight, LPCTSTR lpszResourceName, HMODULE hInst)
{
  m_nColors = 0;
  HBITMAP hBitmap = LoadColorBitmap(lpszResourceName,hInst,&m_nColors);
  if(hBitmap!=NULL)
  {
    CBitmap bitmap;
    bitmap.Attach(hBitmap);
    if(m_IconsList.GetSafeHandle())
    {
      m_IconsList.DeleteImageList();
    }
    m_IconsList.Create(nWidth,nHeight,ILC_COLORDDB|ILC_MASK,0,10);
    m_IconsList.Add(&bitmap,m_crTransparent);

    return TRUE;
  }
  return FALSE;
}

BOOL CNewMenuIcons::LoadToolBar(HBITMAP hBitmap, CSize size, UINT* pID, COLORREF crTransparent)
{
  BOOL bResult = FALSE;
  m_nColors = 0;
  if(hBitmap!=NULL)
  {
    BITMAP myInfo = {0};
    if(GetObject(hBitmap,sizeof(myInfo),&myInfo))
    {
      m_crTransparent = crTransparent;
      if(m_IconsList.GetSafeHandle())
      {
        m_IconsList.DeleteImageList();
      }
      m_IconsList.Create(size.cx,size.cy,ILC_COLORDDB|ILC_MASK,0,10);
      // Changed by Mehdy Bohlool(zy) ( December_28_2003 )
      //
      // CImageList::Add function change the background color ( color
      // specified as transparent ) to black, and this bitmap may use
      // after call to this function, It seem that Load functions do
      // not change their source data provider ( currently hBitmap ).
      // Old Code:
      // CBitmap* pBitmap = CBitmap::FromHandle(hBitmap);
      // m_IconsList.Add(pBitmap,m_crTransparent);
      // New Code:
      {
        HBITMAP hBitmapCopy;

        hBitmapCopy = (HBITMAP) CopyImage( hBitmap, IMAGE_BITMAP, 0,0,0);

        CBitmap* pBitmap = CBitmap::FromHandle(hBitmapCopy);
        m_IconsList.Add(pBitmap,m_crTransparent);

        DeleteObject( hBitmapCopy );
      }

      while(*pID)
      {
        UINT nID = *(pID++);
        m_IDs.Add(nID);
        bResult = TRUE;
      }
      MakeImages();
    }
  }
  return bResult;
}


BOOL CNewMenuIcons::LoadToolBar(WORD* pIconInfo, COLORREF crTransparent)
{
  BOOL bResult = FALSE;
  m_crTransparent = crTransparent;
  CNewMenuIconInfo* pInfo = (CNewMenuIconInfo*)pIconInfo;

  if (LoadBitmap(pInfo->wWidth,pInfo->wHeight,MAKEINTRESOURCE(pInfo->wBitmapID)))
  {
    SetResourceName(MAKEINTRESOURCE(pInfo->wBitmapID));

    WORD* pID = pInfo->ids();
    while(*pID)
    {
      UINT nID = *(pID++);
      m_IDs.Add(nID);
      bResult = TRUE;
    }
    MakeImages();
  }
  return bResult;
}

void CNewMenuIcons::SetResourceName(LPCTSTR lpszResourceName)
{
  ASSERT_VALID(this);
  ASSERT(lpszResourceName != NULL);

  if(m_lpszResourceName && !IS_INTRESOURCE(m_lpszResourceName))
  {
    delete [](LPTSTR)m_lpszResourceName;
  }
  if( lpszResourceName && !IS_INTRESOURCE(lpszResourceName))
  {
    size_t bufSizeTchar = _tcslen(lpszResourceName)+1;
    m_lpszResourceName = new TCHAR[bufSizeTchar];
    _tcscpy_s((LPTSTR)m_lpszResourceName,bufSizeTchar,lpszResourceName);
  }
  else
  {
    m_lpszResourceName = lpszResourceName;
  }
}

BOOL CNewMenuIcons::LoadToolBar(LPCTSTR lpszResourceName, HMODULE hInst)
{
  ASSERT_VALID(this);

  SetResourceName(lpszResourceName);

  m_hInst = hInst;

  // determine location of the bitmap in resource
  if(hInst==0)
  {
    hInst = AfxFindResourceHandle(lpszResourceName, RT_TOOLBAR);
  }
  HRSRC hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR);

  if (hRsrc == NULL)
  { // Special purpose when you try to load it from a dll 30.05.2002
    if(AfxGetResourceHandle()!=hInst)
    {
      hInst = AfxGetResourceHandle();
      hRsrc = ::FindResource(hInst, lpszResourceName, RT_TOOLBAR);
    }
    if (hRsrc == NULL)
    {
      return FALSE;
    }
  }

  HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
  if (hGlobal == NULL)
  {
    return FALSE;
  }

  CToolBarData* pData = (CToolBarData*)LockResource(hGlobal);
  if (pData == NULL)
  {
    return FALSE;
  }

  BOOL bResult = FALSE;
  ASSERT(pData->wVersion == 1);

  if(LoadBitmap(pData->wWidth,pData->wHeight,lpszResourceName,hInst))
  {
    // Remove all previous ID's
    m_IDs.RemoveAll();
    for (int i = 0; i < pData->wItemCount; i++)
    {
      UINT nID = pData->items()[i];
      if (nID)
      {
        m_IDs.Add(nID);
        bResult = TRUE;
      }
    }
  }

  UnlockResource(hGlobal);
  FreeResource(hGlobal);

  MakeImages();

  return bResult;
}

int CNewMenuIcons::AddGloomIcon(HICON hIcon, int nIndex)
{
  ICONINFO iconInfo = {0};
  if(!GetIconInfo(hIcon,&iconInfo))
  {
    return -1;
  }

  CSize size = GetIconSize();
  CDC myDC;
  myDC.CreateCompatibleDC(0);

  CBitmap bmColor;
  bmColor.Attach(iconInfo.hbmColor);
  CBitmap bmMask;
  bmMask.Attach(iconInfo.hbmMask);

  CBitmap* pOldBitmap = myDC.SelectObject(&bmColor);
  COLORREF crPixel;
  for(int i=0;i<size.cx;++i)
  {
    for(int j=0;j<size.cy;++j)
    {
      crPixel = myDC.GetPixel(i,j);
      // Jan-12-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
      // added so the gloom value can be adjusted, this was 50
      myDC.SetPixel(i,j,DarkenColor(CNewMenu::GetGloomFactor(), crPixel));
    }
  }
  myDC.SelectObject(pOldBitmap);
  if(nIndex==-1)
  {
    return m_IconsList.Add(&bmColor,&bmMask);
  }

  return (m_IconsList.Replace(nIndex,&bmColor,&bmMask)) ? nIndex: -1;
}

int CNewMenuIcons::AddGrayIcon(HICON hIcon, int nIndex)
{
  ICONINFO iconInfo = {0};
  if(!GetIconInfo(hIcon,&iconInfo))
  {
    return -1;
  }

  CBitmap bmColor;
  bmColor.Attach(iconInfo.hbmColor);
  CBitmap bmMask;
  bmMask.Attach(iconInfo.hbmMask);

  COLORREF blendcolor;
  switch (CNewMenu::GetMenuDrawMode())
  {
  case CNewMenu::STYLE_XP_2003:
  case CNewMenu::STYLE_XP_2003_NOBORDER:
  case CNewMenu::STYLE_COLORFUL_NOBORDER:
  case CNewMenu::STYLE_COLORFUL:
    blendcolor = LightenColor(115,CNewMenu::GetMenuBarColor2003());
    break;

  case CNewMenu::STYLE_XP:
  case CNewMenu::STYLE_XP_NOBORDER:
    blendcolor = LightenColor(115,CNewMenu::GetMenuBarColorXP());
    break;

  default:
    blendcolor = LightenColor(115,CNewMenu::GetMenuBarColor());
    break;
  }
  MakeGrayAlphablend(&bmColor,110, blendcolor);

  if(nIndex==-1)
  {
    return m_IconsList.Add(&bmColor,&bmMask);
  }

  return (m_IconsList.Replace(nIndex,&bmColor,&bmMask)) ? nIndex: -1;
}

BOOL CNewMenuIcons::MakeImages()
{
  int nCount = m_IconsList.GetImageCount();
  if(!nCount)
  {
    return FALSE;
  }

  CSize size = GetIconSize();
  CImageList ilTemp;
  ilTemp.Attach(m_IconsList.Detach());
  m_IconsList.Create(size.cx,size.cy,ILC_COLORDDB|ILC_MASK,0,10);

  for(int nIndex=0;nIndex<nCount;nIndex++)
  {
    HICON hIcon = ilTemp.ExtractIcon(nIndex);
    m_IconsList.Add(hIcon);
    AddGloomIcon(hIcon);
    AddGrayIcon(hIcon);

    DestroyIcon(hIcon);
  }
  return TRUE;
}

//
// Construction/Destruction
//

IMPLEMENT_DYNAMIC(CNewMenuBitmaps,CNewMenuIcons);

CNewMenuBitmaps::CNewMenuBitmaps()
{
}

CNewMenuBitmaps::~CNewMenuBitmaps()
{
}

int CNewMenuBitmaps::Add(UINT nID, COLORREF crTransparent)
{
  int nIndex = (int)m_IDs.GetSize();
  while(nIndex--)
  {
    if(m_IDs.GetAt(nIndex)==nID)
    {
      return nIndex*MENU_ICONS;
    }
  }
  // Try to load the bitmap for getting dimension
  HBITMAP hBitmap = LoadColorBitmap(MAKEINTRESOURCE(nID),0);
  if(hBitmap!=NULL)
  {
    CBitmap temp;
    temp.Attach(hBitmap);

    BITMAP bitmap = {0};
    if(!temp.GetBitmap(&bitmap))
    {
      return -1;
    }

    if(m_IconsList.GetSafeHandle()==NULL)
    {
      m_IconsList.Create(bitmap.bmWidth,bitmap.bmHeight,ILC_COLORDDB|ILC_MASK,0,10);
    }
    else
    {
      CSize size = GetIconSize();
      // Wrong size?
      if(size.cx!=bitmap.bmWidth || size.cy!=bitmap.bmHeight)
      {
        return -1;
      }
    }
    m_TranspColors.Add(crTransparent);
    m_IDs.Add(nID);

    nIndex = m_IconsList.Add(&temp,crTransparent);
    HICON hIcon = m_IconsList.ExtractIcon(nIndex);
    AddGloomIcon(hIcon);
    AddGrayIcon(hIcon);
    DestroyIcon(hIcon);

    //SetBlendImage();
    return nIndex;
  }
  return -1;
}

void CNewMenuBitmaps::OnSysColorChange()
{
  int nCount = (int)m_IDs.GetSize();
  for(int nIndex=0;nIndex<nCount;nIndex+=MENU_ICONS)
  {
    //Todo reload icons
    HICON hIcon = m_IconsList.ExtractIcon(nIndex);
    AddGloomIcon(hIcon,nIndex+1);
    AddGrayIcon(hIcon,nIndex+2);

    DestroyIcon(hIcon);
  }
}

int CNewMenuBitmaps::Add(HICON hIcon, UINT nID)
{
  ICONINFO iconInfo = {0};
  if(!GetIconInfo(hIcon,&iconInfo))
  {
    return -1;
  }

  CBitmap temp;
  temp.Attach(iconInfo.hbmColor);
  ::DeleteObject(iconInfo.hbmMask);

  BITMAP bitmap = {0};
  if(!temp.GetBitmap(&bitmap))
  {
    return -1;
  }

  if(m_IconsList.GetSafeHandle()==NULL)
  {
    m_IconsList.Create(bitmap.bmWidth,bitmap.bmHeight,ILC_COLORDDB|ILC_MASK,0,10);
  }
  else
  {
    CSize size = GetIconSize();
    // Wrong size?
    if(size.cx!=bitmap.bmWidth || size.cy!=bitmap.bmHeight)
    {
      return -1;
    }
  }
  if(nID)
  {
    int nIndex = (int)m_IDs.GetSize();
    while(nIndex--)
    {
      if(m_IDs.GetAt(nIndex)==nID)
      {
        // We found the index also replace the icon
        nIndex = nIndex*MENU_ICONS;
        m_IconsList.Replace(nIndex,hIcon);
        AddGloomIcon(hIcon,nIndex+1);
        AddGrayIcon(hIcon,nIndex+2);
        return nIndex;
      }
    }
  }
  COLORREF clr = CLR_NONE;
  m_TranspColors.Add(clr);
  m_IDs.Add(nID);
  int nIndex = m_IconsList.Add(hIcon);
  AddGloomIcon(hIcon);
  AddGrayIcon(hIcon);

  return nIndex;
}

int CNewMenuBitmaps::Add(CBitmap* pBitmap, COLORREF crTransparent)
{
  ASSERT(pBitmap);

  BITMAP bitmap = {0};
  if(!pBitmap->GetBitmap(&bitmap))
  {
    return -1;
  }

  if(m_IconsList.GetSafeHandle()==NULL)
  {
    m_IconsList.Create(bitmap.bmWidth,bitmap.bmHeight,ILC_COLORDDB|ILC_MASK,0,10);
  }
  else
  {
    CSize size = GetIconSize();
    // Wrong size?
    if(size.cx!=bitmap.bmWidth || size.cy!=bitmap.bmHeight)
    {
      return -1;
    }
  }
  UINT nID = 0;
  m_TranspColors.Add(crTransparent);
  m_IDs.Add(nID);
  int nIndex = m_IconsList.Add(pBitmap,crTransparent);
  HICON hIcon = m_IconsList.ExtractIcon(nIndex);
  AddGloomIcon(hIcon);
  AddGrayIcon(hIcon);
  DestroyIcon(hIcon);
  //SetBlendImage();
  return nIndex;
}

//
// Construction/Destruction
//

IMPLEMENT_DYNAMIC(CNewMenuItemData,CObject);

CNewMenuItemData::CNewMenuItemData()
: m_nTitleFlags(0),
m_nFlags(0),
m_nID(0),
m_nSyncFlag(0),
m_pData(NULL),
m_pMenuIcon(NULL),
m_nMenuIconOffset(-1)
{
}

CNewMenuItemData::~CNewMenuItemData()
{
  // it's a safe release. Do not care for NULL pointers.
  m_pMenuIcon->Release();
}

// Get the string, along with (manufactured) accelerator text.
CString CNewMenuItemData::GetString (HACCEL hAccel)
{
  if (m_nFlags & MF_POPUP )
  { // No accelerators if we're the title of a popup menu. Otherwise we get spurious accels
    hAccel = NULL;
  }

  CString s = m_szMenuText;
  int iTabIndex = s.Find ('\t');
  if (!hAccel || iTabIndex>= 0) // Got one hard coded in, or we're a popup menu
  {
    if (!hAccel && iTabIndex>= 0)
    {
      s = s.Left (iTabIndex);
    }
    return s;
  }

  // OK, we've got to go hunting through the default accelerator.
  if (hAccel == INVALID_HANDLE_VALUE)
  {
    hAccel = NULL;
    CFrameWnd *pFrame = DYNAMIC_DOWNCAST(CFrameWnd, AfxGetMainWnd ());
    // No frame. Maybe we're part of a dialog app. etc.
    if (pFrame)
    {
      hAccel = pFrame->GetDefaultAccelerator ();
    }
  }
  // No default found, or we've turned accelerators off.
  if (hAccel == NULL)
  {
    return s;
  }
  // Get the number of entries
  int nEntries = ::CopyAcceleratorTable (hAccel, NULL, 0);
  if (nEntries)
  {
    ACCEL *pAccel = (ACCEL *)_alloca(nEntries*sizeof(ACCEL));
    if (::CopyAcceleratorTable (hAccel, pAccel, nEntries))
    {
      CString sAccel;
      for (int n = 0; n < nEntries; n++)
      {
        if (pAccel [n].cmd != (WORD) m_nID)
        {
          continue;
        }
        if (!sAccel.IsEmpty ())
        {
          sAccel += _T(", ");
        }
        // Translate the accelerator into more useful code.
        if (pAccel [n].fVirt & FALT)         sAccel += _T("Alt+");
        if (pAccel [n].fVirt & FCONTROL)     sAccel += _T("Ctrl+");
        if (pAccel [n].fVirt & FSHIFT)       sAccel += _T("Shift+");
        if (pAccel [n].fVirt & FVIRTKEY)
        {
          TCHAR keyname[64];
          UINT vkey = MapVirtualKey(pAccel [n].key, 0)<<16;
          GetKeyNameText(vkey, keyname, sizeof(keyname));
          sAccel += keyname;
        }
        else
        {
          sAccel += (TCHAR)pAccel [n].key;
        }
      }
      if (!sAccel.IsEmpty ()) // We found one!
      {
        s += '\t';
        s += sAccel;
      }
    }
  }
  return s;
}

void CNewMenuItemData::SetString(LPCTSTR szMenuText)
{
  m_szMenuText = szMenuText;
}

#if defined(_DEBUG) || defined(_AFXDLL)
// Diagnostic Support
void CNewMenuItemData::AssertValid() const
{
  CObject::AssertValid();
}

void CNewMenuItemData::Dump(CDumpContext& dc) const
{
  CObject::Dump(dc);
  dc << _T("MenuItem: ") << m_szMenuText << _T("\n");
}

#endif

//
// Construction/Destruction
//

IMPLEMENT_DYNAMIC(CNewMenuItemDataTitle,CNewMenuItemData);

CNewMenuItemDataTitle::CNewMenuItemDataTitle()
: m_clrTitle(CLR_DEFAULT),
m_clrLeft(CLR_DEFAULT),
m_clrRight(CLR_DEFAULT)
{
}

CNewMenuItemDataTitle::~CNewMenuItemDataTitle()
{
}


//
// Construction/Destruction
//

IMPLEMENT_DYNAMIC(CNewMenu,CMenu);

// actual selectet menu-draw mode
CMenuTheme* CNewMenu::m_pActMenuDrawing = NULL;
CTypedPtrList<CPtrList, CNewMenuIcons*>* CNewMenu::m_pSharedMenuIcons = NULL;

// Gloabal logfont for all menutitles
LOGFONT CNewMenu::m_MenuTitleFont = {16, 0, 0, 0, FW_BOLD,
0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH,_T("Arial")};


void CNewMenu::SetMenuTitleFont(CFont* pFont)
{
  ASSERT(pFont);
  pFont->GetLogFont(&m_MenuTitleFont);
}

void CNewMenu::SetMenuTitleFont(LOGFONT* pLogFont)
{
  ASSERT(pLogFont);
  m_MenuTitleFont = *pLogFont;
}

LOGFONT CNewMenu::GetMenuTitleFont()
{
  return m_MenuTitleFont;
}

DWORD CNewMenu::m_dwLastActiveItem = NULL;

// how the menu's are drawn in winXP
BOOL CNewMenu::m_bEnableXpBlending = TRUE;
BOOL CNewMenu::m_bNewMenuBorderAllMenu = TRUE;
BOOL CNewMenu::m_bSelectDisable = TRUE;
// Jan-12-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
// added so the gloom value can be adjusted
// 50 is the default, may be too high, 20 is subtle
int CNewMenu::m_nGloomFactor = 50;

const Win32Type g_Shell = IsShellType();
BOOL bRemoteSession = FALSE;

// one instance of the hook for menu-subclassing
static CNewMenuHook MyNewMenuHookInstance;

CNewMenu::CNewMenu(HMENU hParent)
: m_hTempOwner(NULL),
m_hParentMenu(hParent),
m_bIsPopupMenu(TRUE),
m_dwOpenMenu(NULL),
m_LastActiveMenuRect(0,0,0,0),
m_pData(NULL),
m_hAccelToDraw((HACCEL)INVALID_HANDLE_VALUE)
{
  // O.S. - no dynamic icons by default
  m_bDynIcons = FALSE;
  // Icon sizes default to 16 x 16
  m_iconX = 16;
  m_iconY = 15;
  m_selectcheck = -1;
  m_unselectcheck = -1;
  m_checkmaps=NULL;
  m_checkmapsshare=FALSE;

  // set the color used for the transparent background in all bitmaps
  m_bitmapBackground = CLR_DEFAULT;
}

CNewMenu::~CNewMenu()
{
  DestroyMenu();
}

COLORREF CNewMenu::GetMenuColor(HMENU hMenu)
{
  if(hMenu!=NULL)
  {
    MENUINFO menuInfo={0};
    menuInfo.cbSize = sizeof(menuInfo);
    menuInfo.fMask = MIM_BACKGROUND;

    if(::GetMenuInfo(hMenu,&menuInfo) && menuInfo.hbrBack)
    {
      LOGBRUSH logBrush;
      if(GetObject(menuInfo.hbrBack,sizeof(LOGBRUSH),&logBrush))
      {
        return logBrush.lbColor;
      }
    }
  }

  if(IsShellType()==WinXP)
  {
    BOOL bFlatMenu = FALSE;
    // theme ist not checket, that must be so
    if( (SystemParametersInfo(SPI_GETFLATMENU,0,&bFlatMenu,0) && bFlatMenu==TRUE) )
    {
      return GetSysColor(COLOR_MENUBAR);
    }
  }
  return GetSysColor(COLOR_MENU);
}

COLORREF CNewMenu::GetMenuBarColorXP()
{
  // Win95 or WinNT do not support to change the menubarcolor
  if(IsShellType()==Win95 || IsShellType()==WinNT4)
  {
    return GetSysColor(COLOR_MENU);
  }
  return GetSysColor(COLOR_3DFACE);
}


HRESULT localGetCurrentThemeName( LPWSTR pszThemeFileName, int dwMaxNameChars,
                                  LPWSTR pszColorBuff,     int cchMaxColorChars,
                                  LPWSTR pszSizeBuff,      int cchMaxSizeChars)
{
  static CNewLoadLib menuInfo(_T("UxTheme.dll"),"GetCurrentThemeName");
  if(menuInfo.m_pProg)
  {
   typedef HRESULT (WINAPI* FktGetCurrentThemeName)(LPWSTR pszThemeFileName,int dwMaxNameChars, LPWSTR pszColorBuff, int cchMaxColorChars, LPWSTR pszSizeBuff, int cchMaxSizeChars);
    return ((FktGetCurrentThemeName)menuInfo.m_pProg)(pszThemeFileName, dwMaxNameChars, pszColorBuff, cchMaxColorChars, pszSizeBuff, cchMaxSizeChars);
  }
  return NULL;
}

HANDLE localGetWindowTheme(HWND hWnd)
{
  static CNewLoadLib menuInfo(_T("UxTheme.dll"),"GetWindowTheme");
  if(menuInfo.m_pProg)
  {
    typedef HANDLE (WINAPI* FktGetWindowTheme)(HWND hWnd);
    return ((FktGetWindowTheme)menuInfo.m_pProg)(hWnd);
  }
  return NULL;
}

HANDLE localOpenThemeData( HWND hWnd, LPCWSTR pszClassList)
{
  static CNewLoadLib menuInfo(_T("UxTheme.dll"),"OpenThemeData");
  if(menuInfo.m_pProg)
  {
    typedef HANDLE (WINAPI* FktOpenThemeData)(HWND hWnd, LPCWSTR pszClassList);
    return ((FktOpenThemeData)menuInfo.m_pProg)(hWnd,pszClassList);
  }
  return NULL;
}

HRESULT localCloseThemeData(HANDLE hTheme)
{
  static CNewLoadLib menuInfo(_T("UxTheme.dll"),"CloseThemeData");
  if(menuInfo.m_pProg)
  {
    typedef HRESULT (WINAPI* FktCloseThemeData)(HANDLE hTheme);
    return ((FktCloseThemeData)menuInfo.m_pProg)(hTheme);
  }
  return NULL;
}

HRESULT localGetThemeColor(HANDLE hTheme,
    int iPartId,
    int iStateId,
    int iColorId,
    COLORREF *pColor)
{
  static CNewLoadLib menuInfo(_T("UxTheme.dll"),"GetThemeColor");
  if(menuInfo.m_pProg)
  {
    typedef HRESULT (WINAPI* FktGetThemeColor)(HANDLE hTheme,int iPartId,int iStateId,int iColorId, COLORREF *pColor);
    return ((FktGetThemeColor)menuInfo.m_pProg)(hTheme, iPartId, iStateId, iColorId, pColor);
  }
  return S_FALSE;
}



COLORREF CNewMenu::GetMenuBarColor2003()
{
  COLORREF colorLeft,colorRight;
  GetMenuBarColor2003(colorLeft,colorRight);
  return colorLeft;
}

void CNewMenu::GetMenuBarColor2003(COLORREF& color1, COLORREF& color2, BOOL bBackgroundColor /* = TRUE */)
{
  // Win95 or WinNT do not support to change the menubarcolor
  if(IsShellType()==Win95 || IsShellType()==WinNT4)
  {
    color1 = color2 = GetSysColor(COLOR_MENU);
    return;
  }

  if(GetMenuDrawMode()==STYLE_COLORFUL_NOBORDER ||  GetMenuDrawMode()==STYLE_COLORFUL)
  {
    COLORREF colorWindow = DarkenColor(10,GetSysColor(COLOR_WINDOW));
    COLORREF colorCaption = GetSysColor(COLOR_ACTIVECAPTION);

    CClientDC myDC(NULL);
    COLORREF nearColor = myDC.GetNearestColor(MidColor(colorWindow,colorCaption));

    // some colorscheme corrections (Andreas Scher)
    if (nearColor == 15779244) //standartblau
    { //entspricht (haar-)genau office 2003
      nearColor = RGB(163,194,245);
    }
    else if (nearColor == 15132390) //standartsilber
    {
      nearColor = RGB(215,215,229);
    }
    else if (nearColor == 13425878) //olivgr
    {
      nearColor = RGB(218,218,170);
    }

    color1 = nearColor;
    color2 = LightenColor(110,color1);
    return;
  }
  else
  {
    if (IsMenuThemeActive())
    {
      COLORREF colorWindow = DarkenColor(10,GetSysColor(COLOR_WINDOW));
      COLORREF colorCaption = GetSysColor(COLOR_ACTIVECAPTION);

      //CWnd* pWnd = AfxGetMainWnd();
      //if (pWnd)
      {
        //HANDLE hTheme = localOpenThemeData(pWnd->GetSafeHwnd(),L"Window");
        // get the them from desktop window
        HANDLE hTheme = localOpenThemeData(NULL,L"Window");
        if(hTheme)
        {
          COLORREF color = CLR_NONE;
          // defined in Tmschema.h
          //    TM_PART(1, WP, CAPTION)
          //    TM_STATE(1, CS, ACTIVE)
          //    TM_PROP(204, TMT, COLOR,     COLOR)
          //for (int iColorID=0;iColorID<6000;iColorID++)
          //{
          //  if(localGetThemeColor(hTheme,1,1,iColorID,&color)==S_OK)
          //  {
          //    colorCaption = color;
          //  }
          //}

          // TM_PROP(3804, TMT, EDGELIGHTCOLOR,     COLOR)     // edge color
          // TM_PROP(3821, TMT, FILLCOLORHINT, COLOR)          // hint about fill color used (for custom controls)
          if(localGetThemeColor(hTheme,1,1,3821,&color)==S_OK && (color!=1))
          {
            colorCaption = color;
          }
          //TM_PROP(3805, TMT, EDGEHIGHLIGHTCOLOR, COLOR)     // edge color
          if(localGetThemeColor(hTheme,1,1,3805,&color)==S_OK && (color!=1))
          {
            colorWindow = color;
          }
          localCloseThemeData(hTheme);

          // left side Menubar
          switch(colorCaption)
          {
          case 0x00e55400: // blue
            color1 = RGB(163,194,245);
            break;

          case 0x00bea3a4:  // silver
            color1 = RGB(215,215,229);
            break;

          case 0x0086b8aa:  //olive green
            color1 = RGB(218,218,170);
            break;

          default:
            {
              CClientDC myDC(NULL);
              color1 = myDC.GetNearestColor(MidColor(colorWindow,colorCaption));
            }
            break;
          }

          if (bBackgroundColor)
          {
            color2 = LightenColor(110,color1);
          }
          else
          {
            color2 = LightenColor(200,color1);
            color1 = DarkenColor(20,color1);
          }
          return;
        }
      }

      CClientDC myDC(NULL);
      COLORREF nearColor = myDC.GetNearestColor(MidColor(colorWindow,colorCaption));

      // some colorscheme corrections (Andreas Sch鋜er)
      if (nearColor == 15779244) //standartblau
      { //entspricht (haar-)genau office 2003
        color1 = RGB(163,194,245);
      }
      else if (nearColor == 15132390) //standartsilber
      {
        color1 = RGB(215,215,229);
      }
      else if (nearColor == 13425878) //olivgr黱
      {
        color1 = RGB(218,218,170);
      }
      else
      {
        color1 = nearColor;
      }

      if (bBackgroundColor)
      {
        color2 = LightenColor(100,color1);
      }
      else
      {
        color2 = LightenColor(200,color1);
        color1 = DarkenColor(20,color1);
      }
    }
    else
    {
      //color1 = ::GetSysColor(COLOR_MENU);
      color1 = ::GetSysColor(COLOR_BTNFACE); // same as COLOR_3DFACE
      color2 = ::GetSysColor(COLOR_WINDOW);
      color2 =  GetAlphaBlendColor(color1,color2,220);
    }
  }
}

COLORREF CNewMenu::GetMenuBarColor(HMENU hMenu)
{
  if(hMenu!=NULL)
  {
    MENUINFO menuInfo = {0};
    menuInfo.cbSize = sizeof(menuInfo);
    menuInfo.fMask = MIM_BACKGROUND;

    if(::GetMenuInfo(hMenu,&menuInfo) && menuInfo.hbrBack)
    {
      LOGBRUSH logBrush;
      if(GetObject(menuInfo.hbrBack,sizeof(LOGBRUSH),&logBrush))
      {
        return logBrush.lbColor;
      }
    }
  }
  if(IsShellType()==WinXP)
  {
    BOOL bFlatMenu = FALSE;
    if((SystemParametersInfo(SPI_GETFLATMENU,0,&bFlatMenu,0) && bFlatMenu==TRUE) ||
      (IsMenuThemeActive()))
    {
      return GetSysColor(COLOR_MENUBAR);
    }
  }
  // May-05-2005 - Mark P. Peterson (mpp@rhinosoft.com) - Changed to use the menubar color, I could not find why COLOR_MENU should
  // be used when not flat and no XP Theme is active.  The problem is that using this shows the wrong color in any other theme, when
  // the background color of menus is something other than the same color of the menu bar.
  return (GetMenuBarColorXP());
//  return GetSysColor(COLOR_MENU);
}

void CNewMenu::SetLastMenuRect(HDC hDC, LPRECT pRect)
{
  if(!m_bIsPopupMenu)
  {
    HWND hWnd = WindowFromDC(hDC);
    if(hWnd && pRect)
    {
      CRect Temp;
      GetWindowRect(hWnd,Temp);
      m_LastActiveMenuRect = *pRect;
      m_LastActiveMenuRect.OffsetRect(Temp.TopLeft());
#ifdef _TRACE_MENU_
      AfxTrace(_T("ActiveRect: (%ld,%ld,%ld,%ld)\n"),m_LastActiveMenuRect.left,m_LastActiveMenuRect.top,m_LastActiveMenuRect.right,m_LastActiveMenuRect.bottom);
#endif
    }
  }
}

void CNewMenu::SetLastMenuRect(LPRECT pRect)
{
  ASSERT(pRect);
  m_LastActiveMenuRect = *pRect;
}

BOOL CNewMenu::IsNewShell()
{
  return (g_Shell>=Win95);
}

BOOL CNewMenu::OnMeasureItem(const MSG* pMsg)
{
  if(pMsg->message==WM_MEASUREITEM)
  {
    LPMEASUREITEMSTRUCT lpMIS = (LPMEASUREITEMSTRUCT)pMsg->lParam;
    if(lpMIS->CtlType==ODT_MENU)
    {
      CMenu* pMenu=NULL;
      if(::IsMenu(UIntToHMenu(lpMIS->itemID)) )
      {
        pMenu = CMenu::FromHandlePermanent(UIntToHMenu(lpMIS->itemID) );
      }
      else
      {
        _AFX_THREAD_STATE* pThreadState = AfxGetThreadState ();
        if (pThreadState->m_hTrackingWindow == pMsg->hwnd)
        {
          // start from popup
          pMenu = FindPopupMenuFromIDData(pThreadState->m_hTrackingMenu,lpMIS->itemID,lpMIS->itemData);
        }
        if(pMenu==NULL)
        {
          // start from menubar
          pMenu = FindPopupMenuFromIDData(::GetMenu(pMsg->hwnd),lpMIS->itemID,lpMIS->itemData);
          if(pMenu==NULL)
          {
            // finaly start from system menu.
            pMenu = FindPopupMenuFromIDData(::GetSystemMenu(pMsg->hwnd,FALSE),lpMIS->itemID,lpMIS->itemData);

#ifdef USE_NEW_MENU_BAR
            if(!pMenu)
            { // Support for new menubar
              static UINT WM_GETMENU = ::RegisterWindowMessage(_T("CNewMenuBar::WM_GETMENU"));
              pMenu = FindPopupMenuFromIDData((HMENU)::SendMessage(pMsg->hwnd,WM_GETMENU,0,0),lpMIS->itemID,lpMIS->itemData);
            }
#endif
          }
        }
      }
      if(pMenu!=NULL)
      {
#ifdef _TRACE_MENU_
        UINT oldWidth = lpMIS->itemWidth;
#endif //_TRACE_MENU_

        pMenu->MeasureItem(lpMIS);

#ifdef _TRACE_MENU_
        AfxTrace(_T("NewMenu MeasureItem: ID:0x08%X, oW:0x%X, W:0x%X, H:0x%X\n"),lpMIS->itemID,oldWidth,lpMIS->itemWidth,lpMIS->itemHeight);
#endif //_TRACE_MENU_
        return TRUE;
      }
    }
  }
  return FALSE;
}

CMenu* CNewMenu::FindPopupMenuFromID(HMENU hMenu, UINT nID)
{
  // check for a valid menu-handle
  if ( ::IsMenu(hMenu))
  {
    CMenu *pMenu = CMenu::FromHandlePermanent(hMenu);
    if(pMenu)
    {
      return FindPopupMenuFromID(pMenu,nID);
    }
  }
  return NULL;
}

CMenu* CNewMenu::FindPopupMenuFromIDData(HMENU hMenu, UINT nID, ULONG_PTR pData)
{
  // check for a valid menu-handle
  if ( ::IsMenu(hMenu))
  {
    CMenu *pMenu = CMenu::FromHandlePermanent(hMenu);
    if(pMenu)
    {
      return FindPopupMenuFromIDData(pMenu,nID,pData);
    }
  }
  return NULL;
}

CMenu* CNewMenu::FindPopupMenuFromIDData(CMenu* pMenu, UINT nID, ULONG_PTR pData)
{
  if(!pMenu || !IsMenu(pMenu->m_hMenu))
  {
    return NULL;
  }
  ASSERT_VALID(pMenu);
  // walk through all items, looking for ID match
  UINT nItems = pMenu->GetMenuItemCount();
  for (int iItem = 0; iItem < (int)nItems; iItem++)
  {
    CMenu* pPopup = pMenu->GetSubMenu(iItem);
    if (pPopup!=NULL)
    {
      // recurse to child popup
      pPopup = FindPopupMenuFromIDData(pPopup, nID, pData);
      // check popups on this popup
      if (pPopup != NULL)
      {
        return pPopup;
      }
    }
    else if (pMenu->GetMenuItemID(iItem) == nID)
    {
      MENUITEMINFO MenuItemInfo = {0};
      MenuItemInfo.cbSize = sizeof(MenuItemInfo);
      MenuItemInfo.fMask = MIIM_DATA;

      if(pMenu->GetMenuItemInfo(iItem,&MenuItemInfo,TRUE))
      {
        if(MenuItemInfo.dwItemData==pData)
        {
          // it is a normal item inside our popup
          return pMenu;
        }
      }
    }
  }
  // not found
  return NULL;
}

CMenu* CNewMenu::FindPopupMenuFromID(CMenu* pMenu, UINT nID)
{
  if(!pMenu || !IsMenu(pMenu->m_hMenu))
  {
    return NULL;
  }
  ASSERT_VALID(pMenu);
  // walk through all items, looking for ID match
  UINT nItems = pMenu->GetMenuItemCount();
  for (int iItem = 0; iItem < (int)nItems; iItem++)
  {
    CMenu* pPopup = pMenu->GetSubMenu(iItem);
    if (pPopup != NULL)
    {
      // recurse to child popup
      pPopup = FindPopupMenuFromID(pPopup, nID);
      // check popups on this popup
      if (pPopup != NULL)
      {
        return pPopup;
      }
    }
    else if (pMenu->GetMenuItemID(iItem) == nID)
    {
      // it is a normal item inside our popup
      return pMenu;
    }
  }
  // not found
  return NULL;
}

BOOL CNewMenu::DestroyMenu()
{
  // Destroy Sub menus:
  int nIndex = (int)m_SubMenus.GetSize();
  while(nIndex--)
  {
    // Destroy only if we createt it!!!!!
    CNewMenu* pMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(m_SubMenus[nIndex]));
    if(pMenu)
    {
      delete pMenu;
    }
  }
  m_SubMenus.RemoveAll();

  // Destroy menu data
  nIndex = (int)m_MenuItemList.GetSize();
  while(nIndex--)
  {
    delete(m_MenuItemList[nIndex]);
  }
  m_MenuItemList.RemoveAll();

  if(m_checkmaps&&!m_checkmapsshare)
  {
    delete m_checkmaps;
    m_checkmaps=NULL;
  }
  // Call base-class implementation last:
  return(CMenu::DestroyMenu());
};

UINT CNewMenu::GetMenuDrawMode()
{
  ASSERT(m_pActMenuDrawing);
  return m_pActMenuDrawing->m_dwThemeId;
}

UINT CNewMenu::SetMenuDrawMode(UINT mode)
{
#ifdef _TRACE_MENU_
  if(mode&1)
  {
    AfxTrace(_T("\nDraw menu no border\n"));
  }
  else
  {
    AfxTrace(_T("\nDraw menu with border\n"));
  }
#endif //  _TRACE_MENU_

  // under wine we disable flat menu and shade drawing
  if(bWine)
  {
    switch(mode)
    {
    case STYLE_ORIGINAL:
      mode = STYLE_ORIGINAL_NOBORDER;
      break;

    case STYLE_XP:
      mode = STYLE_XP_NOBORDER;
      break;

    case STYLE_SPECIAL:
      mode = STYLE_SPECIAL_NOBORDER;
      break;

    case STYLE_ICY:
      mode = STYLE_ICY_NOBORDER;
      break;

    case STYLE_XP_2003:
      mode = STYLE_XP_2003_NOBORDER;
      break;

    case STYLE_COLORFUL:
      mode = STYLE_COLORFUL_NOBORDER;
      break;
    }
  }

  UINT nOldMode = (UINT)STYLE_UNDEFINED;
  CMenuTheme* pTheme = CNewMenuHook::FindTheme(mode);
  if(pTheme)
  {
    if(m_pActMenuDrawing)
    {
      nOldMode = m_pActMenuDrawing->m_dwThemeId;
    }

    m_pActMenuDrawing = pTheme;
  }
  return nOldMode;
}

HMENU CNewMenu::GetParent()
{
  return m_hParentMenu;
}

BOOL CNewMenu::IsPopup()
{
  return m_bIsPopupMenu;
}

BOOL CNewMenu::SetPopup(BOOL bIsPopup)
{
  BOOL bOldFlag = m_bIsPopupMenu;
  m_bIsPopupMenu = bIsPopup;
  return bOldFlag;
}

BOOL CNewMenu::SetSelectDisableMode(BOOL mode)
{
  BOOL bOldMode = m_bSelectDisable;
  m_bSelectDisable=mode;
  return bOldMode;
}

BOOL CNewMenu::GetSelectDisableMode()
{
  return m_bSelectDisable;
}

BOOL CNewMenu::SetXpBlending(BOOL bEnable)
{
  BOOL bOldMode = m_bEnableXpBlending;
  m_bEnableXpBlending = bEnable;
  return bOldMode;
}

BOOL CNewMenu::GetXpBlending()
{
  return m_bEnableXpBlending;
}


// Jan-12-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
// added SetGloomFactor() and GetGloomFactor() so that the glooming can be done in a more or less subtle way
int CNewMenu::SetGloomFactor(int nGloomFactor)
{
  int nOldGloomFactor = m_nGloomFactor;

  // set the new gloom factor
  m_nGloomFactor = nGloomFactor;

  // return the previous gloom factor
  return (nOldGloomFactor);
} // SetGloomFactor


int CNewMenu::GetGloomFactor()
{
  // return the current gloom factor
  return (m_nGloomFactor);
} // GetGloomFactor


// Function to set how default menu border were drawn
//(enable=TRUE means that all menu in the application has the same border)
BOOL CNewMenu::SetNewMenuBorderAllMenu(BOOL bEnable /* =TRUE*/)
{
  BOOL bOldMode = m_bNewMenuBorderAllMenu;
  m_bNewMenuBorderAllMenu = bEnable;
  return bOldMode;
}

BOOL CNewMenu::GetNewMenuBorderAllMenu()
{
  return m_bNewMenuBorderAllMenu;
}

void CNewMenu::OnSysColorChange()
{
  static DWORD dwLastTicks = 0;
  DWORD dwAktTicks = GetTickCount();

  // Last Update 2 sec
  if((dwAktTicks-dwLastTicks)>2000)
  {
    dwLastTicks = dwAktTicks;
    if(m_pSharedMenuIcons)
    {
      POSITION pos = m_pSharedMenuIcons->GetHeadPosition();
      while(pos)
      {
        CNewMenuIcons* pMenuIcons = m_pSharedMenuIcons->GetNext(pos);
        pMenuIcons->OnSysColorChange();
      }
    }
  }
}

void CNewMenu::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
{
  ASSERT(m_pActMenuDrawing);

  BOOL bIsMenuBar = IsMenuBar(UIntToHMenu(lpMIS->itemID));
  if(!bIsMenuBar && m_hParentMenu && !FindMenuItem(lpMIS->itemID)) //::IsMenu(UIntToHMenu(lpMIS->itemID)) )
  {
    CNewMenu* pMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(m_hParentMenu));
    if(pMenu)
    {
      ((*pMenu).*m_pActMenuDrawing->m_pMeasureItem)(lpMIS,bIsMenuBar);
      return;
    }
  }
  ((*this).*m_pActMenuDrawing->m_pMeasureItem)(lpMIS,bIsMenuBar);
}

void CNewMenu::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
  ASSERT(m_pActMenuDrawing);

  BOOL bIsMenuBar = m_hParentMenu ? FALSE: ((m_bIsPopupMenu)?FALSE:TRUE);

  if(bIsMenuBar && m_dwLastActiveItem==lpDIS->itemData)
  {
    if(! (lpDIS->itemState&ODS_HOTLIGHT) )
    {
      // Mark for redraw helper for win 98
      m_dwLastActiveItem = NULL;
    }
  }

  (this->*m_pActMenuDrawing->m_pDrawItem)(lpDIS,bIsMenuBar);
}

// Erase the Background of the menu
BOOL CNewMenu::EraseBkgnd(HWND hWnd, HDC hDC)
{
  CDC* pDC = CDC::FromHandle (hDC);
  CRect Rect;
  //  Get the size of the menu...
  GetClientRect(hWnd, Rect );
  pDC->FillSolidRect (Rect,GetMenuColor());

  return TRUE;
}

void CNewMenu::DrawTitle(LPDRAWITEMSTRUCT lpDIS,BOOL bIsMenuBar)
{
  ASSERT(m_pActMenuDrawing);
  (this->*m_pActMenuDrawing->m_pDrawTitle)(lpDIS,bIsMenuBar);
}

void CNewMenu::DrawMenuTitle(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar)
{
  UNREFERENCED_PARAMETER(bIsMenuBar);

  CDC* pDC = CDC::FromHandle(lpDIS->hDC);

  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpDIS->itemData);
  ASSERT(pMenuData);

  COLORREF colorWindow = GetSysColor(COLOR_WINDOW);
  COLORREF colorMenuBar = GetMenuColor();

  COLORREF colorLeft = MixedColor(colorWindow,colorMenuBar);
  COLORREF colorRight = ::GetSysColor(COLOR_ACTIVECAPTION);
  COLORREF colorText = ::GetSysColor(COLOR_CAPTIONTEXT);

  CSize iconSize(0,0);
  if(pMenuData->m_nMenuIconOffset!=(-1) && pMenuData->m_pMenuIcon)
  {
    iconSize = pMenuData->m_pMenuIcon->GetIconSize();
    if(iconSize!=CSize(0,0))
    {
      iconSize += CSize(4,4);
    }
  }

  CNewMenuItemDataTitle* pItem = DYNAMIC_DOWNCAST(CNewMenuItemDataTitle,pMenuData);
  if(pItem)
  {
    if(pItem->m_clrRight!=CLR_DEFAULT)
    {
      colorRight = pItem->m_clrRight;
    }
    if(pItem->m_clrLeft!=CLR_DEFAULT)
    {
      colorLeft = pItem->m_clrLeft;
    }
    if(pItem->m_clrTitle!=CLR_DEFAULT)
    {
      colorText = pItem->m_clrTitle;
    }
  }

  CRect rcClipBox;

  HWND hWnd = ::WindowFromDC(lpDIS->hDC);
  // try to get the real size of the client window
  if(hWnd==NULL || !GetClientRect(hWnd,rcClipBox) )
  {
    // when we have menu animation the DC is a memory DC
    pDC->GetClipBox(rcClipBox);
  }

  // draw the title bar
  CRect rect = lpDIS->rcItem;
  CPoint TextPoint;

  CFont Font;
  LOGFONT MyFont = m_MenuTitleFont;
  if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
  {
    rect.top = rcClipBox.top;
    rect.bottom = rcClipBox.bottom;
    rect.right += GetSystemMetrics(SM_CXMENUCHECK);
    MyFont.lfOrientation = 900;
    MyFont.lfEscapement = 900;
    TextPoint = CPoint(rect.left+2, rect.bottom-4-iconSize.cy);
  }
  else
  {
    MyFont.lfOrientation = 0;
    MyFont.lfEscapement = 0;

    TextPoint = CPoint(rect.left+2+iconSize.cx, rect.top);
  }
  Font.CreateFontIndirect(&MyFont);
  CFont *pOldFont = pDC->SelectObject(&Font);
  SIZE size = {0,0};
  VERIFY(::GetTextExtentPoint32(pDC->m_hDC,pMenuData->m_szMenuText,pMenuData->m_szMenuText.GetLength(),&size));
  COLORREF oldColor = pDC->SetTextColor(colorText);
  int OldMode = pDC->SetBkMode(TRANSPARENT);

  if(pMenuData->m_nTitleFlags&MFT_GRADIENT)
  {
    if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
    {
      DrawGradient(pDC,rect,colorLeft,colorRight,false);
    }
    else
    {
      DrawGradient(pDC,rect,colorRight,colorLeft,true);
    }
  }
  else
  {
    if(pMenuData->m_nTitleFlags&MFT_ROUND)
    {
      if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
      {
        TextPoint.y-=2;
        rect.right = rect.left+size.cy+4;
      }
      else
      {
        int maxSpace = ((rect.Width()-size.cx)/2);
        TextPoint.x+=min(maxSpace,10);
      }

      CBrush brush(colorRight);
      CPen* pOldPen = (CPen*)pDC->SelectStockObject(WHITE_PEN);
      CBrush* pOldBrush = pDC->SelectObject(&brush);

      pDC->RoundRect(rect,CPoint(10,10));
      pDC->SelectObject(pOldBrush);
      pDC->SelectObject(pOldPen);
    }
    else
    {
      pDC->FillSolidRect(rect,colorRight);
    }
  }
  if (pMenuData->m_nTitleFlags&MFT_SUNKEN)
  {
    pDC->Draw3dRect(rect,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
  }

  if (pMenuData->m_nTitleFlags&MFT_CENTER)
  {
    if (pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
    {
      TextPoint.y = rect.bottom - ((rect.Height()-size.cx-iconSize.cy)>>1)-iconSize.cy;
    }
    else
    {
      TextPoint.x = rect.left + ((rect.Width()-size.cx-iconSize.cx)>>1)+iconSize.cx;
    }
  }

  pDC->TextOut(TextPoint.x,TextPoint.y, pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL));

  if(pMenuData->m_nMenuIconOffset!=(-1) && pMenuData->m_pMenuIcon)
  {
    CPoint ptImage = TextPoint;
    if (pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
    {
      ptImage.y += 2;
    }
    else
    {
      ptImage.x -= iconSize.cx;
      ptImage.y += 2;
    }
    // draws the icon
    HICON hDrawIcon2 = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset);
    pDC->DrawState(ptImage, iconSize-CSize(4,4), hDrawIcon2, DSS_NORMAL,(HBRUSH)NULL);
    DestroyIcon(hDrawIcon2);
  }

  if(pMenuData->m_nTitleFlags&MFT_LINE)
  {
    if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
    {
      CRect rect2(rect.left+20,rect.top+5,rect.left+22,rect.bottom-5);
      pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
      rect2.OffsetRect(3,0);
      rect2.InflateRect(0,-10);
      pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
    }
    else
    {
      CRect rect2(rect.left+2,rect.bottom-7,rect.right-2,rect.bottom-5);
      pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
      rect2.OffsetRect(0,3);
      rect2.InflateRect(-10,0);
      pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
    }
  }
  pDC->SetBkMode(OldMode);
  pDC->SetTextColor(oldColor);
  pDC->SelectObject(pOldFont);
}

void CNewMenu::DrawItem_WinXP(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar)
{
  ASSERT(lpDIS != NULL);

  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpDIS->itemData);
  ASSERT(pMenuData);

  UINT nFlags = pMenuData->m_nFlags;

  CNewMemDC memDC(&lpDIS->rcItem,lpDIS->hDC);
  CDC* pDC;
  if( bIsMenuBar || (nFlags&MF_SEPARATOR) )
  { // For title and menubardrawing disable memory painting
    memDC.DoCancel();
    pDC = CDC::FromHandle(lpDIS->hDC);
  }
  else
  {
    pDC = &memDC;
  }

  COLORREF colorWindow = GetSysColor(COLOR_WINDOW);
  //  COLORREF colorMenuBar = bIsMenuBar?GetMenuBarColor(m_hMenu):GetMenuColor();
  COLORREF colorMenuBar = GetMenuBarColor(m_hMenu);
  COLORREF colorMenu = MixedColor(colorWindow,colorMenuBar);
  COLORREF colorBitmap = MixedColor(GetMenuBarColor(m_hMenu),colorWindow);
  COLORREF colorSel = GetXpHighlightColor();
  COLORREF colorBorder = GetSysColor(COLOR_HIGHLIGHT);//DarkenColor(128,colorMenuBar);

  if(bHighContrast)
  {
    colorBorder = GetSysColor(COLOR_BTNTEXT);
  }

  if (NumScreenColors() <= 256)
  {
    colorBitmap = GetSysColor(COLOR_BTNFACE);
  }

  // Better contrast when you have less than 256 colors
  if(pDC->GetNearestColor(colorMenu)==pDC->GetNearestColor(colorBitmap))
  {
    colorMenu = colorWindow;
    colorBitmap = colorMenuBar;
  }

  //CPen Pen(PS_SOLID,0,GetSysColor(COLOR_HIGHLIGHT));
  CPen Pen(PS_SOLID,0,colorBorder);

  if(bIsMenuBar)
  {
#ifdef _TRACE_MENU_
    //   AfxTrace(_T("BarState: 0x%lX Menus %ld\n"),lpDIS->itemState,m_dwOpenMenu);
#endif
    if(!IsMenu(UIntToHMenu(lpDIS->itemID)) && (lpDIS->itemState&ODS_SELECTED_OPEN))
    {
      lpDIS->itemState = (lpDIS->itemState&~(ODS_SELECTED|ODS_SELECTED_OPEN))|ODS_HOTLIGHT;
    }
    else if(!(lpDIS->itemState&ODS_SELECTED_OPEN) && !m_dwOpenMenu && lpDIS->itemState&ODS_SELECTED)
    {
      lpDIS->itemState = (lpDIS->itemState&~ODS_SELECTED)|ODS_HOTLIGHT;
    }
    if(!(lpDIS->itemState&ODS_HOTLIGHT))
    {
      colorSel = colorBitmap;
    }
    colorMenu = colorMenuBar;
  }

  CBrush m_brSel(colorSel);
  CBrush m_brBitmap(colorBitmap);

  CRect RectIcon(lpDIS->rcItem);
  CRect RectText(lpDIS->rcItem);
  CRect RectSel(lpDIS->rcItem);

  if(bIsMenuBar)
  {
    RectText.InflateRect (0,0,0,0);
    if(lpDIS->itemState&ODS_DRAW_VERTICAL)
      RectSel.InflateRect (0,0,0, -4);
    else
      RectSel.InflateRect (0,0,-2 -2,0);
  }
  else
  {
    if(nFlags&MFT_RIGHTORDER)
    {
      RectIcon.left = RectIcon.right - (m_iconX + 8);
      RectText.right  = RectIcon.left;
    }
    else
    {
      RectIcon.right = RectIcon.left + m_iconX + 8;
      RectText.left  = RectIcon.right;
    }
    // Draw for Bitmapbackground
    pDC->FillSolidRect (RectIcon,colorBitmap);
  }
  // Draw for Textbackground
  pDC->FillSolidRect (RectText,colorMenu);

  // Spacing for submenu only in popups
  if(!bIsMenuBar)
  {
    if(nFlags&MFT_RIGHTORDER)
    {
      RectText.left += 15;
      RectText.right -= 4;
    }
    else
    {
      RectText.left += 4;
      RectText.right -= 15;
    }
  }

  //  Flag for highlighted item
  if(lpDIS->itemState & (ODS_HOTLIGHT|ODS_INACTIVE) )
  {
    lpDIS->itemState |= ODS_SELECTED;
  }

  if(bIsMenuBar && (lpDIS->itemState&ODS_SELECTED) )
  {
    if(!(lpDIS->itemState&ODS_INACTIVE) )
    {
      SetLastMenuRect(lpDIS->hDC,RectSel);
      if(!(lpDIS->itemState&ODS_HOTLIGHT) )
      {
        // Create a new pen for the special color
        Pen.DeleteObject();
        colorBorder = bHighContrast?GetSysColor(COLOR_BTNTEXT):DarkenColor(128,GetMenuBarColor());
        Pen.CreatePen(PS_SOLID,0,colorBorder);

        int X,Y;
        CRect rect = RectText;
        int winH = rect.Height();

        // Simulate a shadow on right edge...
        if (NumScreenColors() <= 256)
        {
          DWORD clr = GetSysColor(COLOR_BTNSHADOW);
          if(lpDIS->itemState&ODS_DRAW_VERTICAL)
          {
            int winW = rect.Width();
            for (Y=0; Y<=1 ;Y++)
            {
              for (X=4; X<=(winW-1) ;X++)
              {
                pDC->SetPixel(rect.left+X,rect.bottom-Y,clr);
              }
            }
          }
          else
          {
            for (X=3; X<=4 ;X++)
            {
              for (Y=4; Y<=(winH-1) ;Y++)
              {
                pDC->SetPixel(rect.right - X, Y+rect.top, clr );
              }
            }
          }
        }
        else
        {
          if(lpDIS->itemState&ODS_DRAW_VERTICAL)
          {
            int winW = rect.Width();
            COLORREF barColor = pDC->GetPixel(rect.left+4,rect.bottom-4);
            for (Y=1; Y<=4 ;Y++)
            {
              for (X=0; X<4 ;X++)
              {
                if(barColor==CLR_INVALID)
                {
                  barColor = pDC->GetPixel(rect.left+X,rect.bottom-Y);
                }
                pDC->SetPixel(rect.left+X,rect.bottom-Y,colorMenuBar);
              }
              for (X=4; X<8 ;X++)
              {
                pDC->SetPixel(rect.left+X,rect.bottom-Y,DarkenColor(2* 3 * Y * (X - 3), colorMenuBar));
              }
              for (X=8; X<=(winW-1) ;X++)
              {
                pDC->SetPixel(rect.left+X,rect.bottom-Y, DarkenColor(2*15 * Y, colorMenuBar) );
              }
            }
          }
          else
          {
            for (X=1; X<=4 ;X++)
            {
              for (Y=0; Y<4 ;Y++)
              {
                pDC->SetPixel(rect.right-X,Y+rect.top, colorMenuBar );
              }
              for (Y=4; Y<8 ;Y++)
              {
                pDC->SetPixel(rect.right-X,Y+rect.top,DarkenColor(2* 3 * X * (Y - 3), colorMenuBar));
              }
              for (Y=8; Y<=(winH-1) ;Y++)
              {
                pDC->SetPixel(rect.right - X, Y+rect.top, DarkenColor(2*15 * X, colorMenuBar) );
              }
            }
          }
        }
      }
    }
  }
  // For keyboard navigation only
  BOOL bDrawSmallSelection = FALSE;
  // remove the selected bit if it's grayed out
  if( (lpDIS->itemState&ODS_GRAYED) && !m_bSelectDisable)
  {
    if( lpDIS->itemState & ODS_SELECTED )
    {
      lpDIS->itemState = lpDIS->itemState & (~ODS_SELECTED);
      DWORD MsgPos = ::GetMessagePos();
      if( MsgPos==CNewMenuHook::m_dwMsgPos )
      {
        bDrawSmallSelection = TRUE;
      }
      else
      {
        CNewMenuHook::m_dwMsgPos = MsgPos;
      }
    }
  }

  // Draw the seperator
  if( nFlags & MF_SEPARATOR )
  {
    if( pMenuData->m_nTitleFlags&MFT_TITLE )
    {
      DrawTitle(lpDIS,bIsMenuBar);
    }
    else
    {
      // Draw only the seperator
      CRect rect;
      rect.top = RectText.CenterPoint().y;
      rect.bottom = rect.top+1;
      if(nFlags&MFT_RIGHTORDER)
      {
        rect.right = RectText.right;
        rect.left = lpDIS->rcItem.left;
      }
      else
      {
      rect.right = lpDIS->rcItem.right;
        rect.left = RectText.left;
      }
      pDC->FillSolidRect(rect,GetSysColor(COLOR_GRAYTEXT));
    }
  }
  else
  {
    if( (lpDIS->itemState & ODS_SELECTED) && !(lpDIS->itemState&ODS_INACTIVE) )
    {
      pDC->FillSolidRect(RectSel,colorSel);
      // Draw the selection
      CPen* pOldPen = pDC->SelectObject(&Pen);
      CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(HOLLOW_BRUSH);
      pDC->Rectangle(RectSel);
      pDC->SelectObject(pOldBrush);
      pDC->SelectObject(pOldPen);
    }
    else if (bDrawSmallSelection)
    {
      pDC->FillSolidRect(RectSel,colorMenu);
      // Draw the selection for keyboardnavigation
      CPen* pOldPen = pDC->SelectObject(&Pen);
      CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(HOLLOW_BRUSH);
      pDC->Rectangle(RectSel);
      pDC->SelectObject(pOldBrush);
      pDC->SelectObject(pOldPen);
    }

    UINT state = lpDIS->itemState;

    BOOL standardflag=FALSE;
    BOOL selectedflag=FALSE;
    BOOL disableflag=FALSE;
    BOOL checkflag=FALSE;

    CString strText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);

    if( (state&ODS_CHECKED) && (pMenuData->m_nMenuIconOffset<0) )
    {
      if(state&ODS_SELECTED && m_selectcheck>0)
      {
        checkflag=TRUE;
      }
      else if(m_unselectcheck>0)
      {
        checkflag=TRUE;
      }
    }
    else if(pMenuData->m_nMenuIconOffset != -1)
    {
      standardflag=TRUE;
      if(state&ODS_SELECTED)
      {
        selectedflag=TRUE;
      }
      else if(state&ODS_GRAYED)
      {
        disableflag=TRUE;
      }
    }

    // draw the menutext
    if(!strText.IsEmpty())
    {
      LOGFONT logFontMenu;
      CFont fontMenu;

#ifdef _NEW_MENU_USER_FONT
      logFontMenu = MENU_USER_FONT;
#else
      NONCLIENTMETRICS nm = {0};
      nm.cbSize = sizeof (nm);
      VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
      logFontMenu =  nm.lfMenuFont;
#endif

      // Default selection?
      if(state&ODS_DEFAULT)
      {
        // Make the font bold
        logFontMenu.lfWeight = FW_BOLD;
      }
      if(state&ODS_DRAW_VERTICAL)
      {
        // rotate font 90?
        logFontMenu.lfOrientation = -900;
        logFontMenu.lfEscapement = -900;
      }

      fontMenu.CreateFontIndirect(&logFontMenu);

      CString leftStr;
      CString rightStr;
      leftStr.Empty();
      rightStr.Empty();

      int tablocr=strText.ReverseFind(_T('\t'));
      if(tablocr!=-1)
      {
        rightStr=strText.Mid(tablocr+1);
        leftStr=strText.Left(strText.Find(_T('\t')));
      }
      else
      {
        leftStr = strText;
      }

      // Draw the text in the correct color:
      UINT nFormat  = DT_LEFT| DT_SINGLELINE|DT_VCENTER;
      UINT nFormatr = DT_RIGHT|DT_SINGLELINE|DT_VCENTER;
      if(nFlags&MFT_RIGHTORDER)
      {
        nFormat  = DT_RIGHT| DT_SINGLELINE|DT_VCENTER|DT_RTLREADING;
        nFormatr = DT_LEFT|DT_SINGLELINE|DT_VCENTER;
      }

      int iOldMode = pDC->SetBkMode( TRANSPARENT);
      CFont* pOldFont = pDC->SelectObject (&fontMenu);

      COLORREF OldTextColor;
      if( (lpDIS->itemState&ODS_GRAYED) ||
        (bIsMenuBar && lpDIS->itemState&ODS_INACTIVE) )
      {
        // Draw the text disabled?
        OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
      }
      else
      {
        // Draw the text normal
        if( bHighContrast && !bIsMenuBar && !(state&ODS_SELECTED) )
        {
          OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
        }
        else
        {
          OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_MENUTEXT));
        }
      }
      UINT dt_Hide = (lpDIS->itemState & ODS_NOACCEL)?DT_HIDEPREFIX:0;
      if(dt_Hide && g_Shell>=Win2000)
      {
        BOOL bMenuUnderlines = TRUE;
        if(SystemParametersInfo( SPI_GETKEYBOARDCUES,0,&bMenuUnderlines,0)==TRUE && bMenuUnderlines==TRUE)
        {
          // do not hide
          dt_Hide = 0;
        }
      }

      if(bIsMenuBar)
      {
        MenuDrawText(pDC->m_hDC,leftStr,-1,RectSel, DT_SINGLELINE|DT_VCENTER|DT_CENTER|dt_Hide);
      }
      else
      {
        pDC->DrawText(leftStr,RectText, nFormat|dt_Hide);
        if(tablocr!=-1)
        {
          pDC->DrawText (rightStr,RectText,nFormatr|dt_Hide);
        }
      }
      pDC->SetTextColor(OldTextColor);
      pDC->SelectObject(pOldFont);
      pDC->SetBkMode(iOldMode);
    }

    // Draw the bitmap or checkmarks
    if(!bIsMenuBar)
    {
      CRect rect2 = RectText;

      if(checkflag||standardflag||selectedflag||disableflag)
      {
        if(checkflag && m_checkmaps)
        {
          CPoint ptImage(RectIcon.left+3,RectIcon.top+4);

          if(state&ODS_SELECTED)
          {
            m_checkmaps->Draw(pDC,1,ptImage,ILD_TRANSPARENT);
          }
          else
          {
            m_checkmaps->Draw(pDC,0,ptImage,ILD_TRANSPARENT);
          }
        }
        else
        {
          CSize size = pMenuData->m_pMenuIcon->GetIconSize();
          HICON hDrawIcon = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset);
          //CPoint ptImage(RectIcon.left+3,RectIcon.top+ 4);
          CPoint ptImage( RectIcon.left+3, RectIcon.top + ((RectIcon.Height()-size.cy)>>1) );

          // Need to draw the checked state
          if (state&ODS_CHECKED)
          {
            CRect rect = RectIcon;
            if(nFlags&MFT_RIGHTORDER)
            {
              rect.InflateRect (-2,-1,-1,-1);
            }
            else
            {
            rect.InflateRect (-1,-1,-2,-1);
            }
            if(selectedflag)
            {
              if (NumScreenColors() > 256)
              {
                pDC->FillSolidRect(rect,MixedColor(colorSel,GetSysColor(COLOR_HIGHLIGHT)));
              }
              else
              {
                pDC->FillSolidRect(rect,colorSel); //GetSysColor(COLOR_HIGHLIGHT)
              }
            }
            else
            {
              pDC->FillSolidRect(rect,MixedColor(colorBitmap,GetSysColor(COLOR_HIGHLIGHT)));
            }

            CPen* pOldPen = pDC->SelectObject(&Pen);
            CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(HOLLOW_BRUSH);

            pDC->Rectangle(rect);

            pDC->SelectObject(pOldBrush);
            pDC->SelectObject(pOldPen);
          }

          // Correcting of a smaler icon
          if(size.cx<m_iconX)
          {
            ptImage.x += (m_iconX-size.cx)>>1;
          }

          if(state & ODS_DISABLED)
          {
            if(m_bEnableXpBlending)
            {
              // draws the icon blended
              HICON hDrawIcon2 = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset+2);
              pDC->DrawState(ptImage, size, hDrawIcon2, DSS_NORMAL,(HBRUSH)NULL);
              DestroyIcon(hDrawIcon2);
            }
            else
            {
              CBrush Brush;
              Brush.CreateSolidBrush(pDC->GetNearestColor(DarkenColor(70,colorBitmap)));
              pDC->DrawState(ptImage, size, hDrawIcon, DSS_MONO, &Brush);
            }
          }
          else
          {
            if(selectedflag)
            {
              CBrush Brush;
              // Color of the shade
              Brush.CreateSolidBrush(pDC->GetNearestColor(DarkenColorXP(colorSel)));
              if(!(state & ODS_CHECKED))
              {
                ptImage.x++; ptImage.y++;
                pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL | DSS_MONO, &Brush);
                ptImage.x-=2; ptImage.y-=2;
              }
              pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL,(HBRUSH)NULL);
            }
            else
            {
              if(m_bEnableXpBlending)
              {
                // draws the icon blended
                HICON hDrawIcon2 = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset+1);
                pDC->DrawState(ptImage, size, hDrawIcon2, DSS_NORMAL,(HBRUSH)NULL);
                DestroyIcon(hDrawIcon2);
              }
              else
              {
                // draws the icon with normal color
                pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL,(HBRUSH)NULL);
              }
            }
          }
          DestroyIcon(hDrawIcon);
        }
      }

      if(pMenuData->m_nMenuIconOffset<0 /*&& state&ODS_CHECKED */ && !checkflag)
      {
        MENUITEMINFO info = {0};
        info.cbSize = sizeof(info);
        info.fMask = MIIM_CHECKMARKS;

        ::GetMenuItemInfo(HWndToHMenu(lpDIS->hwndItem),lpDIS->itemID,MF_BYCOMMAND, &info);

        if(state&ODS_CHECKED || info.hbmpUnchecked)
        {
          CRect rect = RectIcon;
          if(nFlags&MFT_RIGHTORDER)
          {
            rect.InflateRect (-2,-1,-1,-1);
          }
          else
          {
          rect.InflateRect (-1,-1,-2,-1);
          }
          // draw the color behind checkmarks
          if(state&ODS_SELECTED)
          {
            if (NumScreenColors() > 256)
            {
              pDC->FillSolidRect(rect,MixedColor(colorSel,GetSysColor(COLOR_HIGHLIGHT)));
            }
            else
            {
              pDC->FillSolidRect(rect,colorSel);
            }
          }
          else
          {
            pDC->FillSolidRect(rect,MixedColor(colorBitmap,GetSysColor(COLOR_HIGHLIGHT)));
          }
          CPen* pOldPen = pDC->SelectObject(&Pen);
          CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(HOLLOW_BRUSH);

          pDC->Rectangle(rect);

          pDC->SelectObject(pOldBrush);
          pDC->SelectObject(pOldPen);
          if (state&ODS_CHECKED)
          {
            CRect rect(RectIcon);
            rect.InflateRect(2,((m_iconY-RectIcon.Height())>>1)+2);

            if (!info.hbmpChecked)
            { // Checkmark
              DrawSpecialCharStyle(pDC,rect,98,state);
            }
            else if(!info.hbmpUnchecked)
            { // Bullet
              DrawSpecialCharStyle(pDC,rect,105,state);
            }
            else
            { // Draw Bitmap
              BITMAP myInfo = {0};
              GetObject((HGDIOBJ)info.hbmpChecked,sizeof(myInfo),&myInfo);
              CPoint Offset = RectIcon.TopLeft() + CPoint((RectIcon.Width()-myInfo.bmWidth)/2,(RectIcon.Height()-myInfo.bmHeight)/2);
              pDC->DrawState(Offset,CSize(0,0),info.hbmpChecked,DST_BITMAP|DSS_MONO);
            }
          }
          else if(info.hbmpUnchecked)
          {
            // Draw Bitmap
            BITMAP myInfo = {0};
            GetObject((HGDIOBJ)info.hbmpUnchecked,sizeof(myInfo),&myInfo);
            CPoint Offset = RectIcon.TopLeft() + CPoint((RectIcon.Width()-myInfo.bmWidth)/2,(RectIcon.Height()-myInfo.bmHeight)/2);
            if(state & ODS_DISABLED)
            {
              pDC->DrawState(Offset,CSize(0,0),info.hbmpUnchecked,DST_BITMAP|DSS_MONO|DSS_DISABLED);
            }
            else
            {
              pDC->DrawState(Offset,CSize(0,0),info.hbmpUnchecked,DST_BITMAP|DSS_MONO);
            }
          }
        }
        else if ((lpDIS->itemID&0xffff)>=SC_SIZE && (lpDIS->itemID&0xffff)<=SC_HOTKEY )
        {
          DrawSpecial_WinXP(pDC,RectIcon,lpDIS->itemID,state);
        }
      }
    }
  }
}

void CNewMenu::DrawItem_XP_2003(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar)
{
#ifdef _TRACE_MENU_
  AfxTrace(_T("BarState: 0x%lX MenuID 0x%lX\n"),lpDIS->itemState,lpDIS->itemID);
#endif
  ASSERT(lpDIS != NULL);

  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpDIS->itemData);
  ASSERT(pMenuData);

  UINT nFlags = pMenuData->m_nFlags;

  CNewMemDC memDC(&lpDIS->rcItem,lpDIS->hDC);
  CDC* pDC;
  if( bIsMenuBar || (nFlags&MF_SEPARATOR) )
  { // For title and menubardrawing disable memory painting
    memDC.DoCancel();
    pDC = CDC::FromHandle(lpDIS->hDC);
  }
  else
  {
    pDC = &memDC;
  }

  COLORREF colorWindow = DarkenColor(10,GetSysColor(COLOR_WINDOW));
  COLORREF colorMenuBar = bIsMenuBar?GetMenuBarColor():GetMenuColor();
  COLORREF colorMenu = MixedColor(colorWindow,colorMenuBar);
  COLORREF colorBitmap = MixedColor(GetMenuBarColor(),colorWindow);
  COLORREF colorSel = GetXpHighlightColor();
  COLORREF colorBorder = GetSysColor(COLOR_HIGHLIGHT);//DarkenColor(128,colorMenuBar);

  //COLORREF colorCaption = GetSysColor(COLOR_ACTIVECAPTION); //RGB(0,84,227);
  //COLORREF cc1 = MixedColor(colorWindow,colorCaption);
  //COLORREF cc2 = MidColor(colorWindow,colorCaption);

  COLORREF colorCheck    = RGB(255,192,111);
  COLORREF colorCheckSel = RGB(254,128,62);
  colorSel = RGB(255,238,194);
  if(!IsMenuThemeActive() &&
    GetMenuDrawMode()!=STYLE_COLORFUL_NOBORDER &&
      GetMenuDrawMode()!=STYLE_COLORFUL)
  {
    colorSel = GetXpHighlightColor();
    //colorCheck = pDC->GetNearestColor(DarkenColorXP(colorSel));
    colorCheckSel = MixedColor(colorSel,GetSysColor(COLOR_HIGHLIGHT));
    colorCheck = colorCheckSel;
  }

  colorBitmap = colorMenuBar = GetMenuBarColor2003();
  if(bHighContrast)
  {
    colorBorder = GetSysColor(COLOR_BTNTEXT);
  }

  // Better contrast when you have less than 256 colors
  if(pDC->GetNearestColor(colorMenu)==pDC->GetNearestColor(colorBitmap))
  {
    colorMenu = colorWindow;
    colorBitmap = colorMenuBar;
  }

  CPen Pen(PS_SOLID,0,colorBorder);

  if(bIsMenuBar)
  {
    if(!IsMenu(UIntToHMenu(lpDIS->itemID)) && (lpDIS->itemState&ODS_SELECTED_OPEN))
    {
      lpDIS->itemState = (lpDIS->itemState&~(ODS_SELECTED|ODS_SELECTED_OPEN))|ODS_HOTLIGHT;
    }
    else if( !(lpDIS->itemState&ODS_SELECTED_OPEN) && !m_dwOpenMenu && lpDIS->itemState&ODS_SELECTED)
    {
      lpDIS->itemState = (lpDIS->itemState&~ODS_SELECTED)|ODS_HOTLIGHT;
    }
    if(!(lpDIS->itemState&ODS_HOTLIGHT))
    {
      colorSel = colorBitmap;
    }
    colorMenu = colorMenuBar;
  }

  CBrush m_brSel(colorSel);
  CBrush m_brBitmap(colorBitmap);

  CRect RectIcon(lpDIS->rcItem);
  CRect RectText(lpDIS->rcItem);
  CRect RectSel(lpDIS->rcItem);

  if(bIsMenuBar)
  {
    RectText.InflateRect (0,0,0,0);
    if(lpDIS->itemState&ODS_DRAW_VERTICAL)
    {
      RectSel.InflateRect (0,0,0, -4);
    }
    else
    {
      RectSel.InflateRect (0,0,-4,0);
    }

    if(lpDIS->itemState&ODS_SELECTED)
    {
      if(lpDIS->itemState&ODS_DRAW_VERTICAL)
        RectText.bottom -=4;
      else
        RectText.right -=4;
      if(NumScreenColors() <= 256)
      {
        pDC->FillSolidRect(RectText,colorMenu);
      }
      else
      {
        DrawGradient(pDC,RectText,colorMenu,colorBitmap,FALSE,TRUE);
      }
      if(lpDIS->itemState&ODS_DRAW_VERTICAL)
      {
        RectText.bottom +=4;
      }
      else
      {
        RectText.right +=4;
      }
    }
    else
    {
      MENUINFO menuInfo = {0};
      menuInfo.cbSize = sizeof(menuInfo);
      menuInfo.fMask = MIM_BACKGROUND;

      if(::GetMenuInfo(m_hMenu,&menuInfo) && menuInfo.hbrBack)
      {
        CBrush *pBrush = CBrush::FromHandle(menuInfo.hbrBack);
        CPoint brushOrg(0,0);

        // new support for menubar
        CControlBar* pControlBar = DYNAMIC_DOWNCAST(CControlBar,pDC->GetWindow());
        if(pControlBar)
        {
          CFrameWnd* pFrame = pControlBar->GetParentFrame();
          if(pFrame)
          {
            CRect windowRect;
            pFrame->GetWindowRect(windowRect);
            pControlBar->ScreenToClient(windowRect);
            brushOrg = windowRect.TopLeft();
          }
        }

        VERIFY(pBrush->UnrealizeObject());
        CPoint oldOrg = pDC->SetBrushOrg(brushOrg);
        pDC->FillRect(RectText,pBrush);
        pDC->SetBrushOrg(oldOrg);
      }
      else
      {
        pDC->FillSolidRect(RectText,colorMenu);
      }
      }
    }
  else
  {
    if(nFlags&MFT_RIGHTORDER)
    {
      RectIcon.left = RectIcon.right - (m_iconX + 8);
      RectText.right= RectIcon.left;
      // Draw for Bitmapbackground
      DrawGradient(pDC,RectIcon,colorBitmap,colorMenu,TRUE);
  }
  else
  {
      RectIcon.right = RectIcon.left + m_iconX + 8;
      RectText.left  = RectIcon.right;
    // Draw for Bitmapbackground
      DrawGradient(pDC,RectIcon,colorMenu,colorBitmap,TRUE);
    }
    // Draw for Textbackground
    pDC->FillSolidRect(RectText,colorMenu);
  }

  // Spacing for submenu only in popups
  if(!bIsMenuBar)
  {
    if(nFlags&MFT_RIGHTORDER)
    {
      RectText.left += 15;
      RectText.right -= 4;
    }
    else
    {
      RectText.left += 4;
      RectText.right -= 15;
    }
  }

  //  Flag for highlighted item
  if(lpDIS->itemState & (ODS_HOTLIGHT|ODS_INACTIVE) )
  {
    lpDIS->itemState |= ODS_SELECTED;
  }

  if(bIsMenuBar && (lpDIS->itemState&ODS_SELECTED) )
  {
    if(!(lpDIS->itemState&ODS_INACTIVE) )
    {
      SetLastMenuRect(lpDIS->hDC,RectSel);
      if(!(lpDIS->itemState&ODS_HOTLIGHT) )
      {
        // Create a new pen for the special color
        Pen.DeleteObject();
        colorBorder = bHighContrast?GetSysColor(COLOR_BTNTEXT):DarkenColor(128,GetMenuBarColor());
        Pen.CreatePen(PS_SOLID,0,colorBorder);

        int X,Y;
        CRect rect = RectText;
        int winH = rect.Height();

        // Simulate a shadow on right edge...
        if (NumScreenColors() <= 256)
        {
          DWORD clr = GetSysColor(COLOR_BTNSHADOW);
          if(lpDIS->itemState&ODS_DRAW_VERTICAL)
          {
            int winW = rect.Width();
            for (Y=0; Y<=1 ;Y++)
            {
              for (X=4; X<=(winW-1) ;X++)
              {
                pDC->SetPixel(rect.left+X,rect.bottom-Y,clr);
              }
            }
          }
          else
          {
            for (X=3; X<=4 ;X++)
            {
              for (Y=4; Y<=(winH-1) ;Y++)
              {
                pDC->SetPixel(rect.right - X, Y + rect.top, clr );
              }
            }
          }
        }
        else
        {
          if(lpDIS->itemState&ODS_DRAW_VERTICAL)
          {
            int winW = rect.Width();
            COLORREF barColor = pDC->GetPixel(rect.left+4,rect.bottom-4);
            for (Y=1; Y<=4 ;Y++)
            {
              for (X=0; X<4 ;X++)
              {
                if(barColor==CLR_INVALID)
                {
                  barColor = pDC->GetPixel(rect.left+X,rect.bottom-Y);
                }
                pDC->SetPixel(rect.left+X,rect.bottom-Y,barColor);
              }
              for (X=4; X<8 ;X++)
              {
                pDC->SetPixel(rect.left+X,rect.bottom-Y,DarkenColor(2* 3 * Y * (X - 3), barColor));
              }
              for (X=8; X<=(winW-1) ;X++)
              {
                pDC->SetPixel(rect.left+X,rect.bottom-Y, DarkenColor(2*15 * Y, barColor) );
              }
            }
          }
          else
          {
            COLORREF barColor = pDC->GetPixel(rect.right-1,rect.top);
            for (X=1; X<=4 ;X++)
            {
              for (Y=0; Y<4 ;Y++)
              {
                if(barColor==CLR_INVALID)
                {
                  barColor = pDC->GetPixel(rect.right-X,Y+rect.top);
                }
                pDC->SetPixel(rect.right-X,Y+rect.top, barColor );
              }
              for (Y=4; Y<8 ;Y++)
              {
                pDC->SetPixel(rect.right-X,Y+rect.top,DarkenColor(2* 3 * X * (Y - 3), barColor));
              }
              for (Y=8; Y<=(winH-1) ;Y++)
              {
                pDC->SetPixel(rect.right - X, Y+rect.top, DarkenColor(2*15 * X, barColor) );
              }
            }
          }
        }
      }
    }
  }
  // For keyboard navigation only
  BOOL bDrawSmallSelection = FALSE;
  // remove the selected bit if it's grayed out
  if( (lpDIS->itemState&ODS_GRAYED) && !m_bSelectDisable)
  {
    if( lpDIS->itemState & ODS_SELECTED )
    {
      lpDIS->itemState = lpDIS->itemState & (~ODS_SELECTED);
      DWORD MsgPos = ::GetMessagePos();
      if( MsgPos==CNewMenuHook::m_dwMsgPos )
      {
        bDrawSmallSelection = TRUE;
      }
      else
      {
        CNewMenuHook::m_dwMsgPos = MsgPos;
      }
    }
  }

  // Draw the seperator
  if( nFlags & MFT_SEPARATOR )
  {
    if( pMenuData->m_nTitleFlags&MFT_TITLE )
    {
      DrawTitle(lpDIS,bIsMenuBar);
    }
    else
    {
      // Draw only the seperator
      CRect rect;
      rect.top = RectText.CenterPoint().y;
      rect.bottom = rect.top+1;

      if(nFlags&MFT_RIGHTORDER)
      {
        rect.right = RectText.right;
        rect.left = lpDIS->rcItem.left;
      }
      else
      {
      rect.right = lpDIS->rcItem.right;
        rect.left = RectText.left;
      }
      pDC->FillSolidRect(rect,GetSysColor(COLOR_GRAYTEXT));
    }
  }
  else
  {
    if( (lpDIS->itemState & ODS_SELECTED) && !(lpDIS->itemState&ODS_INACTIVE) )
    {
      if(bIsMenuBar)
      {
        if(NumScreenColors() <= 256)
        {
          pDC->FillSolidRect(RectSel,colorWindow);
        }
        else
        {
          DrawGradient(pDC,RectSel,colorWindow,colorSel,FALSE,TRUE);
        }
      }
      else
      {
        pDC->FillSolidRect(RectSel,colorSel);
      }
      // Draw the selection
      CPen* pOldPen = pDC->SelectObject(&Pen);
      CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(HOLLOW_BRUSH);
      pDC->Rectangle(RectSel);
      pDC->SelectObject(pOldBrush);
      pDC->SelectObject(pOldPen);
    }
    else if (bDrawSmallSelection)
    {
      pDC->FillSolidRect(RectSel,colorMenu);
      // Draw the selection for keyboardnavigation
      CPen* pOldPen = pDC->SelectObject(&Pen);
      CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(HOLLOW_BRUSH);
      pDC->Rectangle(RectSel);
      pDC->SelectObject(pOldBrush);
      pDC->SelectObject(pOldPen);
    }

    UINT state = lpDIS->itemState;

    BOOL standardflag=FALSE;
    BOOL selectedflag=FALSE;
    BOOL disableflag=FALSE;
    BOOL checkflag=FALSE;

    CString strText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);

    if( (state&ODS_CHECKED) && (pMenuData->m_nMenuIconOffset<0) )
    {
      if(state&ODS_SELECTED && m_selectcheck>0)
      {
        checkflag=TRUE;
      }
      else if(m_unselectcheck>0)
      {
        checkflag=TRUE;
      }
    }
    else if(pMenuData->m_nMenuIconOffset != -1)
    {
      standardflag = TRUE;
      if(state&ODS_SELECTED)
      {
        selectedflag=TRUE;
      }
      else if(state&ODS_GRAYED)
      {
        disableflag=TRUE;
      }
    }

    if(!strText.IsEmpty())
    {  // draw the menutext
      LOGFONT logFontMenu;
      CFont fontMenu;

#ifdef _NEW_MENU_USER_FONT
      logFontMenu = MENU_USER_FONT;
#else
      NONCLIENTMETRICS nm = {0};
      nm.cbSize = sizeof (nm);
      VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
      logFontMenu = nm.lfMenuFont;
#endif

      // Default selection?
      if(state&ODS_DEFAULT)
      {
        // Make the font bold
        logFontMenu.lfWeight = FW_BOLD;
      }
      if(state&ODS_DRAW_VERTICAL)
      {
        // rotate font 90?
        logFontMenu.lfOrientation = -900;
        logFontMenu.lfEscapement = -900;
      }

      fontMenu.CreateFontIndirect(&logFontMenu);

      CString leftStr;
      CString rightStr;
      leftStr.Empty();
      rightStr.Empty();

      int tablocr = strText.ReverseFind(_T('\t'));
      if(tablocr!=-1)
      {
        rightStr = strText.Mid(tablocr+1);
        leftStr = strText.Left(strText.Find(_T('\t')));
      }
      else
      {
        leftStr=strText;
      }

      // Draw the text in the correct color:
      UINT nFormat  = DT_LEFT| DT_SINGLELINE|DT_VCENTER;
      UINT nFormatr = DT_RIGHT|DT_SINGLELINE|DT_VCENTER;
      if(nFlags&MFT_RIGHTORDER)
      {
        nFormat  = DT_RIGHT| DT_SINGLELINE|DT_VCENTER|DT_RTLREADING;
        nFormatr = DT_LEFT|DT_SINGLELINE|DT_VCENTER;
      }

      int iOldMode = pDC->SetBkMode( TRANSPARENT);
      CFont* pOldFont = pDC->SelectObject (&fontMenu);

      COLORREF OldTextColor;
      if( (lpDIS->itemState&ODS_GRAYED) ||
        (bIsMenuBar && lpDIS->itemState&ODS_INACTIVE) )
      {
        // Draw the text disabled?
        if(bIsMenuBar && (NumScreenColors() <= 256) )
        {
          OldTextColor = pDC->SetTextColor(colorWindow);
        }
        else
        {
          OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
        }
      }
      else
      {
        // Draw the text normal
        if( bHighContrast && !bIsMenuBar && !(state&ODS_SELECTED) )
        {
          OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
        }
        else
        {
          OldTextColor = pDC->SetTextColor(GetSysColor(COLOR_MENUTEXT));
        }
      }
      // Office 2003 ignors this settings
      UINT dt_Hide = 0;//(lpDIS->itemState & ODS_NOACCEL)?DT_HIDEPREFIX:0;
      if(bIsMenuBar)
      {
        MenuDrawText(pDC->m_hDC,leftStr,-1,RectSel, DT_SINGLELINE|DT_VCENTER|DT_CENTER|dt_Hide);
      }
      else
      {
        pDC->DrawText(leftStr,RectText, nFormat|dt_Hide);
        if(tablocr!=-1)
        {
          pDC->DrawText (rightStr,RectText,nFormatr|dt_Hide);
        }
      }
      pDC->SetTextColor(OldTextColor);
      pDC->SelectObject(pOldFont);
      pDC->SetBkMode(iOldMode);
    }

    // Draw the bitmap or checkmarks
    if(!bIsMenuBar)
    {
      CRect rect2 = RectText;

      if(checkflag||standardflag||selectedflag||disableflag)
      {
        if(checkflag && m_checkmaps)
        {
          CPoint ptImage(RectIcon.left+3,RectIcon.top+4);

          if(state&ODS_SELECTED)
          {
            m_checkmaps->Draw(pDC,1,ptImage,ILD_TRANSPARENT);
          }
          else
          {
            m_checkmaps->Draw(pDC,0,ptImage,ILD_TRANSPARENT);
          }
        }
        else
        {
          CSize size = pMenuData->m_pMenuIcon->GetIconSize();
          HICON hDrawIcon = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset);
          //CPoint ptImage(RectIcon.left+3,RectIcon.top+ 4);
          CPoint ptImage( RectIcon.left+3, RectIcon.top + ((RectIcon.Height()-size.cy)>>1) );

          // Need to draw the checked state
          if (state&ODS_CHECKED)
          {
            CRect rect = RectIcon;
            if(nFlags&MFT_RIGHTORDER)
            {
              rect.InflateRect (-2,-1,-1,-1);
            }
            else
            {
            rect.InflateRect (-1,-1,-2,-1);
            }
            if(selectedflag)
            {
              pDC->FillSolidRect(rect,colorCheckSel);
            }
            else
            {
              pDC->FillSolidRect(rect,colorCheck);
            }

            CPen* pOldPen = pDC->SelectObject(&Pen);
            CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(HOLLOW_BRUSH);

            pDC->Rectangle(rect);

            pDC->SelectObject(pOldBrush);
            pDC->SelectObject(pOldPen);
          }

          // Correcting of a smaler icon
          if(size.cx<m_iconX)
          {
            ptImage.x += (m_iconX-size.cx)>>1;
          }

          if(state & ODS_DISABLED)
          {
            //if(m_bEnableXpBlending)
            {
              // draws the icon blended
              HICON hDrawIcon2 = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset+2);
              pDC->DrawState(ptImage, size, hDrawIcon2, DSS_NORMAL,(HBRUSH)NULL);
              DestroyIcon(hDrawIcon2);
            }
            //else
            //{
            //  CBrush Brush;
            //  Brush.CreateSolidBrush(pDC->GetNearestColor(DarkenColor(70,colorBitmap)));
            //  pDC->DrawState(ptImage, size, hDrawIcon, DSS_MONO, &Brush);
            //}
          }
          else
          {
            if(selectedflag)
            {
              //if(!(state & ODS_CHECKED))
              //{
              //  CBrush Brush;
              //  // Color of the shade
              //  Brush.CreateSolidBrush(pDC->GetNearestColor(DarkenColorXP(colorSel)));
              //  ptImage.x++; ptImage.y++;
              //  pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL | DSS_MONO, &Brush);
              //  ptImage.x-=2; ptImage.y-=2;
              //}
              pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL,(HBRUSH)NULL);
            }
            else
            {
              if(m_bEnableXpBlending)
              {
                // draws the icon blended
                HICON hDrawIcon2 = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset+1);
                pDC->DrawState(ptImage, size, hDrawIcon2, DSS_NORMAL,(HBRUSH)NULL);
                DestroyIcon(hDrawIcon2);
              }
              else
              {
                // draws the icon with normal color
                pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL,(HBRUSH)NULL);
                //ImageList_DrawEx(pMenuData->m_pMenuIcon->m_IconsList,pMenuData->m_nMenuIconOffset,pDC->GetSafeHdc(),ptImage.x,ptImage.y,0,0,CLR_DEFAULT,CLR_DEFAULT,ILD_NORMAL);
              }
            }
          }
          DestroyIcon(hDrawIcon);
        }
      }

      if(pMenuData->m_nMenuIconOffset<0 /*&& state&ODS_CHECKED */ && !checkflag)
      {
        MENUITEMINFO info = {0};
        info.cbSize = sizeof(info);
        info.fMask = MIIM_CHECKMARKS;

        ::GetMenuItemInfo(HWndToHMenu(lpDIS->hwndItem),lpDIS->itemID,MF_BYCOMMAND, &info);

        if(state&ODS_CHECKED || info.hbmpUnchecked)
        {
          CRect rect = RectIcon;
          if(nFlags&MFT_RIGHTORDER)
          {
            rect.InflateRect (-2,-1,-1,-1);
          }
          else
          {
          rect.InflateRect (-1,-1,-2,-1);
          }
          // draw the color behind checkmarks
          if(state&ODS_SELECTED)
          {
            pDC->FillSolidRect(rect,colorCheckSel);
          }
          else
          {
            pDC->FillSolidRect(rect,colorCheck);
          }
          CPen* pOldPen = pDC->SelectObject(&Pen);
          CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(HOLLOW_BRUSH);

          pDC->Rectangle(rect);

          pDC->SelectObject(pOldBrush);
          pDC->SelectObject(pOldPen);
          if (state&ODS_CHECKED)
          {
            CRect rect(RectIcon);
            rect.InflateRect(2,((m_iconY-RectIcon.Height())>>1)+2);

            if (!info.hbmpChecked)
            { // Checkmark
              DrawSpecialCharStyle(pDC,rect,98,state);
            }
            else if(!info.hbmpUnchecked)
            { // Bullet
              DrawSpecialCharStyle(pDC,rect,105,state);
            }
            else
            { // Draw Bitmap
              BITMAP myInfo = {0};
              GetObject((HGDIOBJ)info.hbmpChecked,sizeof(myInfo),&myInfo);
              CPoint Offset = RectIcon.TopLeft() + CPoint((RectIcon.Width()-myInfo.bmWidth)/2,(RectIcon.Height()-myInfo.bmHeight)/2);
              pDC->DrawState(Offset,CSize(0,0),info.hbmpChecked,DST_BITMAP|DSS_MONO);
            }
          }
          else
          {
            // Draw Bitmap
            BITMAP myInfo = {0};
            GetObject((HGDIOBJ)info.hbmpUnchecked,sizeof(myInfo),&myInfo);
            CPoint Offset = RectIcon.TopLeft() + CPoint((RectIcon.Width()-myInfo.bmWidth)/2,(RectIcon.Height()-myInfo.bmHeight)/2);
            if(state & ODS_DISABLED)
            {
              pDC->DrawState(Offset,CSize(0,0),info.hbmpUnchecked,DST_BITMAP|DSS_MONO|DSS_DISABLED);
            }
            else
            {
              pDC->DrawState(Offset,CSize(0,0),info.hbmpUnchecked,DST_BITMAP|DSS_MONO);
            }
          }
        }
        else if ((lpDIS->itemID&0xffff)>=SC_SIZE && (lpDIS->itemID&0xffff)<=SC_HOTKEY )
        {
          DrawSpecial_WinXP(pDC,RectIcon,lpDIS->itemID,state);
        }
      }
    }
  }
}

void CNewMenu::DrawItem_SpecialStyle (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar)
{
  if(!bIsMenuBar)
  {
    DrawItem_OldStyle(lpDIS,bIsMenuBar);
    return;
  }

  ASSERT(lpDIS != NULL);
  //CNewMemDC memDC(&lpDIS->rcItem,lpDIS->hDC);
  //CDC* pDC = &memDC;
  CDC* pDC = CDC::FromHandle(lpDIS->hDC);

  ASSERT(lpDIS->itemData);
  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpDIS->itemData);

  CRect rect(lpDIS->rcItem);
  //rect.InflateRect(0,-1);

  COLORREF colorBack;
  if(lpDIS->itemState&(ODS_SELECTED|ODS_HOTLIGHT))
  {
    colorBack = GetSysColor(COLOR_HIGHLIGHT);
    SetLastMenuRect(lpDIS->hDC,rect);
  }
  else
  {
    colorBack = GetMenuBarColor();
  }
  pDC->FillSolidRect(rect,colorBack);

  int iOldMode = pDC->SetBkMode( TRANSPARENT);
  CString strText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
  COLORREF crTextColor;
  if(!(lpDIS->itemState & ODS_GRAYED))
  {
    if(lpDIS->itemState&(ODS_SELECTED|ODS_HOTLIGHT))
    {
      crTextColor = GetSysColor(COLOR_HIGHLIGHTTEXT);
    }
    else
    {
      crTextColor = GetSysColor(COLOR_MENUTEXT);
    }
  }
  else
  {
    crTextColor = GetSysColor(COLOR_GRAYTEXT);
  }
  COLORREF oldColor = pDC->SetTextColor(crTextColor);

  CFont fontMenu;
  LOGFONT logFontMenu;

#ifdef _NEW_MENU_USER_FONT
  logFontMenu =  MENU_USER_FONT;
#else
  NONCLIENTMETRICS nm = {0};
  nm.cbSize = sizeof (nm);
  VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
  logFontMenu =  nm.lfMenuFont;
#endif
  if(lpDIS->itemState&ODS_DRAW_VERTICAL)
  {
    // rotate font 90?
    logFontMenu.lfOrientation = -900;
    logFontMenu.lfEscapement = -900;
  }
  fontMenu.CreateFontIndirect (&logFontMenu);

  CFont* pOldFont = pDC->SelectObject(&fontMenu);
  UINT dt_Hide = (lpDIS->itemState & ODS_NOACCEL)?DT_HIDEPREFIX:0;
  if(dt_Hide && g_Shell>=Win2000)
  {
    BOOL bMenuUnderlines = TRUE;
    if(SystemParametersInfo( SPI_GETKEYBOARDCUES,0,&bMenuUnderlines,0)==TRUE && bMenuUnderlines==TRUE)
    {
      // do not hide
      dt_Hide = 0;
    }
  }
  MenuDrawText(pDC->m_hDC,strText,-1,rect,DT_CENTER|DT_SINGLELINE|DT_VCENTER|dt_Hide);
  pDC->SelectObject(pOldFont);

  pDC->SetTextColor(oldColor);
  pDC->SetBkMode( iOldMode);
}

void CNewMenu::DrawItem_Icy(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar)
{
  ASSERT(lpDIS != NULL);
  CRect rect;

  ASSERT(lpDIS->itemData);
  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpDIS->itemData);

  UINT nFlags = pMenuData->m_nFlags;
  CNewMemDC memDC(&lpDIS->rcItem,lpDIS->hDC);
  CDC* pDC;
  if( bIsMenuBar || (nFlags&MF_SEPARATOR) )
  { // For title and menubardrawing disable memory painting
    memDC.DoCancel();
    pDC = CDC::FromHandle(lpDIS->hDC);
  }
  else
  {
    pDC = &memDC;
  }

  COLORREF colorMenu = GetMenuColor();
  COLORREF colorBack = bIsMenuBar?GetMenuBarColor():colorMenu;
  COLORREF color3DShadow = DarkenColor(60,colorMenu);
  COLORREF color3DHilight = LightenColor(60,colorMenu);
  COLORREF colorGrayText = DarkenColor(100,colorMenu);//GetSysColor(COLOR_GRAYTEXT);
  COLORREF colorHilight = GetSysColor(COLOR_HIGHLIGHT);
  COLORREF colorGrayed = bHighContrast?GetSysColor(COLOR_BTNSHADOW):pDC->GetNearestColor(DarkenColor(70,color3DShadow));

  if(bHighContrast)
  {
    color3DShadow = GetSysColor(COLOR_BTNTEXT);
    color3DHilight = GetSysColor(COLOR_BTNTEXT);
  }

  CRect RectIcon(lpDIS->rcItem);
  CRect RectText(lpDIS->rcItem);
  CRect RectSel(lpDIS->rcItem);

  RectIcon.InflateRect (-1,0,0,0);
  RectText.InflateRect (-1,0,0,0);
  RectSel.InflateRect (0,0,0,0);

  if(!bIsMenuBar)
  {
    if(nFlags&MFT_RIGHTORDER)
    {
      RectIcon.left = RectIcon.right - (m_iconX + 6 + GAP);
      RectText.right  = RectIcon.left;
    }
    else
    {
      RectIcon.right = RectIcon.left + m_iconX + 6 + GAP;
      RectText.left  = RectIcon.right;
    }
  }
  else
  {
    RectText.right += 6;
    RectSel.InflateRect(0,0,-1,-1);
    RectText.InflateRect (1,-2,0,0);

    if(!IsMenu(UIntToHMenu(lpDIS->itemID)) && (lpDIS->itemState&ODS_SELECTED_OPEN))
    {
      lpDIS->itemState = (lpDIS->itemState&~(ODS_SELECTED|ODS_SELECTED_OPEN))|ODS_HOTLIGHT;
    }
    else if(!(lpDIS->itemState&ODS_SELECTED_OPEN) && !m_dwOpenMenu && lpDIS->itemState&ODS_SELECTED)
    {
      lpDIS->itemState = (lpDIS->itemState&~ODS_SELECTED)|ODS_HOTLIGHT;
    }
    if(lpDIS->itemState&(ODS_SELECTED|ODS_HOTLIGHT))
    {
      SetLastMenuRect(lpDIS->hDC,RectSel);
    }
  }

  // For keyboard navigation only
  BOOL bDrawSmallSelection = FALSE;

  // remove the selected bit if it's grayed out
  if( (lpDIS->itemState&ODS_GRAYED) && !m_bSelectDisable )
  {
    if(lpDIS->itemState & ODS_SELECTED)
    {
      lpDIS->itemState &= ~ODS_SELECTED;
      DWORD MsgPos = ::GetMessagePos();
      if(MsgPos==CNewMenuHook::m_dwMsgPos)
      {
        bDrawSmallSelection = TRUE;
      }
      else
      {
        CNewMenuHook::m_dwMsgPos = MsgPos;
      }
    }
  }

  if(nFlags & MF_SEPARATOR)
  {
    if(pMenuData->m_nTitleFlags&MFT_TITLE)
    {
      DrawTitle(lpDIS,bIsMenuBar);
    }
    else
    {
      rect = lpDIS->rcItem;
      //pDC->FillSolidRect(rect,colorBack);
      pDC->FillSolidRect(rect,color3DHilight);
      rect.left += 1;
      rect.right -= 1;
      pDC->DrawEdge(&rect,EDGE_ETCHED,BF_TOP);
    }
  }
  else
  {
    CRect rect2;
    BOOL standardflag=FALSE,selectedflag=FALSE,disableflag=FALSE;
    BOOL checkflag=FALSE;

    CBrush m_brSelect;
    int nIconNormal=-1;

    // set some colors and the font
    m_brSelect.CreateSolidBrush(colorHilight);
    rect2=rect=RectSel;

    // draw the up/down/focused/disabled state
    UINT state = lpDIS->itemState;

    nIconNormal = pMenuData->m_nMenuIconOffset;

    if( (state&ODS_CHECKED) && nIconNormal<0)
    {
      if(state&ODS_SELECTED && m_selectcheck>0)
      {
        checkflag = TRUE;
      }
      else if(m_unselectcheck>0)
      {
        checkflag = TRUE;
      }
    }
    else if(nIconNormal != -1)
    {
      standardflag = TRUE;
      if(state&ODS_SELECTED && !(state&ODS_GRAYED))
      {
        selectedflag=TRUE;
      }
      else if(state&ODS_GRAYED)
      {
        disableflag=TRUE;
      }
    }

    if(bIsMenuBar)
    {
      CRect tempRect = rect;
      tempRect.InflateRect (0,0,0,1);
      rect.OffsetRect(0,1);
      rect2=rect;

      if( bHighContrast || (state&ODS_INACTIVE) || (!(state&ODS_HOTLIGHT) && !(state&ODS_SELECTED)) )
      {
        // pDC->FillSolidRect(tempRect,colorBack);
        MENUINFO menuInfo = {0};
        menuInfo.cbSize = sizeof(menuInfo);
        menuInfo.fMask = MIM_BACKGROUND;

        if(!bHighContrast && ::GetMenuInfo(m_hMenu,&menuInfo) && menuInfo.hbrBack)
        {
          CBrush *pBrush = CBrush::FromHandle(menuInfo.hbrBack);
          VERIFY(pBrush->UnrealizeObject());
          CPoint oldOrg = pDC->SetBrushOrg(0,0);
          pDC->FillRect(tempRect,pBrush);
          pDC->SetBrushOrg(oldOrg);
        }
        else
        {
          pDC->FillSolidRect(tempRect,colorBack);
        }
      }
      else
      {
        colorBack = GetMenuColor();
        DrawGradient(pDC,tempRect,LightenColor(30,colorBack),DarkenColor(30,colorBack),false,true);
      }
    }
    else
    {
      if(bHighContrast)
      {
        pDC->FillSolidRect (rect,colorBack);
      }
      else
      {
        DrawGradient(pDC,rect,LightenColor(30,colorBack),DarkenColor(30,colorBack),false,true);
      }
    }
    // Draw the selection
    if(state&ODS_SELECTED)
    {
      // You need only Text highlight and that's what you get
      if(!bIsMenuBar)
      {
        if(checkflag||standardflag||selectedflag||disableflag||state&ODS_CHECKED)
        {
          rect2 = RectText;
        }

        if(bHighContrast)
        {
          pDC->FillSolidRect (rect2,colorHilight);
        }
        else
        {
          DrawGradient(pDC,rect2,LightenColor(30,colorHilight),DarkenColor(30,colorHilight),false,true);
        }
        pDC->Draw3dRect(rect2 ,color3DShadow,color3DHilight);
      }
      else
      {
        pDC->Draw3dRect(rect2 ,color3DShadow,color3DHilight);
      }
    }
    else if(bIsMenuBar && (state&ODS_HOTLIGHT) && !(state&ODS_INACTIVE))
    {
      pDC->Draw3dRect(rect,color3DHilight,color3DShadow);
    }
    else if (bDrawSmallSelection)
    {
      pDC->DrawFocusRect(rect);
    }

    // Draw the Bitmap or checkmarks
    if(!bIsMenuBar)
    {
      CRect IconRect = RectIcon;
      // center the image
      IconRect.InflateRect(-(RectIcon.Width()-m_iconX)>>1,-(RectIcon.Height()-m_iconY)>>1);
      CPoint ptImage = IconRect.TopLeft();
      IconRect.InflateRect(2,2);

      if(checkflag||standardflag||selectedflag||disableflag)
      {
        if(checkflag && m_checkmaps)
        {
          if(state&ODS_SELECTED)
          {
            m_checkmaps->Draw(pDC,1,ptImage,ILD_TRANSPARENT);
          }
          else
          {
            m_checkmaps->Draw(pDC,0,ptImage,ILD_TRANSPARENT);
          }
        }
        else
        {
          // Need to draw the checked state
          if (IsNewShell())
          {
            if(state&ODS_CHECKED)
            {
              pDC->Draw3dRect(IconRect,color3DShadow,color3DHilight);
            }
            else if (selectedflag)
            {
              pDC->Draw3dRect(IconRect,color3DHilight,color3DShadow);
            }
          }

          CSize size = pMenuData->m_pMenuIcon->GetIconSize();
          // Correcting of a smaler icon
          if(size.cx<m_iconX)
          {
            ptImage.x += (m_iconX-size.cx)>>1;
          }
          if(size.cy<m_iconY)
          {
            ptImage.y += (m_iconY-size.cy)>>1;
          }

          HICON hDrawIcon = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset);
          if(state & ODS_DISABLED)
          {
            CBrush Brush;
            Brush.CreateSolidBrush(colorGrayed);
            pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL | DSS_MONO, (HBRUSH)Brush);
          }
          else
          {
            pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL, (HBRUSH)NULL);
          }
          DestroyIcon(hDrawIcon);
        }
      }
      if ((lpDIS->itemID&0xffff)>=SC_SIZE && (lpDIS->itemID&0xffff)<=SC_HOTKEY )
      {
        DrawSpecial_OldStyle(pDC,IconRect,lpDIS->itemID,state);
      }
      else if(nIconNormal<0 /*&& state&ODS_CHECKED */&& !checkflag)
      {
        MENUITEMINFO info = {0};
        info.cbSize = sizeof(info);
        info.fMask = MIIM_CHECKMARKS;

        ::GetMenuItemInfo(HWndToHMenu(lpDIS->hwndItem),lpDIS->itemID,MF_BYCOMMAND, &info);

        Draw3DCheckmark(pDC, IconRect,info.hbmpChecked,info.hbmpUnchecked,state);
      }
    }


    CString strText;
    strText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
    if(!strText.IsEmpty())
    {
      COLORREF crText = GetSysColor(COLOR_MENUTEXT);

      if(bIsMenuBar)
      {
        rect.left += 6;
        if(lpDIS->itemState&ODS_INACTIVE)
        {
          crText = colorGrayText;
        }
      }
      else
      {
        if(lpDIS->itemState&ODS_SELECTED)
        {
          crText = GetSysColor(COLOR_HIGHLIGHTTEXT);
        }
        rect.left += m_iconX + 12;
      }
      CRect rectt(rect.left,rect.top-1,rect.right,rect.bottom-1);

      // Find tabs
      CString leftStr,rightStr;
      leftStr.Empty();rightStr.Empty();

      int tablocr = strText.ReverseFind(_T('\t'));
      if(tablocr!=-1)
      {
        rightStr = strText.Mid(tablocr+1);
        leftStr = strText.Left(strText.Find(_T('\t')));
        rectt.right -= m_iconX;
      }
      else
      {
        leftStr = strText;
      }

      int iOldMode = pDC->SetBkMode( TRANSPARENT);
      // Draw the text in the correct colour:
      UINT dt_Hide = (lpDIS->itemState & ODS_NOACCEL)?DT_HIDEPREFIX:0;
      if(dt_Hide && g_Shell>=Win2000)
      {
        BOOL bMenuUnderlines = TRUE;
        if(SystemParametersInfo( SPI_GETKEYBOARDCUES,0,&bMenuUnderlines,0)==TRUE && bMenuUnderlines==TRUE)
        {
          // do not hide
          dt_Hide = 0;
        }
      }

      UINT nFormat  = DT_LEFT|DT_SINGLELINE|DT_VCENTER|dt_Hide;
      UINT nFormatr = DT_RIGHT|DT_SINGLELINE|DT_VCENTER|dt_Hide;
      if(nFlags&MFT_RIGHTORDER)
      {
        nFormat  = DT_RIGHT| DT_SINGLELINE|DT_VCENTER|DT_RTLREADING|dt_Hide;
        nFormatr = DT_LEFT|DT_SINGLELINE|DT_VCENTER|dt_Hide;
      }

      if(bIsMenuBar)
      {
        rectt = RectSel;
        rectt.OffsetRect(-1,0);
        if(state & ODS_SELECTED)
        {
          rectt.OffsetRect(1,1);
        }
        nFormat = DT_CENTER|DT_SINGLELINE|DT_VCENTER|dt_Hide;
      }
      else
      {
        if(nFlags&MFT_RIGHTORDER)
        {
          RectText.left += 15;
          RectText.right -= 4;
        }
        else
        {
          RectText.left += 4;
          RectText.right -= 15;
        }
      }

      CFont fontMenu;
      LOGFONT logFontMenu;

#ifdef _NEW_MENU_USER_FONT
      logFontMenu =  MENU_USER_FONT;
#else
      NONCLIENTMETRICS nm = {0};
      nm.cbSize = sizeof (nm);
      VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
      logFontMenu =  nm.lfMenuFont;
#endif

      // Default selection?
      if(state&ODS_DEFAULT)
      {
        // Make the font bold
        logFontMenu.lfWeight = FW_BOLD;
      }
      if(state&ODS_DRAW_VERTICAL)
      {
        // rotate font 90?
        logFontMenu.lfOrientation = -900;
        logFontMenu.lfEscapement = -900;
      }

      fontMenu.CreateFontIndirect (&logFontMenu);
      CFont* pOldFont = pDC->SelectObject(&fontMenu);

      if(!(lpDIS->itemState & ODS_GRAYED))
      {
        pDC->SetTextColor(crText);
        if(bIsMenuBar)
        {
          MenuDrawText(pDC->m_hDC,leftStr,-1,RectText,nFormat);
          if(tablocr!=-1)
          {
            MenuDrawText(pDC->m_hDC,rightStr,-1,RectText,nFormatr);
          }
        }
        else
        {
          pDC->DrawText (leftStr,RectText,nFormat);
          if(tablocr!=-1)
          {
            pDC->DrawText (rightStr,RectText,nFormatr);
          }
        }
      }
      else
      {
        // Draw the disabled text
        if(!(state & ODS_SELECTED))
        {
          CRect offset = RectText;
          offset.OffsetRect (1,1);

          pDC->SetTextColor(colorGrayed);
          pDC->DrawText(leftStr,RectText, nFormat);
          if(tablocr!=-1)
          {
            pDC->DrawText(rightStr,RectText,nFormatr);
          }
        }
        else
        {
          // And the standard Grey text:
          pDC->SetTextColor(colorBack);
          pDC->DrawText(leftStr,RectText, nFormat);
          if(tablocr!=-1)
          {
            pDC->DrawText (rightStr,RectText,nFormatr);
          }
        }
      }
      pDC->SelectObject(pOldFont);
      pDC->SetBkMode( iOldMode );
    }
    m_brSelect.DeleteObject();
  }
}

void CNewMenu::DrawItem_OldStyle (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar)
{
  ASSERT(lpDIS != NULL);
  CRect rect;

  ASSERT(lpDIS->itemData);
  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpDIS->itemData);

  UINT nFlags = pMenuData->m_nFlags;

  CNewMemDC memDC(&lpDIS->rcItem,lpDIS->hDC);
  CDC* pDC;
  if( bIsMenuBar || (nFlags&MF_SEPARATOR) )
  { // For title and menubardrawing disable memory painting
    memDC.DoCancel();
    pDC = CDC::FromHandle(lpDIS->hDC);
  }
  else
  {
    pDC = &memDC;
  }

  COLORREF colorBack = bIsMenuBar?GetMenuBarColor():GetSysColor(COLOR_MENU);

  CRect RectIcon(lpDIS->rcItem);
  CRect RectText(lpDIS->rcItem);
  CRect RectSel(lpDIS->rcItem);

  RectIcon.InflateRect (-1,0,0,0);
  RectText.InflateRect (-1,0,0,0);
  RectSel.InflateRect (0,0,0,0);

  if(!bIsMenuBar)
  {
    if(nFlags&MFT_RIGHTORDER)
    {
      RectIcon.left = RectIcon.right - (m_iconX + 6 + GAP);
      RectText.right  = RectIcon.left;
    }
    else
    {
      RectIcon.right = RectIcon.left + m_iconX + 6 + GAP;
      RectText.left  = RectIcon.right;
    }
  }
  else
  {
    RectText.right += 6;
    RectText.InflateRect (1,0,0,0);
    RectSel.InflateRect (0,0,-2,0);
    RectSel.OffsetRect(1,-1);

#ifdef _TRACE_MENU_
    //   AfxTrace(_T("BarState: 0x%lX Menus %ld\n"),lpDIS->itemState,m_dwOpenMenu);
#endif
    if(!IsMenu(UIntToHMenu(lpDIS->itemID)) && (lpDIS->itemState&ODS_SELECTED_OPEN))
    {
      lpDIS->itemState = (lpDIS->itemState&~(ODS_SELECTED|ODS_SELECTED_OPEN))|ODS_HOTLIGHT;
    }
    else if( !(lpDIS->itemState&ODS_SELECTED_OPEN) && !m_dwOpenMenu && lpDIS->itemState&ODS_SELECTED)
    {
      lpDIS->itemState = (lpDIS->itemState&~ODS_SELECTED)|ODS_HOTLIGHT;
    }

    if(lpDIS->itemState&(ODS_SELECTED|ODS_HOTLIGHT))
    {
      SetLastMenuRect(lpDIS->hDC,RectSel);
    }
  }

  // For keyboard navigation only
  BOOL bDrawSmallSelection = FALSE;

  // remove the selected bit if it's grayed out
  if( (lpDIS->itemState&ODS_GRAYED) && !m_bSelectDisable )
  {
    if(lpDIS->itemState & ODS_SELECTED)
    {
      lpDIS->itemState &= ~ODS_SELECTED;
      DWORD MsgPos = ::GetMessagePos();
      if(MsgPos==CNewMenuHook::m_dwMsgPos)
      {
        bDrawSmallSelection = TRUE;
      }
      else
      {
        CNewMenuHook::m_dwMsgPos = MsgPos;
      }
    }
  }

  if(nFlags & MF_SEPARATOR)
  {
    if(pMenuData->m_nTitleFlags&MFT_TITLE)
    {
      DrawTitle(lpDIS,bIsMenuBar);
    }
    else
    {
      rect = lpDIS->rcItem;
      pDC->FillSolidRect(rect,colorBack);
      rect.left += 1;
      rect.top += 1;
      pDC->DrawEdge(&rect,EDGE_ETCHED,BF_TOP);
    }
  }
  else
  {
    CRect rect2;
    BOOL standardflag=FALSE,selectedflag=FALSE,disableflag=FALSE;
    BOOL checkflag=FALSE;

    CBrush m_brSelect;
    int nIconNormal=-1;
    //CImageList *bitmap=NULL;

    // set some colors and the font
    m_brSelect.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));

    // draw the colored rectangle portion
    rect2=rect=RectSel;

    // draw the up/down/focused/disabled state
    UINT state = lpDIS->itemState;

    nIconNormal = pMenuData->m_nMenuIconOffset;

    if( (state&ODS_CHECKED) && nIconNormal<0)
    {
      if(state&ODS_SELECTED && m_selectcheck>0)
      {
        checkflag = TRUE;
      }
      else if(m_unselectcheck>0)
      {
        checkflag = TRUE;
      }
    }
    else if(nIconNormal != -1)
    {
      standardflag=TRUE;
      if(state&ODS_SELECTED && !(state&ODS_GRAYED))
      {
        selectedflag = TRUE;
      }
      else if(state&ODS_GRAYED)
      {
        disableflag = TRUE;
      }
    }

    if(bIsMenuBar)
    {
      //rect.InflateRect (1,0,0,0);
      rect.OffsetRect(-1,1);
      rect2=rect;
      rect.right +=2;
      pDC->FillSolidRect (rect,colorBack);
      rect.right -=2;
    }
    else
    {
      // Draw the background
      pDC->FillSolidRect (rect,colorBack);
    }
    // Draw the selection
    if(state&ODS_SELECTED)
    {
      // You need only Text highlight and that's what you get
      if(!bIsMenuBar)
      {
        if(checkflag||standardflag||selectedflag||disableflag||state&ODS_CHECKED)
        {
          rect2 = RectText;
        }
        pDC->FillRect(rect2,&m_brSelect);
      }
      else
      {
        pDC->Draw3dRect(rect ,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
      }
    }
    else if(bIsMenuBar && (state&ODS_HOTLIGHT) && !(state&ODS_INACTIVE))
    {
      pDC->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
    }
    else if (bDrawSmallSelection)
    {
      pDC->DrawFocusRect(rect);
    }

    // Draw the Bitmap or checkmarks
    if(!bIsMenuBar)
    {
      CRect IconRect = RectIcon;
      // center the image
      IconRect.InflateRect(-(RectIcon.Width()-m_iconX)>>1,-(RectIcon.Height()-m_iconY)>>1);
      CPoint ptImage = IconRect.TopLeft();
      IconRect.InflateRect(2,2);

      if(checkflag||standardflag||selectedflag||disableflag)
      {
        if(checkflag && m_checkmaps)
        {
          if(state&ODS_SELECTED)
          {
            m_checkmaps->Draw(pDC,1,ptImage,ILD_TRANSPARENT);
          }
          else
          {
            m_checkmaps->Draw(pDC,0,ptImage,ILD_TRANSPARENT);
          }
        }
        else
        {
          // Need to draw the checked state
          if (IsNewShell())
          {
            if(state&ODS_CHECKED)
            {
              pDC->Draw3dRect(IconRect,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DHILIGHT));
            }
            else if (selectedflag)
            {
              pDC->Draw3dRect(IconRect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_3DSHADOW));
            }
          }

          CSize size = pMenuData->m_pMenuIcon->GetIconSize();
          // Correcting of a smaler icon
          if(size.cx<m_iconX)
          {
            ptImage.x += (m_iconX-size.cx)>>1;
          }
          if(size.cy<m_iconY)
          {
            ptImage.y += (m_iconY-size.cy)>>1;
          }

          HICON hDrawIcon = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset);
          if(state & ODS_DISABLED)
          {
            // Jan-19-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
            // opted to use blended disabled icons instead, the default is just too bad to think about using
            HICON hDrawIcon2 = pMenuData->m_pMenuIcon->m_IconsList.ExtractIcon(pMenuData->m_nMenuIconOffset+2);
            pDC->DrawState(ptImage, size, hDrawIcon2, DSS_NORMAL,(HBRUSH)NULL);
            DestroyIcon(hDrawIcon2);
//          pDC->DrawState(ptImage, size, hDrawIcon, DSS_DISABLED, (HBRUSH)NULL);
          }
          else
          {
            pDC->DrawState(ptImage, size, hDrawIcon, DSS_NORMAL, (HBRUSH)NULL);
          }
          DestroyIcon(hDrawIcon);
        }
      }
      if ((lpDIS->itemID&0xffff)>=SC_SIZE && (lpDIS->itemID&0xffff)<=SC_HOTKEY )
      {
        DrawSpecial_OldStyle(pDC,IconRect,lpDIS->itemID,state);
      }
      else if(nIconNormal<0 /*&& state&ODS_CHECKED */ && !checkflag)
      {
        MENUITEMINFO info = {0};
        info.cbSize = sizeof(info);
        info.fMask = MIIM_CHECKMARKS;

        ::GetMenuItemInfo(HWndToHMenu(lpDIS->hwndItem),lpDIS->itemID,MF_BYCOMMAND, &info);
        Draw3DCheckmark(pDC, IconRect,info.hbmpChecked,info.hbmpUnchecked,state);
      }
    }

    CString strText;
    strText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
    if(!strText.IsEmpty())
    {
      COLORREF crText = GetSysColor(COLOR_MENUTEXT);

      if(bIsMenuBar)
      {
        if(lpDIS->itemState&ODS_INACTIVE)
          crText = GetSysColor(COLOR_GRAYTEXT);
      }
      else
      {
        if(lpDIS->itemState&ODS_SELECTED)
        {
          crText = GetSysColor(COLOR_HIGHLIGHTTEXT);
        }
      }
      // Find tabs
      CString leftStr,rightStr;
      leftStr.Empty();rightStr.Empty();

      int tablocr = strText.ReverseFind(_T('\t'));
      if(tablocr!=-1)
      {
        rightStr = strText.Mid(tablocr+1);
        leftStr = strText.Left(strText.Find(_T('\t')));
      }
      else
      {
        leftStr = strText;
      }

      int iOldMode = pDC->SetBkMode( TRANSPARENT);
      // Draw the text in the correct colour:
      UINT dt_Hide = (lpDIS->itemState & ODS_NOACCEL)?DT_HIDEPREFIX:0;
      if(dt_Hide && g_Shell>=Win2000)
      {
        BOOL bMenuUnderlines = TRUE;
        if(SystemParametersInfo( SPI_GETKEYBOARDCUES,0,&bMenuUnderlines,0)==TRUE && bMenuUnderlines==TRUE)
        {
          // do not hide
          dt_Hide = 0;
        }
      }
      UINT nFormat  = DT_LEFT|DT_SINGLELINE|DT_VCENTER|dt_Hide;
      UINT nFormatr = DT_RIGHT|DT_SINGLELINE|DT_VCENTER|dt_Hide;
      if(nFlags&MFT_RIGHTORDER)
      {
        nFormat  = DT_RIGHT| DT_SINGLELINE|DT_VCENTER|DT_RTLREADING|dt_Hide;
        nFormatr = DT_LEFT|DT_SINGLELINE|DT_VCENTER|dt_Hide;
      }

      if(bIsMenuBar)
      {
        if(state & ODS_SELECTED)
        {
          RectText.OffsetRect(1,1);
        }
        nFormat = DT_CENTER|DT_SINGLELINE|DT_VCENTER|dt_Hide;
      }
      else
      {
        if(nFlags&MFT_RIGHTORDER)
        {
          RectText.left += 15;
          RectText.right -= 4;
        }
        else
        {
          RectText.left += 4;
          RectText.right -= 15;
        }
      }
      CFont fontMenu;
      LOGFONT logFontMenu;

#ifdef _NEW_MENU_USER_FONT
      logFontMenu =  MENU_USER_FONT;
#else
      NONCLIENTMETRICS nm = {0};
      nm.cbSize = sizeof (nm);
      VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
      logFontMenu =  nm.lfMenuFont;
#endif

      // Default selection?
      if(state&ODS_DEFAULT)
      {
        // Make the font bold
        logFontMenu.lfWeight = FW_BOLD;
      }
      if(state&ODS_DRAW_VERTICAL)
      {
        // rotate font 90?
        logFontMenu.lfOrientation = -900;
        logFontMenu.lfEscapement = -900;
      }

      fontMenu.CreateFontIndirect (&logFontMenu);
      CFont* pOldFont = pDC->SelectObject(&fontMenu);

      if(!(lpDIS->itemState & ODS_GRAYED))
      {
        pDC->SetTextColor(crText);
        if(bIsMenuBar)
        {
          MenuDrawText(pDC->m_hDC,leftStr,-1,RectText,nFormat);
          if(tablocr!=-1)
          {
            MenuDrawText(pDC->m_hDC,rightStr,-1,RectText,nFormatr);
          }
        }
        else
        {
          pDC->DrawText (leftStr,RectText,nFormat);
          if(tablocr!=-1)
          {
            pDC->DrawText (rightStr,RectText,nFormatr);
          }
        }
      }
      else
      {
        // Draw the disabled text
        if(!(state & ODS_SELECTED))
        {
          CRect offset = RectText;
          offset.OffsetRect (1,1);

          pDC->SetTextColor(GetSysColor(COLOR_BTNHILIGHT));
          pDC->DrawText(leftStr,&offset, nFormat);
          if(tablocr!=-1)
          {
            pDC->DrawText (rightStr,&offset,nFormatr);
          }

          pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
          pDC->DrawText(leftStr,RectText, nFormat);
          if(tablocr!=-1)
          {
            pDC->DrawText(rightStr,RectText,nFormatr);
          }
        }
        else
        {
          // And the standard Grey text:
          pDC->SetTextColor(colorBack);
          pDC->DrawText(leftStr,RectText, nFormat);
          if(tablocr!=-1)
          {
            pDC->DrawText (rightStr,RectText,nFormatr);
          }
        }
      }
      pDC->SelectObject(pOldFont);
      pDC->SetBkMode( iOldMode );
    }
    m_brSelect.DeleteObject();
  }
}

BOOL CNewMenu::IsMenuBar(HMENU hMenu)
{
  BOOL bIsMenuBar = FALSE;
  if(!FindMenuItem(HMenuToUInt(hMenu)))
  {
    if(m_hParentMenu==NULL)
    {
      return m_bIsPopupMenu?FALSE:TRUE;
    }
    CNewMenu* pMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(m_hParentMenu));
    if (pMenu!=NULL)
    {
      return pMenu->m_bIsPopupMenu?FALSE:TRUE;
    }
  }
  else
  {
    // Test for only one item not bar
    bIsMenuBar = m_hParentMenu ? FALSE: ((m_bIsPopupMenu)?FALSE:TRUE);
  }
  return bIsMenuBar;
}

/*
==========================================================================
void CNewMenu::MeasureItem(LPMEASUREITEMSTRUCT)
---------------------------------------------

Called by the framework when it wants to know what the width and height
of our item will be.  To accomplish this we provide the width of the
icon plus the width of the menu text, and then the height of the icon.

==========================================================================
*/
void CNewMenu::MeasureItem_OldStyle( LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenuBar )
{
  ASSERT(lpMIS->itemData);
  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpMIS->itemData);

  UINT state = pMenuData->m_nFlags;
  if(state & MF_SEPARATOR)
  {
    if(pMenuData->m_nTitleFlags&MFT_TITLE)
    {
      SIZE size = {0,0};
      {// We need this sub-block for releasing the dc
        // DC of the desktop
        CClientDC myDC(NULL);

        CFont font;
        LOGFONT MyFont = m_MenuTitleFont;
        MyFont.lfOrientation = 0;
        MyFont.lfEscapement = 0;
        font.CreateFontIndirect(&MyFont);

        CFont* pOldFont = myDC.SelectObject (&font);
        CString lpstrText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
        VERIFY(::GetTextExtentPoint32(myDC.m_hDC,lpstrText,(int)_tcslen(lpstrText),&size));
        // Select old font in
        myDC.SelectObject(pOldFont);
      } // We need this sub-block for releasing the dc

      CSize iconSize(0,0);
      if(pMenuData->m_nMenuIconOffset!=(-1) && pMenuData->m_pMenuIcon)
      {
        iconSize = pMenuData->m_pMenuIcon->GetIconSize();
        if(iconSize!=CSize(0,0))
        {
          iconSize += CSize(2,2);
        }
      }

      if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
      {
        if(bWine)
        {
          lpMIS->itemWidth = max(size.cy,iconSize.cx);
        }
        else
        {
          lpMIS->itemWidth = max(size.cy,iconSize.cx) - GetSystemMetrics(SM_CXMENUCHECK);
        }
        // Don't make the menu higher than menuitems in it
        lpMIS->itemHeight = 0;
        if(pMenuData->m_nTitleFlags&MFT_LINE)
        {
          lpMIS->itemWidth += 8;
        }
        else if(pMenuData->m_nTitleFlags&MFT_ROUND)
        {
          lpMIS->itemWidth += 4;
        }
      }
      else
      {
        lpMIS->itemWidth = size.cx + iconSize.cx;
        lpMIS->itemHeight = max(size.cy,iconSize.cy);
        if(pMenuData->m_nTitleFlags&MFT_LINE)
        {
          lpMIS->itemHeight += 8;
        }
      }
    }
    else
    {
      lpMIS->itemHeight = 3;
      lpMIS->itemWidth = 3;
    }
  }
  else
  {
    //Get pointer to text SK
    CString itemText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
    SIZE size = {0,0};

    {// We need this sub-block for releasing the dc
      CFont fontMenu;
      LOGFONT logFontMenu;

  #ifdef _NEW_MENU_USER_FONT
      logFontMenu =  MENU_USER_FONT;
  #else
      NONCLIENTMETRICS nm = {0};
      nm.cbSize = sizeof (nm);
      VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
      logFontMenu =  nm.lfMenuFont;
  #endif

      // Default selection?
      if(GetDefaultItem(0, FALSE) == pMenuData->m_nID)
      {
        // Make the font bold
        logFontMenu.lfWeight = FW_BOLD;
      }
      fontMenu.CreateFontIndirect (&logFontMenu);

      // DC of the desktop
      CClientDC myDC(NULL);
      // Select menu font in...
      CFont* pOldFont = myDC.SelectObject (&fontMenu);
      VERIFY(::GetTextExtentPoint32(myDC.m_hDC,itemText,itemText.GetLength(),&size));
      // Select old font in
      myDC.SelectObject(pOldFont);
    } // We need this sub-block for releasing the dc


    // Set width and height:
    if(bIsMenuBar)
    {
      if(itemText.Find(_T("&"))>=0)
      {
        lpMIS->itemWidth = size.cx - GetSystemMetrics(SM_CXMENUCHECK)/2;
      }
      else
      {
        lpMIS->itemWidth = size.cx;
      }
    }
    else
    {
      lpMIS->itemWidth = m_iconX + size.cx + m_iconX + GAP;
    }

    int temp = GetSystemMetrics(SM_CYMENU);
    lpMIS->itemHeight = (temp>(m_iconY+4)) ? temp : (m_iconY+4);
    if(lpMIS->itemHeight<((UINT)size.cy) )
    {
      lpMIS->itemHeight=((UINT)size.cy);
    }

    // set status bar as appropriate
    UINT nItemID = (lpMIS->itemID & 0xFFF0);
    // Special case for system menu
    if (nItemID>=SC_SIZE && nItemID<=SC_HOTKEY)
    {
      BOOL bGetNext = FALSE;
      // search the actual menu item
      for (int j=0;j<m_MenuItemList.GetUpperBound();++j)
      {
        CNewMenuItemData* pTemp = m_MenuItemList[j];
        if(pTemp==pMenuData || bGetNext==TRUE)
        {
          bGetNext = TRUE;
          pTemp = m_MenuItemList[j+1];
          if(pTemp->m_nID)
          {
            lpMIS->itemData = (ULONG_PTR)pTemp;
            lpMIS->itemID = pTemp->m_nID;
            UINT nOrgWidth = lpMIS->itemWidth;
            MeasureItem_OldStyle(lpMIS,bIsMenuBar);
            // Restore old values
            lpMIS->itemData = (ULONG_PTR)pMenuData;
            lpMIS->itemID = pMenuData->m_nID;
            lpMIS->itemWidth = max(lpMIS->itemWidth,nOrgWidth);
            break;
          }
        }
      }
      lpMIS->itemHeight = temp;
    }
  }
}

void CNewMenu::MeasureItem_Icy( LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenuBar )
{
  ASSERT(lpMIS->itemData);
  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpMIS->itemData);

  UINT state = pMenuData->m_nFlags;
  if(state & MF_SEPARATOR)
  {
    if(pMenuData->m_nTitleFlags&MFT_TITLE)
    {
      SIZE size = {0,0};
      {// We need this sub-block for releasing the dc
        // DC of the desktop
        CClientDC myDC(NULL);

        CFont font;
        LOGFONT MyFont = m_MenuTitleFont;
        MyFont.lfOrientation = 0;
        MyFont.lfEscapement = 0;
        font.CreateFontIndirect(&MyFont);

        CFont* pOldFont = myDC.SelectObject (&font);
        CString lpstrText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
        VERIFY(::GetTextExtentPoint32(myDC.m_hDC,lpstrText,(int)_tcslen(lpstrText),&size));
        // Select old font in
        myDC.SelectObject(pOldFont);
      } // We need this sub-block for releasing the dc

      CSize iconSize(0,0);
      if(pMenuData->m_nMenuIconOffset!=(-1) && pMenuData->m_pMenuIcon)
      {
        iconSize = pMenuData->m_pMenuIcon->GetIconSize();
        if(iconSize!=CSize(0,0))
        {
          iconSize += CSize(2,2);
        }
      }

      if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
      {
        if(bWine)
        {
          lpMIS->itemWidth = max(size.cy,iconSize.cx);
        }
        else
        {
          lpMIS->itemWidth = max(size.cy,iconSize.cx) - GetSystemMetrics(SM_CXMENUCHECK);
        }
        // Don't make the menu higher than menuitems in it
        lpMIS->itemHeight = 0;
        if(pMenuData->m_nTitleFlags&MFT_LINE)
        {
          lpMIS->itemWidth += 8;
        }
        else if(pMenuData->m_nTitleFlags&MFT_ROUND)
        {
          lpMIS->itemWidth += 4;
        }
      }
      else
      {
        lpMIS->itemWidth = size.cx + iconSize.cx;
        lpMIS->itemHeight = max(size.cy,iconSize.cy);
        if(pMenuData->m_nTitleFlags&MFT_LINE)
        {
          lpMIS->itemHeight += 8;
        }
      }
    }
    else
    {
      lpMIS->itemHeight = 3;
      lpMIS->itemWidth = 3;
    }
  }
  else
  {
    //Get pointer to text SK
    CString itemText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
    SIZE size = {0,0};
    {// We need this sub-block for releasing the dc
      LOGFONT logFontMenu;
      CFont fontMenu;

  #ifdef _NEW_MENU_USER_FONT
      logFontMenu =  MENU_USER_FONT;
  #else
      NONCLIENTMETRICS nm = {0};
      nm.cbSize = sizeof (nm);
      VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
      logFontMenu =  nm.lfMenuFont;
  #endif

      // Default selection?
      if(GetDefaultItem(0, FALSE) == pMenuData->m_nID)
      {
        // Make the font bold
        logFontMenu.lfWeight = FW_BOLD;
      }

      fontMenu.CreateFontIndirect (&logFontMenu);

      // DC of the desktop
      CClientDC myDC(NULL);
      // Select menu font in...
      CFont* pOldFont = myDC.SelectObject (&fontMenu);
      // Check the Key-Shortcut replacing for japanise/chinese calculating space
      itemText.Replace(_T("\t"),_T("nnn"));
      VERIFY(::GetTextExtentPoint32(myDC.m_hDC,itemText,itemText.GetLength(),&size));
      // Select old font in
      myDC.SelectObject(pOldFont);
    }// We need this sub-block for releasing the dc

    // Set width and height:
    if(bIsMenuBar)
    {
      if(itemText.Find(_T("&"))>=0)
      {
        lpMIS->itemWidth = size.cx - GetSystemMetrics(SM_CXMENUCHECK)/2;
      }
      else
      {
        lpMIS->itemWidth = size.cx;
      }
    }
    else
    {
      lpMIS->itemWidth = m_iconX + size.cx + m_iconX + GAP;
    }

    int temp = GetSystemMetrics(SM_CYMENU);
    lpMIS->itemHeight = (temp>(m_iconY + 6)) ? temp : (m_iconY+6);
    if(lpMIS->itemHeight<((UINT)size.cy) )
    {
      lpMIS->itemHeight=((UINT)size.cy);
    }

    // set status bar as appropriate
    UINT nItemID = (lpMIS->itemID & 0xFFF0);
    // Special case for system menu
    if (nItemID>=SC_SIZE && nItemID<=SC_HOTKEY)
    {
      BOOL bGetNext = FALSE;
      // search the actual menu item
      for (int j=0;j<m_MenuItemList.GetUpperBound();++j)
      {
        CNewMenuItemData* pTemp = m_MenuItemList[j];
        if(pTemp==pMenuData || bGetNext==TRUE)
        {
          bGetNext = TRUE;
          pTemp = m_MenuItemList[j+1];
          if(pTemp->m_nID)
          {
            lpMIS->itemData = (ULONG_PTR)pTemp;
            lpMIS->itemID = pTemp->m_nID;
            UINT nOrgWidth = lpMIS->itemWidth;
            MeasureItem_Icy(lpMIS,bIsMenuBar);
            // Restore old values
            lpMIS->itemData = (ULONG_PTR)pMenuData;
            lpMIS->itemID = pMenuData->m_nID;
            lpMIS->itemWidth = max(lpMIS->itemWidth,nOrgWidth);
            break;
          }
        }
      }
      lpMIS->itemHeight = temp;
    }
  }
}

void CNewMenu::MeasureItem_WinXP( LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenuBar )
{
  ASSERT(lpMIS->itemData);
  CNewMenuItemData* pMenuData = (CNewMenuItemData*)(lpMIS->itemData);

  UINT nFlag = pMenuData->m_nFlags;
  if(nFlag & MF_SEPARATOR)
  {
    if(pMenuData->m_nTitleFlags&MFT_TITLE)
    {
      SIZE size = {0,0};
      {// We need this sub-block for releasing the dc
        // DC of the desktop
        CClientDC myDC(NULL);

        CFont font;
        LOGFONT MyFont = m_MenuTitleFont;
        MyFont.lfOrientation = 0;
        MyFont.lfEscapement = 0;
        font.CreateFontIndirect(&MyFont);

        CFont* pOldFont = myDC.SelectObject (&font);
        CString lpstrText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
        VERIFY(::GetTextExtentPoint32(myDC.m_hDC,lpstrText,(int)_tcslen(lpstrText),&size));
        // Select old font in
        myDC.SelectObject(pOldFont);
      }

      CSize iconSize(0,0);
      if(pMenuData->m_nMenuIconOffset!=(-1) && pMenuData->m_pMenuIcon)
      {
        iconSize = pMenuData->m_pMenuIcon->GetIconSize();
        if(iconSize!=CSize(0,0))
        {
          iconSize += CSize(2,2);
        }
      }

      if(pMenuData->m_nTitleFlags&MFT_SIDE_TITLE)
      {
        if(bWine)
        {
          lpMIS->itemWidth = max(size.cy,iconSize.cx);
        }
        else
        {
          lpMIS->itemWidth = max(size.cy,iconSize.cx) - GetSystemMetrics(SM_CXMENUCHECK);
        }
        // Don't make the menu higher than menuitems in it
        lpMIS->itemHeight = 0;
        if(pMenuData->m_nTitleFlags&MFT_LINE)
        {
          lpMIS->itemWidth += 8;
        }
        else if(pMenuData->m_nTitleFlags&MFT_ROUND)
        {
          lpMIS->itemWidth += 4;
        }
      }
      else
      {
        lpMIS->itemWidth = size.cx + iconSize.cx;
        lpMIS->itemHeight = max(size.cy,iconSize.cy);
        if(pMenuData->m_nTitleFlags&MFT_LINE)
        {
          lpMIS->itemHeight += 8;
        }
      }
    }
    else
    {
      lpMIS->itemHeight = 3;
      lpMIS->itemWidth = 3;
    }
  }
  else
  {
    SIZE size = {0,0};
    //Get pointer to text SK
    CString itemText = pMenuData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
    { // We need this sub-block for releasing the dc
      CFont fontMenu;
      LOGFONT logFontMenu;

  #ifdef _NEW_MENU_USER_FONT
      logFontMenu =  MENU_USER_FONT;
  #else
      NONCLIENTMETRICS nm = {0};
      nm.cbSize = sizeof (NONCLIENTMETRICS);
      VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
      logFontMenu =  nm.lfMenuFont;
  #endif

      // Default selection?
      if (GetDefaultItem(0, FALSE) == pMenuData->m_nID)
      {
        // Make the font bold
        logFontMenu.lfWeight = FW_BOLD;
      }

      fontMenu.CreateFontIndirect (&logFontMenu);

       // DC of the desktop
      CClientDC myDC(NULL);
      // Select menu font in...
      CFont* pOldFont = myDC.SelectObject (&fontMenu);
      // Check the Key-Shortcut replacing for japanise/chinese calculating space
      itemText.Replace(_T("\t"),_T("nnn"));
      VERIFY(::GetTextExtentPoint32(myDC.m_hDC,itemText,itemText.GetLength(),&size));
      // Select old font in
      myDC.SelectObject(pOldFont);
    }// We need this sub-block for releasing the dc

    int temp = GetSystemMetrics(SM_CYMENU);
    // Set width and height:
    if(bIsMenuBar)
    {
      if(itemText.Find(_T("&"))>=0)
      {
        lpMIS->itemWidth = size.cx-6; // - GetSystemMetrics(SM_CXMENUCHECK)/2;
      }
      else
      {
        lpMIS->itemWidth = size.cx;
      }
      lpMIS->itemHeight = temp >(m_iconY+2) ? temp : m_iconY+2;
    }
    else
    {
      if(nFlag&MF_POPUP)
      {
        lpMIS->itemWidth = 2 + m_iconX + 4 + size.cx + GetSystemMetrics(SM_CYMENU);
      }
      else
      {
      lpMIS->itemWidth = 2 + m_iconX +4+ size.cx + GetSystemMetrics(SM_CYMENU) / 2;
      }
      lpMIS->itemHeight = temp>m_iconY+8 ? temp : m_iconY+7;
    }

    if(lpMIS->itemHeight<((UINT)size.cy) )
    {
      lpMIS->itemHeight=((UINT)size.cy);
    }

    // set status bar as appropriate
    UINT nItemID = (lpMIS->itemID & 0xFFF0);
    // Special case for system menu
    if (nItemID>=SC_SIZE && nItemID<=SC_HOTKEY)
    {
      BOOL bGetNext = FALSE;
      // search the actual menu item
      for (int j=0;j<m_MenuItemList.GetUpperBound();++j)
      {
        CNewMenuItemData* pTemp = m_MenuItemList[j];
        if(pTemp==pMenuData || bGetNext==TRUE)
        {
          bGetNext = TRUE;
          pTemp = m_MenuItemList[j+1];
          if(pTemp->m_nID)
          {
            lpMIS->itemData = (ULONG_PTR)pTemp;
            lpMIS->itemID = pTemp->m_nID;
            UINT nOrgWidth = lpMIS->itemWidth;
            MeasureItem_WinXP(lpMIS,bIsMenuBar);
            // Restore old values
            lpMIS->itemData = (ULONG_PTR)pMenuData;
            lpMIS->itemID = pMenuData->m_nID;
            lpMIS->itemWidth = max(lpMIS->itemWidth,nOrgWidth);
            break;
          }
        }
      }
      lpMIS->itemHeight = temp;
    }
  }
  //AfxTrace("IsMenuBar %ld, Height %2ld, width %3ld, ID 0x%08lX \r\n",int(bIsMenuBar),lpMIS->itemHeight,lpMIS->itemWidth,lpMIS->itemID);
}

void CNewMenu::SetIconSize (int width, int height)
{
  m_iconX = width;
  m_iconY = height;
}

CSize CNewMenu::GetIconSize()
{
  return CSize(m_iconX,m_iconY);
}

BOOL CNewMenu::AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID, int nIconNormal)
{
  return CNewMenu::AppendODMenu(lpstrText,nFlags,nID,(CImageList*)NULL,nIconNormal);
}

BOOL CNewMenu::AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID,
                            CBitmap* pBmp)
{
  int nIndex = -1;
  CNewMenuIconLock iconLock(GetMenuIcon(nIndex,pBmp));
  return AppendODMenu(lpstrText,nFlags,nID,iconLock,nIndex);
}

BOOL CNewMenu::AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID,
                            CImageList* pil, int xoffset)
{
  int nIndex = 0;
  // Helper for addref and release
  CNewMenuIconLock iconLock(GetMenuIcon(nIndex,nID,pil,xoffset));
  return AppendODMenu(lpstrText,nFlags,nID,iconLock,nIndex);
}

BOOL CNewMenu::AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID,
                            CNewMenuIcons* pIcons, int nIndex)
{
  // Add the MF_OWNERDRAW flag if not specified:
  if(!nID)
  {
    if(nFlags&MF_BYPOSITION)
      nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
    else
      nFlags=MF_SEPARATOR|MF_OWNERDRAW;
  }
  else if(!(nFlags & MF_OWNERDRAW))
  {
    nFlags |= MF_OWNERDRAW;
  }

  if(nFlags & MF_POPUP)
  {
    CNewMenu* pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(UIntToHMenu(nID)));
    if(pSubMenu)
    {
      pSubMenu->m_hParentMenu = m_hMenu;
    }
  }

  CNewMenuItemData* pItemData = new CNewMenuItemData;
  m_MenuItemList.Add(pItemData);
  pItemData->SetString(lpstrText);

  pIcons->AddRef();
  pItemData->m_pMenuIcon->Release();
  pItemData->m_pMenuIcon = pIcons;
  pItemData->m_nFlags = nFlags;
  pItemData->m_nID = nID;

  if(pIcons && nIndex>=0)
  {
    pItemData->m_nMenuIconOffset = nIndex;
    CSize size = pIcons->GetIconSize();
    m_iconX = max(m_iconX,size.cx);
    m_iconY = max(m_iconY,size.cy);
  }
  else
  {
    pItemData->m_nMenuIconOffset = -1;
  }

  // for having automated shortcut handling, thank to Mehdy Bohlool
  if (CMenu::AppendMenu(nFlags&~MF_OWNERDRAW, nID, pItemData->m_szMenuText))
  {
    return CMenu::ModifyMenu( CMenu::GetMenuItemCount()-1, MF_BYPOSITION| nFlags, nID, (LPCTSTR)pItemData );
  }
  return FALSE;
}

BOOL CNewMenu::InsertODMenu(UINT nPosition, LPCTSTR lpstrText, UINT nFlags, UINT nID,
                            int nIconNormal)
{
  int nIndex = -1;
  CNewMenuIcons* pIcons=NULL;

  if(nIconNormal>=0)
  {
    if(LoadFromToolBar(nID,nIconNormal,nIndex))
    {
      // the nIconNormal is a toolbar
      pIcons = GetToolbarIcons(nIconNormal);
      if(pIcons)
      {
        nIndex = pIcons->FindIndex(nID);
      }
    }
    else
    {
      // the nIconNormal is a bitmap
      pIcons = GetMenuIcon(nIndex,nIconNormal);
    }
  }

  CNewMenuIconLock iconLock(pIcons);
  return InsertODMenu(nPosition,lpstrText,nFlags,nID,iconLock,nIndex);
}

BOOL CNewMenu::InsertODMenu(UINT nPosition, LPCTSTR lpstrText, UINT nFlags, UINT nID, CBitmap* pBmp)
{
  int nIndex = -1;
  CNewMenuIconLock iconLock(GetMenuIcon(nIndex,pBmp));
  return InsertODMenu(nPosition,lpstrText,nFlags,nID,iconLock,nIndex);
}

BOOL CNewMenu::InsertODMenu(UINT nPosition, LPCTSTR lpstrText, UINT nFlags, UINT nID, CImageList *pil, int xoffset)
{
  int nIndex = -1;
  CNewMenuIconLock iconLock(GetMenuIcon(nIndex,nID,pil,xoffset));
  return InsertODMenu(nPosition,lpstrText,nFlags,nID,iconLock,nIndex);
}

BOOL CNewMenu::InsertODMenu(UINT nPosition, LPCTSTR lpstrText, UINT nFlags, UINT nID,
                            CNewMenuIcons* pIcons, int nIndex)
{
  if(!(nFlags & MF_BYPOSITION))
  {
    int iPosition =0;
    CNewMenu* pMenu = FindMenuOption(nPosition,iPosition);
    if(pMenu)
    {
      return(pMenu->InsertODMenu(iPosition,lpstrText,nFlags|MF_BYPOSITION,nID,pIcons,nIndex));
    }
    else
    {
      return(FALSE);
    }
  }

  if(!nID)
  {
    nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
  }
  else if(!(nFlags & MF_OWNERDRAW))
  {
    nFlags |= MF_OWNERDRAW;
  }

  if(nFlags & MF_POPUP)
  {
    CNewMenu* pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(UIntToHMenu(nID)));
    if(pSubMenu)
    {
      pSubMenu->m_hParentMenu = m_hMenu;
    }
  }

  //Stephane Clog suggested adding this, believe it or not it's in the help
  if(nPosition==(UINT)-1)
  {
    nPosition = GetMenuItemCount();
  }

  CNewMenuItemData *pItemData = new CNewMenuItemData;
  m_MenuItemList.InsertAt(nPosition,pItemData);
  pItemData->SetString(lpstrText);

  pIcons->AddRef();
  pItemData->m_pMenuIcon->Release();
  pItemData->m_pMenuIcon = pIcons;
  pItemData->m_nFlags = nFlags;
  pItemData->m_nID = nID;

  if(pIcons && nIndex>=0)
  {
    pItemData->m_nMenuIconOffset = nIndex;
    CSize size = pIcons->GetIconSize();
    m_iconX = max(m_iconX,size.cx);
    m_iconY = max(m_iconY,size.cy);
  }
  else
  {
    pItemData->m_nMenuIconOffset = -1;
  }
  // for having automated shortcut handling, thank to Mehdy Bohlool
  if (CMenu::InsertMenu(nPosition,nFlags&~MF_OWNERDRAW,nID,pItemData->m_szMenuText))
  {
    return CMenu::ModifyMenu(nPosition, MF_BYPOSITION| nFlags, nID, (LPCTSTR)pItemData );
  }
  return FALSE;
}

// Same as ModifyMenu but replacement for CNewMenu
BOOL CNewMenu::ModifyODMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem,LPCTSTR lpszNewItem)
{
  if(!(nFlags & MF_BYPOSITION))
  {
    int iPosition =0;
    CNewMenu* pMenu = FindMenuOption(nPosition,iPosition);
    if(pMenu)
    {
      return(pMenu->ModifyODMenu(iPosition,nFlags|MF_BYPOSITION,nIDNewItem,lpszNewItem));
    }
    else
    {
      return(FALSE);
    }
  }
  UINT nMenuID = GetMenuItemID(nPosition);
  if(nMenuID==(UINT)-1)
  {
    nMenuID = HMenuToUInt(::GetSubMenu(m_hMenu,nPosition));
  }
  CNewMenuItemData* pItemData = FindMenuItem(nMenuID);
  BOOL bRet = CMenu::ModifyMenu(nPosition, nFlags, nIDNewItem,lpszNewItem);
  if(pItemData)
  {
    pItemData->m_nID = nIDNewItem;
    GetMenuString(nPosition,pItemData->m_szMenuText,MF_BYPOSITION);
    CMenu::ModifyMenu(nPosition, nFlags|MF_OWNERDRAW, nIDNewItem,(LPCTSTR)pItemData);
  }
  if(bRet && (nFlags & MF_POPUP) )
  {
    CNewMenu* pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(UIntToHMenu(nIDNewItem)));
    if(pSubMenu)
    {
      pSubMenu->m_hParentMenu = m_hMenu;
    }
  }
  return bRet;
}

BOOL CNewMenu::ModifyODMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp)
{
  if(!(nFlags & MF_BYPOSITION))
  {
    int iPosition =0;
    CNewMenu* pMenu = FindMenuOption(nPosition,iPosition);
    if(pMenu)
    {
      return(pMenu->ModifyODMenu(iPosition,nFlags|MF_BYPOSITION,nIDNewItem,pBmp));
    }
    else
    {
      return(FALSE);
    }
  }
  UINT nMenuID = GetMenuItemID(nPosition);
  if(nMenuID==(UINT)-1)
  {
    nMenuID = HMenuToUInt(::GetSubMenu(m_hMenu,nPosition));
  }
  CNewMenuItemData* pItemData = FindMenuItem(nMenuID);
  BOOL bRet = CMenu::ModifyMenu(nPosition, nFlags, nIDNewItem,pBmp);
  if(pItemData)
  {
    pItemData->m_nID = nIDNewItem;
    pItemData->m_szMenuText.Empty();
    CMenu::ModifyMenu(nPosition, nFlags|MF_OWNERDRAW, nIDNewItem,(LPCTSTR)pItemData);
  }
  if(bRet && (nFlags & MF_POPUP) )
  {
    CNewMenu* pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(UIntToHMenu(nIDNewItem)));
    if(pSubMenu)
    {
      pSubMenu->m_hParentMenu = m_hMenu;
    }
  }
  return bRet;
}

BOOL CNewMenu::ModifyODMenu(LPCTSTR lpstrText, UINT nID, int nIconNormal)
{
  int nLoc;
  CNewMenuItemData* pItemData;
  CArray<CNewMenu*,CNewMenu*>newSubs;
  CArray<int,int&>newLocs;

  BOOL bModifyOK = TRUE;

  // Find the old CNewMenuItemData structure:
  CNewMenu* pSubMenu = FindMenuOption(nID,nLoc);
  do {
    if(pSubMenu && nLoc>=0)
    {
      pItemData = pSubMenu->m_MenuItemList[nLoc];
    }
    else
    {
      // Create a new CNewMenuItemData structure:
      pItemData = new CNewMenuItemData;
      m_MenuItemList.Add(pItemData);
    }

    BOOL bTextChanged = FALSE;
    ASSERT(pItemData);
    if(lpstrText && pItemData->m_szMenuText.Compare(lpstrText)!=NULL)
    {
      bTextChanged = TRUE;
      pItemData->SetString(lpstrText);
    }

    pItemData->m_nMenuIconOffset=-1;
    if(nIconNormal>=0)
    {
      int nxOffset = -1;
      CNewMenuIcons* pIcons=NULL;
      if(LoadFromToolBar(nID,nIconNormal,nxOffset))
      {
        // the nIconNormal is a toolbar
        pIcons = GetToolbarIcons(nIconNormal);
        if(pIcons)
        {
          pItemData->m_nMenuIconOffset = pIcons->FindIndex(nID);
        }
      }
      else
      {
        // the nIconNormal is a bitmap
        pIcons = GetMenuIcon(pItemData->m_nMenuIconOffset,nIconNormal);
      }
      pIcons->AddRef();
      pItemData->m_pMenuIcon->Release();
      pItemData->m_pMenuIcon = pIcons;
      if(pIcons)
      {
        CSize size = pIcons->GetIconSize();
        pSubMenu->m_iconX = max(pSubMenu->m_iconX,size.cx);
        pSubMenu->m_iconY = max(pSubMenu->m_iconY,size.cy);
      }
    }
    pItemData->m_nFlags &= ~(MF_BYPOSITION);
    pItemData->m_nFlags |= MF_OWNERDRAW;
    pItemData->m_nID = nID;

    // for having automated shortcut handling
    if(pSubMenu && bTextChanged)
    {
      if(pSubMenu->ModifyMenu(nLoc, MF_BYPOSITION|(pItemData->m_nFlags&~MF_OWNERDRAW), nID,pItemData->m_szMenuText) )
      {
        if(!pSubMenu->ModifyMenu(nLoc, MF_BYPOSITION|pItemData->m_nFlags, nID,(LPCTSTR)pItemData))
        {
          bModifyOK = FALSE;
        }
      }
      else
      {
        bModifyOK = FALSE;
      }
    }

    newSubs.Add(pSubMenu);
    newLocs.Add(nLoc);

    if(pSubMenu && nLoc>=0)
    {
      pSubMenu = FindAnotherMenuOption(nID,nLoc,newSubs,newLocs);
    }
    else
    {
      pSubMenu = NULL;
    }
  }while(pSubMenu);

  return (CMenu::ModifyMenu(nID,pItemData->m_nFlags,nID,(LPCTSTR)pItemData)) && bModifyOK;
}

BOOL CNewMenu::ModifyODMenu(LPCTSTR lpstrText, UINT nID, CImageList *pil, int xoffset)
{
  int nIndex = 0;
  CNewMenuIcons* pIcons = GetMenuIcon(nIndex,nID,pil,xoffset);
  pIcons->AddRef();

  BOOL bResult = ModifyODMenu(lpstrText,nID,pIcons,nIndex);

  pIcons->Release();

  return bResult;
}

BOOL CNewMenu::ModifyODMenu(LPCTSTR lpstrText, UINT nID, CNewMenuIcons* pIcons, int xoffset)
{
  ASSERT(pIcons);
  int nLoc;
  CNewMenuItemData *pItemData;
  CArray<CNewMenu*,CNewMenu*>newSubs;
  CArray<int,int&>newLocs;
  BOOL bModifyOK = TRUE;

  // Find the old CNewMenuItemData structure:
  CNewMenu *pSubMenu = FindMenuOption(nID,nLoc);
  do {
    if(pSubMenu && nLoc>=0)
    {
      pItemData = pSubMenu->m_MenuItemList[nLoc];
    }
    else
    {
      // Create a new CNewMenuItemData structure:
      pItemData = new CNewMenuItemData;
      m_MenuItemList.Add(pItemData);
    }

    BOOL bTextChanged = FALSE;
    ASSERT(pItemData);
    if(lpstrText && pItemData->m_szMenuText.Compare(lpstrText)!=NULL)
    {
      bTextChanged = TRUE;
      pItemData->SetString(lpstrText);
    }

    if(pIcons)
    {
      pIcons->AddRef();
      pItemData->m_pMenuIcon->Release();
      pItemData->m_pMenuIcon = pIcons;

      pItemData->m_nMenuIconOffset = xoffset;

      int x=0;
      int y=0;
      if(pSubMenu && pIcons->GetIconSize(&x,&y))
      {
        // Correct the size of the menuitem
        pSubMenu->m_iconX = max(pSubMenu->m_iconX,x);
        pSubMenu->m_iconY = max(pSubMenu->m_iconY,y);
      }
    }
    else
    {
      pItemData->m_nMenuIconOffset = -1;
    }
    pItemData->m_nFlags &= ~(MF_BYPOSITION);
    pItemData->m_nFlags |= MF_OWNERDRAW;
    pItemData->m_nID = nID;

    // for having automated shortcut handling
    if(pSubMenu && bTextChanged)
    {
      if(pSubMenu->ModifyMenu(nLoc, MF_BYPOSITION|(pItemData->m_nFlags&~MF_OWNERDRAW), nID,pItemData->m_szMenuText) )
      {
        if(!pSubMenu->ModifyMenu(nLoc, MF_BYPOSITION|pItemData->m_nFlags, nID,(LPCTSTR)pItemData))
        {
          bModifyOK = FALSE;
        }
      }
      else
      {
        bModifyOK = FALSE;
      }
    }

    newSubs.Add(pSubMenu);
    newLocs.Add(nLoc);
    if(pSubMenu && nLoc>=0)
    {
      pSubMenu = FindAnotherMenuOption(nID,nLoc,newSubs,newLocs);
    }
    else
    {
      pSubMenu = NULL;
    }
  } while(pSubMenu);

  return (CMenu::ModifyMenu(nID,pItemData->m_nFlags,nID,(LPCTSTR)pItemData)) && bModifyOK;
}

BOOL CNewMenu::ModifyODMenu(LPCTSTR lpstrText, UINT nID, CBitmap* bmp)
{
  if (bmp)
  {
    CImageList temp;
    temp.Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);

    temp.Add(bmp,GetBitmapBackground());

    return ModifyODMenu(lpstrText,nID,&temp,0);
  }
  return ModifyODMenu(lpstrText,nID,(CImageList*)NULL,0);
}

BOOL CNewMenu::ModifyODMenu(LPCTSTR lpstrText, UINT nID, COLORREF fill, COLORREF border, int hatchstyle)
{
  // Get device context
  CSize bitmap_size(m_iconX,m_iconY);
  CBitmap bmp;
  {
    CClientDC DC(0);
    ColorBitmap(&DC,bmp,bitmap_size,fill,border,hatchstyle);
  }
  return ModifyODMenu(lpstrText,nID,&bmp);
}

BOOL CNewMenu::ModifyODMenu(LPCTSTR lpstrText, LPCTSTR OptionText, int nIconNormal)
{
  int nIndex = 0;
  CNewMenu* pOptionMenu = FindMenuOption(OptionText,nIndex);

  if(pOptionMenu!=NULL && nIndex>=0)
  {
    CNewMenuItemData* pItemData = pOptionMenu->m_MenuItemList[nIndex];

    BOOL bTextChanged = FALSE;
    ASSERT(pItemData);
    if(lpstrText && pItemData->m_szMenuText.Compare(lpstrText)!=NULL)
    {
      bTextChanged = TRUE;
      pItemData->SetString(lpstrText);
    }

    pItemData->m_nMenuIconOffset = nIconNormal;
    if(nIconNormal>=0)
    {
      CNewMenuIcons* pIcons = GetMenuIcon(pItemData->m_nMenuIconOffset,nIconNormal);
      pIcons->AddRef();
      pItemData->m_pMenuIcon->Release();
      pItemData->m_pMenuIcon = pIcons;

      CNewMenuBitmaps* pMenuIcon = DYNAMIC_DOWNCAST(CNewMenuBitmaps,pItemData->m_pMenuIcon);
      if(pMenuIcon)
      {
        CSize size = pMenuIcon->GetIconSize();
        pOptionMenu->m_iconX = max(pOptionMenu->m_iconX,size.cx);
        pOptionMenu->m_iconY = max(pOptionMenu->m_iconY,size.cy);
      }
    }

    // for having automated shortcut handling
    if(pOptionMenu && bTextChanged)
    {
      if(!pOptionMenu->ModifyMenu(nIndex, MF_BYPOSITION|(pItemData->m_nFlags&~MF_OWNERDRAW), pItemData->m_nID,pItemData->m_szMenuText) ||
        !pOptionMenu->ModifyMenu(nIndex, MF_BYPOSITION|pItemData->m_nFlags, pItemData->m_nID,(LPCTSTR)pItemData))
      {
        return FALSE;
      }
    }
    return TRUE;
  }
  return FALSE;
}

CNewMenuItemData* CNewMenu::NewODMenu(UINT pos, UINT nFlags, UINT nID, LPCTSTR string)
{
  CNewMenuItemData* pItemData;

  pItemData = new CNewMenuItemData;
  pItemData->m_nFlags = nFlags;
  pItemData->m_nID = nID;
  if(!(nFlags&MF_BITMAP))
  {
  pItemData->SetString (string);
  }

  if(nFlags & MF_POPUP)
  {
    CNewMenu* pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(UIntToHMenu(nID)));
    if(pSubMenu)
    {
      pSubMenu->m_hParentMenu = m_hMenu;
    }
  }

  BOOL bModified = FALSE;
  if (nFlags&MF_OWNERDRAW)
  {
    bModified = ModifyMenu(pos,nFlags,nID,(LPCTSTR)pItemData);
  }
  else if (nFlags&MF_BITMAP)
  {
    bModified = ModifyMenu(pos,nFlags,nID,(CBitmap*)string);
  }
  else if (nFlags&MF_SEPARATOR)
  {
    ASSERT(nFlags&MF_SEPARATOR);
    bModified = ModifyMenu(pos,nFlags,nID);
  }
  else // (nFlags&MF_STRING)
  {
    ASSERT(!(nFlags&MF_OWNERDRAW));
    bModified = ModifyMenu(pos,nFlags,nID,pItemData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL));
  }
  if(!bModified)
  {
    ShowLastError(_T("Error from Menu: ModifyMenu"));
  }
  return(pItemData);
};

BOOL CNewMenu::LoadToolBars(const UINT* arID, int n, HMODULE hInst)
{
  ASSERT(arID);
  BOOL returnflag = TRUE;
  for(int i=0;i<n;++i)
  {
    if(!LoadToolBar(arID[i],hInst))
    {
      returnflag = FALSE;
    }
  }
  return(returnflag);
}

DWORD CNewMenu::SetMenuIcons(CNewMenuIcons* pMenuIcons)
{
  ASSERT(pMenuIcons);
  int nCount = (int)pMenuIcons->m_IDs.GetSize();
  while(nCount--)
  {
    ModifyODMenu(NULL,pMenuIcons->m_IDs[nCount],pMenuIcons,nCount*MENU_ICONS);
  }
  return pMenuIcons->m_dwRefCount;
}

CNewMenuIcons* CNewMenu::GetMenuIcon(int &nIndex, UINT nID, CImageList *pil, int xoffset)
{
  if(pil==NULL || xoffset<0)
  {
    nIndex=-1;
    return NULL;
  }

  HICON hIcon = pil->ExtractIcon(xoffset);

  if(m_pSharedMenuIcons!=NULL)
  {
    POSITION pos = m_pSharedMenuIcons->GetHeadPosition();
    while(pos)
    {
      CNewMenuBitmaps* pMenuIcon = DYNAMIC_DOWNCAST(CNewMenuBitmaps,m_pSharedMenuIcons->GetNext(pos));
      if(pMenuIcon)
      {
        nIndex = pMenuIcon->Add(hIcon,nID);
        if(nIndex!=-1)
        {
          DestroyIcon(hIcon);
          return pMenuIcon;
        }
      }
    }
  }
  else
  {
    m_pSharedMenuIcons = new CTypedPtrList<CPtrList, CNewMenuIcons*>;
  }
  CNewMenuBitmaps* pMenuIcon = new CNewMenuBitmaps();
  pMenuIcon->m_crTransparent = m_bitmapBackground;
  nIndex = pMenuIcon->Add(hIcon,nID);
  DestroyIcon(hIcon);
  if(nIndex!=-1)
  {
    m_pSharedMenuIcons->AddTail(pMenuIcon);
    return pMenuIcon;
  }
  delete pMenuIcon;
  return NULL;
}

CNewMenuIcons* CNewMenu::GetMenuIcon(int &nIndex, int nID)
{
  if(m_pSharedMenuIcons!=NULL)
  {
    POSITION pos = m_pSharedMenuIcons->GetHeadPosition();
    while(pos)
    {
      CNewMenuBitmaps* pMenuIcon = DYNAMIC_DOWNCAST(CNewMenuBitmaps,m_pSharedMenuIcons->GetNext(pos));
      if(pMenuIcon)
      {
        if(m_bDynIcons)
        {
          nIndex = pMenuIcon->Add((HICON)(INT_PTR)nID);
        }
        else
        {
          nIndex = pMenuIcon->Add(nID,m_bitmapBackground);
        }
        if(nIndex!= -1)
        {
          return pMenuIcon;
        }
      }
    }
  }
  else
  {
    m_pSharedMenuIcons = new CTypedPtrList<CPtrList, CNewMenuIcons*>;
  }
  CNewMenuBitmaps* pMenuIcon = new CNewMenuBitmaps();
  pMenuIcon->m_crTransparent = m_bitmapBackground;
  nIndex = pMenuIcon->Add(nID,m_bitmapBackground);
  if(nIndex!=-1)
  {
    m_pSharedMenuIcons->AddTail(pMenuIcon);
    return pMenuIcon;
  }
  delete pMenuIcon;
  return NULL;
}

CNewMenuIcons* CNewMenu::GetMenuIcon(int &nIndex, CBitmap* pBmp)
{
  if(pBmp==NULL)
  {
    nIndex=-1;
    return NULL;
  }

  if(m_pSharedMenuIcons!=NULL)
  {
    POSITION pos = m_pSharedMenuIcons->GetHeadPosition();
    while(pos)
    {
      CNewMenuBitmaps* pMenuIcon = DYNAMIC_DOWNCAST(CNewMenuBitmaps,m_pSharedMenuIcons->GetNext(pos));
      if(pMenuIcon)
      {
        nIndex = pMenuIcon->Add(pBmp,m_bitmapBackground);
        if(nIndex!=-1)
        {
          return pMenuIcon;
        }
      }
    }
  }
  else
  {
    m_pSharedMenuIcons = new CTypedPtrList<CPtrList, CNewMenuIcons*>;
  }
  CNewMenuBitmaps* pMenuIcon = new CNewMenuBitmaps();
  pMenuIcon->m_crTransparent = m_bitmapBackground;
  nIndex = pMenuIcon->Add(pBmp,m_bitmapBackground);
  if(nIndex!=-1)
  {
    m_pSharedMenuIcons->AddTail(pMenuIcon);
    return pMenuIcon;
  }
  delete pMenuIcon;
  return NULL;
}


CNewMenuIcons* CNewMenu::GetToolbarIcons(UINT nToolBar, HMODULE hInst)
{
  ASSERT_VALID(this);
  ASSERT(nToolBar != NULL);

  if(m_pSharedMenuIcons!=NULL)
  {
    POSITION pos = m_pSharedMenuIcons->GetHeadPosition();
    while(pos)
    {
      CNewMenuIcons* pMenuIcon = m_pSharedMenuIcons->GetNext(pos);
      if(pMenuIcon->DoMatch(MAKEINTRESOURCE(nToolBar),hInst))
      {
        return pMenuIcon;
      }
    }
  }
  else
  {
    m_pSharedMenuIcons = new CTypedPtrList<CPtrList, CNewMenuIcons*>;
  }
  CNewMenuIcons* pMenuIcon = new CNewMenuIcons();
  pMenuIcon->m_crTransparent = m_bitmapBackground;
  if(pMenuIcon->LoadToolBar(MAKEINTRESOURCE(nToolBar),hInst))
  {
    m_pSharedMenuIcons->AddTail(pMenuIcon);
    return pMenuIcon;
  }
  delete pMenuIcon;
  return NULL;
}


BOOL CNewMenu::LoadToolBar(LPCTSTR lpszResourceName, HMODULE hInst)
{
  CNewMenuIcons* pMenuIcon = GetToolbarIcons((UINT)(UINT_PTR)lpszResourceName,hInst);
  if(pMenuIcon)
  {
    SetMenuIcons(pMenuIcon);
    return TRUE;
  }
  return FALSE;
}

BOOL CNewMenu::LoadToolBar(HBITMAP hBitmap, CSize size, UINT* pID, COLORREF crTransparent)
{
  ASSERT_VALID(this);
  ASSERT(pID);

  if(crTransparent==CLR_NONE)
  {
    crTransparent = m_bitmapBackground;
  }
  if(m_pSharedMenuIcons!=NULL)
  {
    POSITION pos = m_pSharedMenuIcons->GetHeadPosition();
    while(pos)
    {
      CNewMenuIcons* pMenuIcon = m_pSharedMenuIcons->GetNext(pos);
      if(pMenuIcon->DoMatch(hBitmap,size,pID))
      {
        SetMenuIcons(pMenuIcon);
        return TRUE;
      }
    }
  }
  else
  {
    m_pSharedMenuIcons = new CTypedPtrList<CPtrList, CNewMenuIcons*>;
  }
  CNewMenuIcons* pMenuIcon = new CNewMenuIcons();
  if(pMenuIcon->LoadToolBar(hBitmap,size,pID,crTransparent))
  {
    m_pSharedMenuIcons->AddTail(pMenuIcon);
    SetMenuIcons(pMenuIcon);
    return TRUE;
  }
  delete pMenuIcon;
  return FALSE;
}

BOOL CNewMenu::LoadToolBar(WORD* pToolInfo, COLORREF crTransparent)
{
  ASSERT_VALID(this);
  ASSERT(pToolInfo);

  if(crTransparent==CLR_NONE)
  {
    crTransparent = m_bitmapBackground;
  }

  if(m_pSharedMenuIcons!=NULL)
  {
    POSITION pos = m_pSharedMenuIcons->GetHeadPosition();
    while(pos)
    {
      CNewMenuIcons* pMenuIcon = m_pSharedMenuIcons->GetNext(pos);
      if(pMenuIcon->DoMatch(pToolInfo,crTransparent))
      {
        SetMenuIcons(pMenuIcon);
        return TRUE;
      }
    }
  }
  else
  {
    m_pSharedMenuIcons = new CTypedPtrList<CPtrList, CNewMenuIcons*>;
  }
  CNewMenuIcons* pMenuIcon = new CNewMenuIcons();
  if(pMenuIcon->LoadToolBar(pToolInfo,crTransparent))
  {
    m_pSharedMenuIcons->AddTail(pMenuIcon);
    SetMenuIcons(pMenuIcon);
    return TRUE;
  }
  delete pMenuIcon;
  return FALSE;
}


// Jan-12-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
// added this function as a helper to LoadToolBar(WORD* pToolInfo, COLORREF crTransparent), the purpose of this function
// is to easily load a high color toolbar to the menu, instead of creating and maintaining a command map.  this function
// simply reads an existing 16 bit toolbar, and builds the word map based on that toolbar, using the 256 color bitmap.
BOOL CNewMenu::LoadToolBar(UINT n16ToolBarID, UINT n256BitmapID, COLORREF transparentColor, HMODULE hInst)
{
  BOOL bRet = FALSE;
  // determine location of the bitmap in resource
  if(hInst==0)
  {
    hInst = AfxFindResourceHandle(MAKEINTRESOURCE(n16ToolBarID), RT_TOOLBAR);
  }
  HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(n16ToolBarID), RT_TOOLBAR);

  if (hRsrc == NULL)
  { // Special purpose when you try to load it from a dll 30.05.2002
    if(AfxGetResourceHandle()!=hInst)
    {
      hInst = AfxGetResourceHandle();
      hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(n16ToolBarID), RT_TOOLBAR);
    }
    if (hRsrc == NULL)
    {
      return FALSE;
    }
  }

  HGLOBAL hGlobal = LoadResource(hInst, hRsrc);
  if (hGlobal)
  {
    CToolBarData* pData = (CToolBarData*)LockResource(hGlobal);
    if (pData)
    {
      int nSize = sizeof(WORD)*(pData->wItemCount+4);
      // no need for delete
      WORD* pToolId = (WORD*)_alloca(nSize);
      // sets also the last entry to zero
      ZeroMemory(pToolId,nSize);

      pToolId[0] = (WORD)n256BitmapID;
      pToolId[1] = pData->wWidth;
      pToolId[2] = pData->wHeight;

      WORD* pTemp = pToolId+3;
      for (int nIndex = 0; nIndex < pData->wItemCount; nIndex++)
      { // not a seperator?
        if( (pData->items()[nIndex]) )
        {
          *pTemp++ = pData->items()[nIndex];
        }
      }
      // load the toolbar images into the menu
      bRet = LoadToolBar(pToolId, transparentColor);
      UnlockResource(hGlobal);
    }
    FreeResource(hGlobal);
  }
  // return TRUE for success, FALSE for failure
  return (bRet);
} // LoadHiColor


BOOL CNewMenu::LoadToolBar(UINT nToolBar, HMODULE hInst)
{
  return LoadToolBar((LPCTSTR)(UINT_PTR)nToolBar,hInst);
}

BOOL CNewMenu::LoadFromToolBar(UINT nID, UINT nToolBar, int& xoffset)
{
  int xset,offset;
  UINT nStyle;
  BOOL returnflag=FALSE;
  CToolBar bar;

  CWnd* pWnd = AfxGetMainWnd();
  if (pWnd == NULL)
  {
    pWnd = CWnd::GetDesktopWindow();
  }
  bar.Create(pWnd);

  if(bar.LoadToolBar(nToolBar))
  {
    offset=bar.CommandToIndex(nID);
    if(offset>=0)
    {
      bar.GetButtonInfo(offset,nID,nStyle,xset);
      if(xset>0)
      {
        xoffset = xset;
      }
      returnflag=TRUE;
    }
  }
  return returnflag;
}

// O.S.
CNewMenuItemData* CNewMenu::FindMenuItem(UINT nID)
{
  CNewMenuItemData *pData = NULL;
  int i;

  for(i = 0; i < m_MenuItemList.GetSize(); i++)
  {
    if (m_MenuItemList[i]->m_nID == nID)
    {
      pData = m_MenuItemList[i];
      break;
    }
  }
  if (!pData)
  {
    int loc;
    CNewMenu *pMenu = FindMenuOption(nID, loc);
    ASSERT(pMenu != this);
    if (loc >= 0)
    {
      return pMenu->FindMenuItem(nID);
    }
  }
  return pData;
}


CNewMenu* CNewMenu::FindAnotherMenuOption(int nId, int& nLoc,
                                          CArray<CNewMenu*,CNewMenu*>&newSubs,
                                          CArray<int,int&>&newLocs)
{
  int i,numsubs,j;
  CNewMenu *pSubMenu,*pgoodmenu;
  BOOL foundflag;

  for(i=0;i<(int)(GetMenuItemCount());++i)
  {
    pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,GetSubMenu(i));
    if(pSubMenu)
    {
      pgoodmenu = pSubMenu->FindAnotherMenuOption(nId,nLoc,newSubs,newLocs);
      if(pgoodmenu)
      {
        return pgoodmenu;
      }
    }
    else if(nId==(int)GetMenuItemID(i))
    {
      numsubs = (int)newSubs.GetSize();
      foundflag = TRUE;
      for(j=0;j<numsubs;++j)
      {
        if(newSubs[j]==this && newLocs[j]==i)
        {
          foundflag = FALSE;
          break;
        }
      }
      if(foundflag)
      {
        nLoc = i;
        return this;
      }
    }
  }
  nLoc = -1;

  return NULL;
}

CNewMenu* CNewMenu::FindMenuOption(int nId, int& nLoc)
{
  int i;
  CNewMenu *pSubMenu,*pgoodmenu;

  for(i=0;i<(int)(GetMenuItemCount());++i)
  {
    pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,GetSubMenu(i));
    if(pSubMenu)
    {
      pgoodmenu = pSubMenu->FindMenuOption(nId,nLoc);
      if(pgoodmenu)
      {
        return pgoodmenu;
      }
    }
    else if(nId==(int)GetMenuItemID(i))
    {
      nLoc = i;
      return(this);
    }
  }
  nLoc = -1;
  return NULL;
}

CNewMenu* CNewMenu::FindMenuOption(LPCTSTR lpstrText, int& nLoc)
{
  int i;
  // First look for all item text.
  for(i=0;i<(int)m_MenuItemList.GetSize();++i)
  {
    if(m_MenuItemList[i]->m_szMenuText.Compare(lpstrText)==NULL)
    {
      nLoc = i;
      return this;
    }
  }
  CNewMenu* pSubMenu;
  // next, look in all submenus
  for(i=0; i<(int)(GetMenuItemCount());++i)
  {
    pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,GetSubMenu(i));
    if(pSubMenu)
    {
      pSubMenu = pSubMenu->FindMenuOption(lpstrText,nLoc);
      if(pSubMenu)
      {
        return pSubMenu;
      }
    }
  }
  nLoc = -1;
  return NULL;
}

BOOL CNewMenu::LoadMenu(HMENU hMenu)
{
  if(!::IsMenu(hMenu) || !Attach(hMenu))
  {
    return FALSE;
  }
  m_bIsPopupMenu = FALSE;
  for(int i=0;i<(int)(GetMenuItemCount());++i)
  {
    HMENU hSubMenu = ::GetSubMenu(m_hMenu,i);
    if(hSubMenu)
    {
      CNewMenu* pMenu = new CNewMenu(m_hMenu);
      m_SubMenus.Add(hSubMenu);
      pMenu->LoadMenu(hSubMenu);
      pMenu->m_bIsPopupMenu = TRUE;
    }
  }
  SynchronizeMenu();
  return TRUE;
}

BOOL CNewMenu::LoadMenu(int nResource)
{
  return(CNewMenu::LoadMenu(MAKEINTRESOURCE(nResource)));
}

BOOL CNewMenu::LoadMenu(LPCTSTR lpszResourceName)
{
  ASSERT(this);
  HMENU hMenu = ::LoadMenu(AfxFindResourceHandle(lpszResourceName,RT_MENU), lpszResourceName);
  #ifdef _DEBUG
  ShowLastError(_T("Error from Menu: LoadMenu"));
  #endif
  return LoadMenu(hMenu);
}

BOOL CNewMenu::SetItemData(UINT uiId, DWORD_PTR dwItemData, BOOL fByPos)
{
  MENUITEMINFO MenuItemInfo = {0};
  MenuItemInfo.cbSize = sizeof(MenuItemInfo);
  MenuItemInfo.fMask = MIIM_DATA;
  if(::GetMenuItemInfo(m_hMenu,uiId,fByPos,&MenuItemInfo))
  {
    CNewMenuItemData* pItem = CheckMenuItemData(MenuItemInfo.dwItemData);
    if(pItem)
    {
      pItem->m_pData = (void*)dwItemData;
      return TRUE;
    }
  }
  return FALSE;
}

BOOL CNewMenu::SetItemDataPtr(UINT uiId, void* pItemData, BOOL fByPos )
{
  return SetItemData(uiId, (DWORD_PTR) pItemData, fByPos);
}

DWORD_PTR CNewMenu::GetItemData(UINT uiId, BOOL fByPos) const
{
  MENUITEMINFO MenuItemInfo = {0};
  MenuItemInfo.cbSize = sizeof(MenuItemInfo);
  MenuItemInfo.fMask = MIIM_DATA;
  if(::GetMenuItemInfo(m_hMenu,uiId,fByPos,&MenuItemInfo))
  {
    CNewMenuItemData* pItem = CheckMenuItemData(MenuItemInfo.dwItemData);
    if(pItem)
    {
      return (DWORD_PTR)pItem->m_pData;
    }
  }
  return DWORD_PTR(-1);
}

void* CNewMenu::GetItemDataPtr(UINT uiId, BOOL fByPos) const
{
  return (void*)GetItemData(uiId,fByPos);
}

BOOL CNewMenu::SetMenuData(DWORD_PTR dwMenuData)
{
  m_pData = (void*)dwMenuData;
  return TRUE;
}

BOOL CNewMenu::SetMenuDataPtr(void* pMenuData)
{
  m_pData = (void*)pMenuData;
  return TRUE;
}

DWORD_PTR CNewMenu::GetMenuData() const
{
  return (DWORD_PTR)m_pData;
}

void* CNewMenu::GetMenuDataPtr() const
{
  return m_pData;
}

BOOL  CNewMenu::m_bDrawAccelerators = TRUE;

BOOL  CNewMenu::SetAcceleratorsDraw (BOOL bDraw)
{
  BOOL bOld = m_bDrawAccelerators;
  m_bDrawAccelerators = bDraw;
  return bOld;
}
BOOL  CNewMenu::GetAcceleratorsDraw ()
{
  return m_bDrawAccelerators;
}

BYTE CNewMenu::m_bAlpha = 255;

BYTE CNewMenu::SetAlpha(BYTE bAlpha)
{
  BYTE oldAlpha = m_bAlpha;
  m_bAlpha = bAlpha;
  return oldAlpha;
}

BYTE CNewMenu::GetAlpha()
{
  return m_bAlpha;
}

// INVALID_HANDLE_VALUE = Draw default frame's accel. NULL = Off
HACCEL  CNewMenu::SetAccelerator (HACCEL hAccel)
{
  HACCEL hOld = m_hAccelToDraw;
  m_hAccelToDraw = hAccel;
  return hOld;
}
HACCEL  CNewMenu::GetAccelerator ()
{
  return m_hAccelToDraw;
}

void CNewMenu::LoadCheckmarkBitmap(int unselect, int select)
{
  if(unselect>0 && select>0)
  {
    m_selectcheck = select;
    m_unselectcheck = unselect;
    if(m_checkmaps)
    {
      m_checkmaps->DeleteImageList();
    }
    else
    {
      m_checkmaps = new CImageList();
    }

    m_checkmaps->Create(m_iconX,m_iconY,ILC_MASK,2,1);
    BOOL flag1 = AddBitmapToImageList(m_checkmaps,unselect);
    BOOL flag2 = AddBitmapToImageList(m_checkmaps,select);

    if(!flag1||!flag2)
    {
      m_checkmaps->DeleteImageList();
      delete m_checkmaps;
      m_checkmaps = NULL;
    }
  }
}

BOOL CNewMenu::GetMenuText(UINT id, CString& string, UINT nFlags/*= MF_BYPOSITION*/)
{
  if(MF_BYPOSITION&nFlags)
  {
    UINT numMenuItems = (int)m_MenuItemList.GetSize();
    if(id<numMenuItems)
    {
      string = m_MenuItemList[id]->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
      return TRUE;
    }
  }
  else
  {
    int uiLoc;
    CNewMenu* pMenu = FindMenuOption(id,uiLoc);
    if(NULL!=pMenu)
    {
      return pMenu->GetMenuText(uiLoc,string);
    }
  }
  return FALSE;
}

CNewMenuItemData* CNewMenu::CheckMenuItemData(ULONG_PTR nItemData) const
{
  for(int i=0;i<m_MenuItemList.GetSize();++i)
  {
    CNewMenuItemData* pItem = m_MenuItemList[i];
    if ( ((ULONG_PTR)pItem)==nItemData )
    {
      return pItem;
    }
  }
  return NULL;
}


CNewMenuItemData* CNewMenu::FindMenuList(UINT nID)
{
  for(int i=0;i<m_MenuItemList.GetSize();++i)
  {
    CNewMenuItemData* pMenuItem = m_MenuItemList[i];
    if(pMenuItem->m_nID==nID && !pMenuItem->m_nSyncFlag)
    {
      pMenuItem->m_nSyncFlag = 1;
      return pMenuItem;
    }
  }
  return NULL;
}

void CNewMenu::InitializeMenuList(int value)
{
  for(int i=0;i<m_MenuItemList.GetSize();++i)
  {
     m_MenuItemList[i]->m_nSyncFlag = value;
  }
}

void CNewMenu::DeleteMenuList()
{
  for(int i=0;i<m_MenuItemList.GetSize();++i)
  {
    if(!m_MenuItemList[i]->m_nSyncFlag)
    {
      delete m_MenuItemList[i];
    }
  }
}

void CNewMenu::SynchronizeMenu()
{
  CTypedPtrArray<CPtrArray, CNewMenuItemData*> temp;
  CNewMenuItemData *pItemData;
  CString string;
  UINT submenu,state,j;

  InitializeMenuList(0);
  for(j=0;j<GetMenuItemCount();++j)
  {
    MENUITEMINFO menuInfo = {0};
    menuInfo.cbSize = sizeof(menuInfo);
    // we get a wrong state for seperators
    menuInfo.fMask = MIIM_TYPE|MIIM_ID|MIIM_STATE;
    // item doesn't exist
    if(!GetMenuItemInfo(j,&menuInfo,TRUE))
    {
      break;
    }
    state = GetMenuState(j,MF_BYPOSITION);
    if(state!=menuInfo.fState)
    {
      state|=0;
    }
    pItemData=NULL;
    if(state==UINT_PTR(-1))
    {
      break;
    }
    if(!(state&MF_SYSMENU))
    {
      if(menuInfo.fType&MFT_RIGHTJUSTIFY)
      {
        state |= MF_RIGHTJUSTIFY;
      }
      // MFT_RIGHTORDER is the same value as MFT_SYSMENU.
      // We distinguish between the two by also looking for MFT_BITMAP.
      if(!(state&MF_BITMAP) && (menuInfo.fType&MFT_RIGHTORDER) )
      {
        state |= MFT_RIGHTORDER;
      }
    }

    // Special purpose for Windows NT 4.0
    if(state&MF_BITMAP)
    {
      // Bitmap-button like system menu, maximize, minimize and close
      // just ignore.
      UINT nID = GetMenuItemID(j);
      pItemData = FindMenuList(nID);
      if(!pItemData)
      {
        //if(nID>=SC_SIZE && nID<=SC_HOTKEY)
        // we do not support bitmap in menu because the OS handle it not right with
        // ownerdrawn style so let show the default one
        {
        pItemData = new CNewMenuItemData;
        pItemData->m_nFlags = state;
        pItemData->m_nID = nID;
      }
        //else
        //{
        //  // sets the handle of the bitmap
        //  pItemData = NewODMenu(j,state|MF_BYPOSITION|MF_OWNERDRAW,nID,menuInfo.dwTypeData);
        //}
      }
    }
    else if(state&MF_POPUP)
    {
      HMENU hSubMenu = GetSubMenu(j)->m_hMenu;
      submenu = HMenuToUInt(hSubMenu);
      pItemData = FindMenuList(submenu);
      GetMenuString(j,string,MF_BYPOSITION);

      if(!pItemData)
      {
        state &= ~(MF_USECHECKBITMAPS|MF_SEPARATOR);
        pItemData = NewODMenu(j,state|MF_BYPOSITION|MF_POPUP|MF_OWNERDRAW,submenu,string);
      }
      else if(!string.IsEmpty ())
      {
        pItemData->SetString(string);
      }

      CNewMenu* pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(hSubMenu));
      if(pSubMenu && pSubMenu->m_hParentMenu!=m_hMenu)
      { // Sets again the parent to this one
        pSubMenu->m_hParentMenu = m_hMenu;
      }
    }
    else if(state&MF_SEPARATOR)
    {
      pItemData = FindMenuList(0);
      if(!pItemData)
      {
        pItemData = NewODMenu(j,state|MF_BYPOSITION|MF_OWNERDRAW,0,_T(""));
      }
      else
      {
        pItemData->m_nFlags = state|MF_BYPOSITION|MF_OWNERDRAW;
        ModifyMenu(j,pItemData->m_nFlags,0,(LPCTSTR)pItemData);
      }
    }
    else
    {
      UINT nID = GetMenuItemID(j);
      pItemData = FindMenuList(nID);
      GetMenuString(j,string,MF_BYPOSITION);

      if(!pItemData)
      {
        pItemData = NewODMenu(j,state|MF_BYPOSITION|MF_OWNERDRAW,nID,string);
      }
      else
      {
        pItemData->m_nFlags = state|MF_BYPOSITION|MF_OWNERDRAW;
        if(string.GetLength()>0)
        {
          pItemData->SetString(string);
        }
        ModifyMenu(j,pItemData->m_nFlags,nID,(LPCTSTR)pItemData);
      }
    }
    if(pItemData)
    {
      temp.Add(pItemData);
    }
  }
  DeleteMenuList();
  m_MenuItemList.RemoveAll();
  m_MenuItemList.Append(temp);
  temp.RemoveAll();
}

void CNewMenu::OnInitMenuPopup(HWND hWnd, CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
{
  UNREFERENCED_PARAMETER(nIndex);
  UNREFERENCED_PARAMETER(bSysMenu);

#ifdef _TRACE_MENU_
  AfxTrace(_T("InitMenuPopup: 0x%lx from Wnd 0x%lx\n"),HMenuToUInt(pPopupMenu->m_hMenu),HWndToUInt(hWnd));
#endif
  CNewMenuHook::m_hLastMenu = pPopupMenu->m_hMenu;

  if(IsMenu(pPopupMenu->m_hMenu))
  {
    CNewMenu* pSubMenu = DYNAMIC_DOWNCAST(CNewMenu,pPopupMenu);
    if(pSubMenu)
    {
      pSubMenu->m_hTempOwner = hWnd;
      pSubMenu->OnInitMenuPopup();
      HMENU hMenu = pSubMenu->GetParent();
      CNewMenu* pParent = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(hMenu));
      if(pParent)
      {
        pParent->m_dwOpenMenu += 1;
        if(pParent->m_dwOpenMenu==1 && !pParent->m_bIsPopupMenu)
        {
          // Redraw the menubar for the shade
          CRect rect = pParent->GetLastActiveMenuRect();
          if(!rect.IsRectEmpty())
          {
            rect.InflateRect(0,0,10,10);
            CPoint Point(0,0);
            ClientToScreen(hWnd,&Point);
            rect.OffsetRect(-Point);
            RedrawWindow(hWnd,rect,0,RDW_FRAME|RDW_INVALIDATE);
          }
        }
      }
    }
  }
}

BOOL CNewMenu::Replace(UINT nID, UINT nNewID)
{
  int nLoc=0;
  CNewMenu* pTempMenu = FindMenuOption(nID,nLoc);
  if(pTempMenu && nLoc >= 0)
  {
#ifdef _TRACE_MENU_
    AfxTrace(_T("Replace MenuID 0x%X => 0x%X\n"),nID,nNewID);
#endif
    CNewMenuItemData* pData = pTempMenu->m_MenuItemList[nLoc];
    UINT nFlags = pData->m_nFlags|MF_OWNERDRAW|MF_BYPOSITION;
    pData->m_nID = nNewID;
    return pTempMenu->ModifyMenu(nLoc,nFlags,nNewID,(LPCTSTR)pData);
  }
  return FALSE;
}

void CNewMenu::OnInitMenuPopup()
{
  m_bIsPopupMenu = true;
  SynchronizeMenu();
  // Special purpose for windows XP with themes!!!
  if(g_Shell==WinXP)
  {
    Replace(SC_RESTORE,SC_RESTORE+1);
    Replace(SC_CLOSE,SC_CLOSE+1);
    Replace(SC_MINIMIZE,SC_MINIMIZE+1);
  }
}

BOOL CNewMenu::OnUnInitPopupMenu()
{
#ifdef _TRACE_MENU_
  AfxTrace(_T("UnInitMenuPopup: 0x%lx\n"),HMenuToUInt(m_hMenu));
#endif
  if(g_Shell==WinXP)
  {
    // Special purpose for windows XP with themes!!!
    // Restore old values otherwise you have disabled windowbuttons
    Replace(SC_MINIMIZE+1,SC_MINIMIZE);
    Replace(SC_RESTORE+1,SC_RESTORE);
    if(Replace(SC_CLOSE+1,SC_CLOSE))
    {
      //EnableMenuItem(SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
      SetWindowPos(m_hTempOwner,0,0,0,0,0,SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER);
    }
    //Replace(SC_RESTORE+1,SC_RESTORE);
    //Replace(SC_MINIMIZE+1,SC_MINIMIZE);
  }

  HMENU hMenu = GetParent();
  CNewMenu* pParent = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(hMenu));
  if(pParent)
  {
    pParent->m_dwOpenMenu -= 1;
    if(pParent->m_dwOpenMenu>=NULL && !pParent->m_bIsPopupMenu)
    {
      pParent->m_dwOpenMenu = 0;
      // Redraw the menubar for the shade
      CRect rect = pParent->GetLastActiveMenuRect();
      if(!rect.IsRectEmpty())
      {
        rect.InflateRect(0,0,10,10);
        CPoint Point(0,0);
        ClientToScreen(m_hTempOwner,&Point);
        rect.OffsetRect(-Point);
        RedrawWindow(m_hTempOwner,rect,0,RDW_FRAME|RDW_INVALIDATE);
      }
      return TRUE;
    }
  }
  return FALSE;
}

LRESULT CNewMenu::FindKeyboardShortcut(UINT nChar, UINT nFlags, CMenu* pMenu)
{
  UNREFERENCED_PARAMETER(nFlags);

  CNewMenu* pNewMenu = DYNAMIC_DOWNCAST(CNewMenu,pMenu);
  if(pNewMenu)
  {
    //SK: modified for Unicode correctness
    CString key(_T('&'),2);
    key.SetAt(1,(TCHAR)nChar);
    key.MakeLower();
    CString menutext;
    int menusize = (int)pNewMenu->GetMenuItemCount();
    if(menusize!=(pNewMenu->m_MenuItemList.GetSize()))
    {
      pNewMenu->SynchronizeMenu();
    }
    for(int i=0;i<menusize;++i)
    {
      if(pNewMenu->GetMenuText(i,menutext))
      {
        menutext.MakeLower();
        if(menutext.Find(key)>=0)
        {
          return(MAKELRESULT(i,2));
        }
      }
    }
  }
  return NULL;
}

BOOL CNewMenu::AddBitmapToImageList(CImageList* bmplist,UINT nResourceID)
{
  // O.S.
  if (m_bDynIcons)
  {
    bmplist->Add((HICON)(UINT_PTR)nResourceID);
    return TRUE;
  }

  CBitmap mybmp;
  HBITMAP hbmp = LoadSysColorBitmap(nResourceID);
  if(hbmp)
  {
    // Object will be destroyd by destructor of CBitmap
    mybmp.Attach(hbmp);
  }
  else
  {
    mybmp.LoadBitmap(nResourceID);
  }

  if (mybmp.m_hObject && bmplist->Add(&mybmp,GetBitmapBackground())>=0 )
  {
    return TRUE;
  }

  return FALSE;
}

COLORREF CNewMenu::SetBitmapBackground(COLORREF newColor)
{
  COLORREF oldColor = m_bitmapBackground;
  m_bitmapBackground = newColor;
  return oldColor;
}

COLORREF CNewMenu::GetBitmapBackground()
{
  if(m_bitmapBackground==CLR_DEFAULT)
    return GetSysColor(COLOR_3DFACE);

  return m_bitmapBackground;
}

BOOL CNewMenu::Draw3DCheckmark(CDC *pDC, CRect rect, HBITMAP hbmpChecked, HBITMAP hbmpUnchecked, DWORD dwState)
{
  if(dwState&ODS_CHECKED || hbmpUnchecked)
  {
    rect.InflateRect(-1,-1);

    if (IsNewShell()) //SK: looks better on the old shell
    {
      pDC->DrawEdge(rect, BDR_SUNKENOUTER, BF_RECT);
    }

    rect.InflateRect (2,2);
    if(dwState&ODS_CHECKED)
    {
      if (!hbmpChecked)
      { // Checkmark
        rect.OffsetRect(1,2);
        DrawSpecialCharStyle(pDC,rect,98,dwState);
      }
      else if(!hbmpUnchecked)
      { // Bullet
        DrawSpecialCharStyle(pDC,rect,105,dwState);
      }
      else
      {
        // Draw Bitmap
        BITMAP myInfo = {0};
        GetObject((HGDIOBJ)hbmpChecked,sizeof(myInfo),&myInfo);
        CPoint Offset = rect.TopLeft() + CPoint((rect.Width()-myInfo.bmWidth)/2,(rect.Height()-myInfo.bmHeight)/2);
        pDC->DrawState(Offset,CSize(0,0),hbmpChecked,DST_BITMAP|DSS_MONO);
      }
    }
    else
    {
      // Draw Bitmap
      BITMAP myInfo = {0};
      GetObject((HGDIOBJ)hbmpUnchecked,sizeof(myInfo),&myInfo);
      CPoint Offset = rect.TopLeft() + CPoint((rect.Width()-myInfo.bmWidth)/2,(rect.Height()-myInfo.bmHeight)/2);
      if(dwState & ODS_DISABLED)
      {
        pDC->DrawState(Offset,CSize(0,0),hbmpUnchecked,DST_BITMAP|DSS_MONO|DSS_DISABLED);
      }
      else
      {
        pDC->DrawState(Offset,CSize(0,0),hbmpUnchecked,DST_BITMAP|DSS_MONO);
      }
    }
    return TRUE;
  }
  return FALSE;
}

HBITMAP CNewMenu::LoadSysColorBitmap(int nResourceId)
{
  HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(nResourceId),RT_BITMAP);
  HRSRC hRsrc = ::FindResource(hInst,MAKEINTRESOURCE(nResourceId),RT_BITMAP);
  if (hRsrc == NULL)
  {
    return NULL;
  }

  // determine how many colors in the bitmap
  HGLOBAL hglb;
  if ((hglb = LoadResource(hInst, hRsrc)) == NULL)
  {
    return NULL;
  }
  LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hglb);
  if (lpBitmap == NULL)
  {
    return NULL;
  }
  WORD numcol = NumBitmapColors(lpBitmap);
  ::FreeResource(hglb);

  if(numcol!=16)
  {
    return(NULL);
  }
  return AfxLoadSysColorBitmap(hInst, hRsrc, FALSE);
}

// sPos means Seperator's position, since we have no way to find the
// seperator's position in the menu we have to specify them when we call the
// RemoveMenu to make sure the unused seperators are removed;
// sPos  = None no seperator removal;
//       = Head  seperator in front of this menu item;
//       = Tail  seperator right after this menu item;
//       = Both  seperators at both ends;
// remove the menu item based on their text, return -1 if not found, otherwise
// return the menu position;
int CNewMenu::RemoveMenu(LPCTSTR pText, ESeperator sPos)
{
  int nPos = GetMenuPosition(pText);
  if(nPos != -1)
  {
    switch (sPos)
    {
    case CNewMenu::NONE:
      RemoveMenu(nPos, MF_BYPOSITION);
      break;

    case CNewMenu::HEAD:
      ASSERT(nPos - 1 >= 0);
      RemoveMenu(nPos-1, MF_BYPOSITION);
      break;

    case CNewMenu::TAIL:
      RemoveMenu(nPos+1, MF_BYPOSITION);
      break;

    case CNewMenu::BOTH:
      // remove the end first;
      RemoveMenu(nPos+1, MF_BYPOSITION);
      // remove the head;
      ASSERT(nPos - 1 >= 0);
      RemoveMenu(nPos-1, MF_BYPOSITION);
      break;
    }
  }
  return nPos;
}

BOOL CNewMenu::RemoveMenu(UINT uiId, UINT nFlags)
{
  if(MF_BYPOSITION&nFlags)
  {
    UINT nItemState = GetMenuState(uiId,MF_BYPOSITION);
    if((nItemState&MF_SEPARATOR) && !(nItemState&MF_POPUP))
    {
      CNewMenuItemData* pData =  m_MenuItemList.GetAt(uiId);
      m_MenuItemList.RemoveAt(uiId);
      delete pData;
    }
    else
    {
      CMenu* pSubMenu = GetSubMenu(uiId);
      if(NULL==pSubMenu)
      {
        UINT uiCommandId = GetMenuItemID(uiId);
        for(int i=0;i<m_MenuItemList.GetSize(); i++)
        {
          if(m_MenuItemList[i]->m_nID==uiCommandId)
          {
            CNewMenuItemData* pData = m_MenuItemList.GetAt(i);
            m_MenuItemList.RemoveAt(i);
            delete pData;
            break;
          }
        }
      }
      else
      {
        // Only remove the menu.
        int numSubMenus = (int)m_SubMenus.GetSize();
        while(numSubMenus--)
        {
          if(m_SubMenus[numSubMenus]==pSubMenu->m_hMenu)
          {
            m_SubMenus.RemoveAt(numSubMenus);
          }
        }
        numSubMenus = (int)m_MenuItemList.GetSize();
        while(numSubMenus--)
        {
          if(m_MenuItemList[numSubMenus]->m_nID==HMenuToUInt(pSubMenu->m_hMenu) )
          {
            CNewMenuItemData* pData = m_MenuItemList.GetAt(numSubMenus);
            m_MenuItemList.RemoveAt(numSubMenus);
            delete pData;
            break;
          }
        }
        // Don't delete it's only remove
        //delete pSubMenu;
      }
    }
  }
  else
  {
    int iPosition =0;
    CNewMenu* pMenu = FindMenuOption(uiId,iPosition);
    if(pMenu)
    {
      return pMenu->RemoveMenu(iPosition,MF_BYPOSITION);
    }
  }
  return CMenu::RemoveMenu(uiId,nFlags);
}

BOOL CNewMenu::DeleteMenu(UINT uiId, UINT nFlags)
{
  if(MF_BYPOSITION&nFlags)
  {
    UINT nItemState = GetMenuState(uiId,MF_BYPOSITION);
    if( (nItemState&MF_SEPARATOR) && !(nItemState&MF_POPUP))
    {
      CNewMenuItemData* pData = m_MenuItemList.GetAt(uiId);
      m_MenuItemList.RemoveAt(uiId);
      delete pData;
    }
    else
    {
      CMenu* pSubMenu = GetSubMenu(uiId);
      if(NULL==pSubMenu)
      {
        UINT uiCommandId = GetMenuItemID(uiId);
        for(int i=0;i<m_MenuItemList.GetSize(); i++)
        {
          if(m_MenuItemList[i]->m_nID==uiCommandId)
          {
            CNewMenuItemData* pData = m_MenuItemList.GetAt(i);
            m_MenuItemList.RemoveAt(i);
            delete pData;
          }
        }
      }
      else
      {
        BOOL bCanDelete = FALSE;
        int numSubMenus = (int)m_SubMenus.GetSize();
        while(numSubMenus--)
        {
          if(m_SubMenus[numSubMenus]==pSubMenu->m_hMenu)
          {
            m_SubMenus.RemoveAt(numSubMenus);
            bCanDelete = TRUE;
          }
        }

        numSubMenus = (int)m_MenuItemList.GetSize();
        while(numSubMenus--)
        {
          if(m_MenuItemList[numSubMenus]->m_nID==HMenuToUInt(pSubMenu->m_hMenu) )
          {
            CNewMenuItemData* pData = m_MenuItemList.GetAt(numSubMenus);
            m_MenuItemList.RemoveAt(numSubMenus);
            delete pData;
            break;
          }
        }
        // Did we created the menu
        if(bCanDelete)
        { // Oh yes so we can destroy it
          delete pSubMenu;
        }
      }
    }
  }
  else
  {
    int iPosition =0;
    CNewMenu* pMenu = FindMenuOption(uiId,iPosition);
    if(pMenu)
    {
      return pMenu->DeleteMenu(iPosition,MF_BYPOSITION);
    }
  }
  return CMenu::DeleteMenu(uiId,nFlags);
}

BOOL CNewMenu::AppendMenu(UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem, int nIconNormal)
{
  return AppendODMenu(lpszNewItem,nFlags,nIDNewItem,nIconNormal);
}

BOOL CNewMenu::AppendMenu(UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem, CImageList* il, int xoffset)
{
  return AppendODMenu(lpszNewItem,nFlags,nIDNewItem,il,xoffset);
}

BOOL CNewMenu::AppendMenu(UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem, CBitmap* bmp)
{
  return AppendODMenu(lpszNewItem,nFlags,nIDNewItem,bmp);
}

BOOL CNewMenu::InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem, int nIconNormal)
{
  return InsertODMenu(nPosition,lpszNewItem,nFlags,nIDNewItem,nIconNormal);
}

BOOL CNewMenu::InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem, CImageList* il, int xoffset)
{
  return InsertODMenu(nPosition,lpszNewItem,nFlags,nIDNewItem,il,xoffset);
}

BOOL CNewMenu::InsertMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem, LPCTSTR lpszNewItem, CBitmap* bmp)
{
  return InsertODMenu(nPosition,lpszNewItem,nFlags,nIDNewItem,bmp);
}

CNewMenu* CNewMenu::AppendODPopupMenu(LPCTSTR lpstrText)
{
  CNewMenu* pSubMenu = new CNewMenu(m_hMenu);
  pSubMenu->m_unselectcheck=m_unselectcheck;
  pSubMenu->m_selectcheck=m_selectcheck;
  pSubMenu->m_checkmaps=m_checkmaps;
  pSubMenu->m_checkmapsshare=TRUE;
  pSubMenu->CreatePopupMenu();
  if(AppendODMenu(lpstrText,MF_POPUP,HMenuToUInt(pSubMenu->m_hMenu), -1))
  {
    m_SubMenus.Add(pSubMenu->m_hMenu);
    return pSubMenu;
  }
  delete pSubMenu;
  return NULL;
}

CMenu* CNewMenu::GetSubMenu(int nPos) const
{
  return CMenu::GetSubMenu (nPos);
}

CMenu* CNewMenu::GetSubMenu(LPCTSTR lpszSubMenuName) const
{
  int num = GetMenuItemCount ();
  CString name;
  MENUITEMINFO info = {0};

  for (int i=0; i<num; i++)
  {
    GetMenuString (i, name, MF_BYPOSITION);
    // fix from George Menhorn
    if(name.IsEmpty())
    {
      info.cbSize = sizeof (MENUITEMINFO);
      info.fMask = MIIM_DATA;
      ::GetMenuItemInfo(m_hMenu, i, TRUE, &info);

      CNewMenuItemData* pItemData = CheckMenuItemData(info.dwItemData);
      if (pItemData)
      {
        name = pItemData->GetString(m_bDrawAccelerators ? m_hAccelToDraw : NULL);
      }
    }

    if (name.Compare (lpszSubMenuName) == 0)
    {
      return CMenu::GetSubMenu (i);
    }
  }
  return NULL;
}

// Tongzhe Cui, Functions to remove a popup menu based on its name. Seperators
// before and after the popup menu can also be removed if they exist.
int CNewMenu::GetMenuPosition(LPCTSTR pText)
{
  for(int i=0;i<(int)(GetMenuItemCount());++i)
  {
    if(!GetSubMenu(i))
    {
      for(int j=0;j<m_MenuItemList.GetSize();++j)
      {
        if(m_MenuItemList[j]->m_szMenuText.Compare(pText)==NULL)
        {
          return j;
        }
      }
    }
  }
  // means no found;
  return -1;
}

BOOL CNewMenu::RemoveMenuTitle()
{
  int numMenuItems = (int)m_MenuItemList.GetSize();

  // We need a seperator at the beginning of the menu
  if(!numMenuItems || !((m_MenuItemList[0]->m_nFlags)&MF_SEPARATOR) )
  {
    return FALSE;
  }
  CNewMenuItemData* pMenuData = m_MenuItemList[0];
  // Check for title
  if(pMenuData->m_nTitleFlags&MFT_TITLE)
  {
    if(numMenuItems>0)
    {
      CNewMenuItemData* pMenuNextData = m_MenuItemList[1];
      if((pMenuNextData->m_nFlags&MF_MENUBREAK))
      {
        pMenuNextData->m_nFlags &= ~MF_MENUBREAK;
        CMenu::ModifyMenu(1,MF_BYPOSITION|pMenuNextData->m_nFlags,pMenuNextData->m_nID,(LPCTSTR)pMenuNextData);
      }
    }
    // Now remove the title
    RemoveMenu(0,MF_BYPOSITION);
    return TRUE;
  }
  return FALSE;
}

BOOL CNewMenu::SetMenuTitle(LPCTSTR pTitle, UINT nTitleFlags, int nIconNormal)
{
  int nIndex = -1;
  CNewMenuIconLock iconLock(GetMenuIcon(nIndex,nIconNormal));
  return SetMenuTitle(pTitle,nTitleFlags,iconLock,nIndex);
}

BOOL CNewMenu::SetMenuTitle(LPCTSTR pTitle, UINT nTitleFlags, CBitmap* pBmp)
{
  int nIndex = -1;
  CNewMenuIconLock iconLock(GetMenuIcon(nIndex,pBmp));
  return SetMenuTitle(pTitle,nTitleFlags,iconLock,nIndex);
}

BOOL CNewMenu::SetMenuTitle(LPCTSTR pTitle, UINT nTitleFlags, CImageList *pil, int xoffset)
{
  int nIndex = -1;
  CNewMenuIconLock iconLock(GetMenuIcon(nIndex,0,pil,xoffset));
  return SetMenuTitle(pTitle,nTitleFlags,iconLock,nIndex);
}

BOOL CNewMenu::SetMenuTitle(LPCTSTR pTitle, UINT nTitleFlags, CNewMenuIcons* pIcons, int nIndex)
{
  // Check if menu is valid
  if(!::IsMenu(m_hMenu))
  {
    return FALSE;
  }
  // Check the menu integrity
  if((int)GetMenuItemCount()!=(int)m_MenuItemList.GetSize())
  {
    SynchronizeMenu();
  }
  int numMenuItems = (int)m_MenuItemList.GetSize();
  // We need a seperator at the beginning of the menu
  if(!numMenuItems || !((m_MenuItemList[0]->m_nFlags)&MF_SEPARATOR) )
  {
    // We add the special menu item for title
    CNewMenuItemData *pItemData = new CNewMenuItemDataTitle;
    m_MenuItemList.InsertAt(0,pItemData);
    pItemData->SetString(pTitle);
    pItemData->m_nFlags = MF_BYPOSITION|MF_SEPARATOR|MF_OWNERDRAW;

    VERIFY(CMenu::InsertMenu(0,MF_SEPARATOR|MF_BYPOSITION,0,pItemData->m_szMenuText));
    VERIFY(CMenu::ModifyMenu(0, MF_BYPOSITION|MF_SEPARATOR|MF_OWNERDRAW, 0, (LPCTSTR)pItemData ));

    //InsertMenu(0,MF_SEPARATOR|MF_BYPOSITION);
  }

  numMenuItems = (int)m_MenuItemList.GetSize();
  if(numMenuItems)
  {
    CNewMenuItemData* pMenuData = m_MenuItemList[0];
    if(pMenuData->m_nFlags&MF_SEPARATOR)
    {
      pIcons->AddRef();
      pMenuData->m_pMenuIcon->Release();
      pMenuData->m_pMenuIcon = pIcons;
      if(pIcons && nIndex>=0)
      {
        pMenuData->m_nMenuIconOffset = nIndex;
        //CSize size = pIcons->GetIconSize();
        //m_iconX = max(m_iconX,size.cx);
        //m_iconY = max(m_iconY,size.cy);
      }
      else
      {
        pMenuData->m_nMenuIconOffset = -1;
      }
      pMenuData->SetString(pTitle);
      pMenuData->m_nTitleFlags = nTitleFlags|MFT_TITLE;

      if(numMenuItems>1)
      {
        CNewMenuItemData* pMenuData = m_MenuItemList[1];

        if(nTitleFlags&MFT_SIDE_TITLE)
        {
          if(!(pMenuData->m_nFlags&MF_MENUBREAK))
          {
            pMenuData->m_nFlags |= MF_MENUBREAK;
            CMenu::ModifyMenu(1,MF_BYPOSITION|pMenuData->m_nFlags,pMenuData->m_nID,(LPCTSTR)pMenuData);
          }
        }
        else
        {
          if((pMenuData->m_nFlags&MF_MENUBREAK))
          {
            pMenuData->m_nFlags &= ~MF_MENUBREAK;
            CMenu::ModifyMenu(1,MF_BYPOSITION|pMenuData->m_nFlags,pMenuData->m_nID,(LPCTSTR)pMenuData);
          }
        }
        return TRUE;
      }
    }
  }
  return FALSE;
}

CNewMenuItemDataTitle* CNewMenu::GetMemuItemDataTitle()
{
  // Check if menu is valid
  if(!this || !::IsMenu(m_hMenu))
  {
    return NULL;
  }
  // Check the menu integrity
  if((int)GetMenuItemCount()!=(int)m_MenuItemList.GetSize())
  {
    SynchronizeMenu();
  }

  if(m_MenuItemList.GetSize()>0)
  {
    return DYNAMIC_DOWNCAST(CNewMenuItemDataTitle,m_MenuItemList[0]);
  }
  return NULL;
}


BOOL CNewMenu::SetMenuTitleColor(COLORREF clrTitle, COLORREF clrLeft, COLORREF clrRight)
{
  CNewMenuItemDataTitle* pItem = GetMemuItemDataTitle();
  if(pItem)
  {
    pItem->m_clrTitle = clrTitle;
    pItem->m_clrLeft = clrLeft;
    pItem->m_clrRight = clrRight;
    return TRUE;
  }
  return FALSE;
}

BOOL CNewMenu::SetMenuText(UINT id, CString string, UINT nFlags/*= MF_BYPOSITION*/ )
{
  if(MF_BYPOSITION&nFlags)
  {
    int numMenuItems = (int)m_MenuItemList.GetSize();
    if(id<UINT(numMenuItems))
    {
      // get current menu state so it doesn't change
      UINT nState = GetMenuState(id, MF_BYPOSITION);
      nState &= ~(MF_BITMAP|MF_OWNERDRAW|MF_SEPARATOR);
      // change the menutext
      CNewMenuItemData* pItemData = m_MenuItemList[id];
      pItemData->SetString(string);

      if(CMenu::ModifyMenu(id,MF_BYPOSITION|MF_STRING | nState, pItemData->m_nID, string))
      {
        return ModifyMenu(id,MF_BYPOSITION | MF_OWNERDRAW,pItemData->m_nID,(LPCTSTR)pItemData);
      }
    }
  }
  else
  {
    int uiLoc;
    CNewMenu* pMenu = FindMenuOption(id,uiLoc);
    if(NULL!=pMenu)
    {
      return pMenu->SetMenuText(uiLoc,string);
    }
  }
  return FALSE;
}

// courtesy of Warren Stevens
void CNewMenu::ColorBitmap(CDC* pDC, CBitmap& bmp, CSize size, COLORREF fill, COLORREF border, int hatchstyle)
{
  // Create a memory DC
  CDC MemDC;
  MemDC.CreateCompatibleDC(pDC);
  bmp.CreateCompatibleBitmap(pDC, size.cx, size.cy);
  CPen border_pen(PS_SOLID, 1, border);

  CBrush fill_brush;
  if(hatchstyle!=-1)
  {
    fill_brush.CreateHatchBrush(hatchstyle, fill);
  }
  else
  {
    fill_brush.CreateSolidBrush(fill);
  }

  CBitmap* pOldBitmap = MemDC.SelectObject(&bmp);
  CPen*    pOldPen    = MemDC.SelectObject(&border_pen);
  CBrush*  pOldBrush  = MemDC.SelectObject(&fill_brush);

  MemDC.Rectangle(0,0, size.cx, size.cy);

  if(NULL!=pOldBrush)  { MemDC.SelectObject(pOldBrush);  }
  if(NULL!=pOldPen)    { MemDC.SelectObject(pOldPen);    }
  if(NULL!=pOldBitmap) { MemDC.SelectObject(pOldBitmap); }
}

void CNewMenu::DrawSpecial_OldStyle(CDC* pDC, LPCRECT pRect, UINT nID, DWORD dwStyle)
{
  COLORREF oldColor;
  if( (dwStyle&ODS_GRAYED) || (dwStyle&ODS_INACTIVE))
  {
    oldColor = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
  }
  else if (dwStyle&ODS_SELECTED)
  {
    oldColor = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
  }
  else
  {
    oldColor = pDC->SetTextColor(::GetSysColor(COLOR_MENUTEXT));
  }
  BOOL bBold = (dwStyle&ODS_DEFAULT) ? TRUE : FALSE;

  switch(nID&0xfff0)
  {
  case SC_MINIMIZE:
    DrawSpecialChar(pDC,pRect,48,bBold); // Min
    break;
  case SC_MAXIMIZE:
    DrawSpecialChar(pDC,pRect,49,bBold); // Max
    break;
  case SC_CLOSE:
    DrawSpecialChar(pDC,pRect,114,bBold); // Close
    break;
  case SC_RESTORE:
    DrawSpecialChar(pDC,pRect,50,bBold); // restore
    break;
  }
  pDC->SetTextColor(oldColor);
}

void CNewMenu::DrawSpecial_WinXP(CDC* pDC, LPCRECT pRect, UINT nID, DWORD dwStyle)
{
  TCHAR cSign = 0;
  switch(nID&0xfff0)
  {
  case SC_MINIMIZE:
    cSign = 48; // Min
    break;
  case SC_MAXIMIZE:
    cSign = 49;// Max
    break;
  case SC_CLOSE:
    cSign = 114;// Close
    break;
  case SC_RESTORE:
    cSign = 50;// Restore
    break;
  }
  if(cSign)
  {
    COLORREF oldColor;
    BOOL bBold = (dwStyle&ODS_DEFAULT) ? TRUE : FALSE;
    CRect rect(pRect);
    rect.InflateRect(0,(m_iconY-rect.Height())>>1);


    if( (dwStyle&ODS_GRAYED) || (dwStyle&ODS_INACTIVE))
    {
      oldColor = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
    }
    else if(dwStyle&ODS_SELECTED)
    {
      oldColor = pDC->SetTextColor(DarkenColorXP(GetXpHighlightColor()));
      rect.OffsetRect(1,1);
      DrawSpecialChar(pDC,rect,cSign,bBold);
      pDC->SetTextColor(::GetSysColor(COLOR_MENUTEXT));
      rect.OffsetRect(-2,-2);
    }
    else
    {
      oldColor = pDC->SetTextColor(::GetSysColor(COLOR_MENUTEXT));
    }
    DrawSpecialChar(pDC,rect,cSign,bBold);

    pDC->SetTextColor(oldColor);
  }
}

CRect CNewMenu::GetLastActiveMenuRect()
{
  return m_LastActiveMenuRect;
}

void CNewMenu::DrawSpecialCharStyle(CDC* pDC, LPCRECT pRect, TCHAR Sign, DWORD dwStyle)
{
  COLORREF oldColor;
  if( (dwStyle&ODS_GRAYED) || (dwStyle&ODS_INACTIVE))
  {
    oldColor = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
  }
  else
  {
    oldColor = pDC->SetTextColor(::GetSysColor(COLOR_MENUTEXT));
  }

  DrawSpecialChar(pDC,pRect,Sign,(dwStyle&ODS_DEFAULT) ? TRUE : FALSE);

  pDC->SetTextColor(oldColor);
}

void CNewMenu::DrawSpecialChar(CDC* pDC, LPCRECT pRect, TCHAR Sign, BOOL bBold)
{
  //  48 Min
  //  49 Max
  //  50 Restore
  //  98 Checkmark
  // 105 Bullet
  // 114 Close

  CFont MyFont;
  LOGFONT logfont;

  CRect rect(pRect);
  rect.DeflateRect(2,2);

  logfont.lfHeight = -rect.Height();
  logfont.lfWidth = 0;
  logfont.lfEscapement = 0;
  logfont.lfOrientation = 0;
  logfont.lfWeight = (bBold) ? FW_BOLD:FW_NORMAL;
  logfont.lfItalic = FALSE;
  logfont.lfUnderline = FALSE;
  logfont.lfStrikeOut = FALSE;
  logfont.lfCharSet = DEFAULT_CHARSET;
  logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
  logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  logfont.lfQuality = DEFAULT_QUALITY;
  logfont.lfPitchAndFamily = DEFAULT_PITCH;

  _tcscpy_s(logfont.lfFaceName,ARRAY_SIZE(logfont.lfFaceName),_T("Marlett"));

  MyFont.CreateFontIndirect (&logfont);

  CFont* pOldFont = pDC->SelectObject (&MyFont);
  int OldMode = pDC->SetBkMode(TRANSPARENT);

  pDC->DrawText (&Sign,1,rect,DT_CENTER|DT_SINGLELINE);

  pDC->SetBkMode(OldMode);
  pDC->SelectObject(pOldFont);
}

//
// Construction/Destruction
//

CMenuTheme::CMenuTheme()
: m_dwThemeId(0),
m_dwFlags(0),
m_pMeasureItem(NULL),
m_pDrawItem(NULL),
m_pDrawTitle(NULL),
m_BorderTopLeft(0,0),
m_BorderBottomRight(0,0)
{
}

CMenuTheme::CMenuTheme( DWORD dwThemeId,
                       pItemMeasureFkt pMeasureItem,
                       pItemDrawFkt pDrawItem,
                       pItemDrawFkt pDrawTitle,
                       DWORD dwFlags)
                       :m_dwThemeId(dwThemeId),
                       m_dwFlags(dwFlags),
                       m_pMeasureItem(pMeasureItem),
                       m_pDrawItem(pDrawItem),
                       m_pDrawTitle(pDrawTitle)
{
  UpdateSysColors();
  UpdateSysMetrics();
}

CMenuTheme::~CMenuTheme()
{
}

void CMenuTheme::DrawFrame(CDC* pDC, CRect rectOuter, CRect rectInner, COLORREF crBorder)
{
  CRect Temp;
  rectInner.right -= 1;
  // Border top
  Temp.SetRect(rectOuter.TopLeft(),CPoint(rectOuter.right,rectInner.top));
  pDC->FillSolidRect(Temp,crBorder);
  // Border bottom
  Temp.SetRect(CPoint(rectOuter.left,rectInner.bottom),rectOuter.BottomRight());
  pDC->FillSolidRect(Temp,crBorder);

  // Border left
  Temp.SetRect(rectOuter.TopLeft(),CPoint(rectInner.left,rectOuter.bottom));
  pDC->FillSolidRect(Temp,crBorder);
  // Border right
  Temp.SetRect(CPoint(rectInner.right,rectOuter.top),rectOuter.BottomRight());
  pDC->FillSolidRect(Temp,crBorder);
}

BOOL CMenuTheme::DoDrawBorder()
{
  return (m_dwFlags&1)?TRUE:FALSE;
}

void CMenuTheme::DrawSmalBorder( HWND hWnd, HDC hDC)
{
  CNewMenuHook::CMenuHookData* pData = CNewMenuHook::GetMenuHookData(hWnd);
  if(pData!=NULL)
  {
    if(pData->m_hMenu)
    {
      CNewMenu* pMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(pData->m_hMenu));
      if(pMenu && pMenu->GetParent())
      {
        CNewMenu* pParentMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(pMenu->GetParent()));
        if(pParentMenu && !pParentMenu->IsPopup())
        {
          CRect Rect;
          // Get the size of the menu...
          GetWindowRect(hWnd, Rect );
          Rect.OffsetRect(pData->m_Point - Rect.TopLeft());
          Rect &= pParentMenu->GetLastActiveMenuRect();
          if(!Rect.IsRectEmpty())
          {
            if(Rect.Width()>Rect.Height())
            {
              Rect.InflateRect(-1,0);
            }
            else
            {
              Rect.InflateRect(0,-1);
            }
            Rect.OffsetRect(-pData->m_Point);
            CDC* pDC = CDC::FromHandle(hDC);

            COLORREF colorSmalBorder;
            if (NumScreenColors() > 256)
            {
              colorSmalBorder = MixedColor(CNewMenu::GetMenuBarColor(),GetSysColor(COLOR_WINDOW));
            }
            else
            {
              colorSmalBorder = GetSysColor(COLOR_BTNFACE);
            }
            pDC->FillSolidRect(Rect,colorSmalBorder);
          }
        }
      }
    }
  }
}

void CMenuTheme::DrawShade( HWND hWnd, HDC hDC, CPoint screen)
{
  if(IsShadowEnabled())
    return;

  // Get the size of the menu...
  CRect Rect;
  GetWindowRect(hWnd, Rect );

  long winW = Rect.Width();
  long winH = Rect.Height();
  long xOrg = screen.x;
  long yOrg = screen.y;

  CNewMenuHook::CMenuHookData* pData = CNewMenuHook::GetMenuHookData(hWnd);

  CDC* pDC = CDC::FromHandle(hDC);
  CDC memDC;
  memDC.CreateCompatibleDC(pDC);
  CBitmap* pOldBitmap = memDC.SelectObject(&pData->m_Screen);

  HDC hDcDsk = memDC.m_hDC;
  xOrg = 0;
  yOrg = 0;

   Get the desktop hDC...
  //HDC hDcDsk = GetWindowDC(0);

  int X,Y;
  // Simulate a shadow on right edge...
  if (NumScreenColors() <= 256)
  {
    DWORD rgb = ::GetSysColor(COLOR_BTNSHADOW);
    BitBlt(hDC,winW-2,0,    2,winH,hDcDsk,xOrg+winW-2,0,SRCCOPY);
    BitBlt(hDC,0,winH-2,winW,2,hDcDsk,0,yOrg+winH-2,SRCCOPY);
    for (X=3; X<=4 ;X++)
    {
      for (Y=0; Y<4 ;Y++)
      {
        SetPixel(hDC,winW-X,Y,GetPixel(hDcDsk,xOrg+winW-X,yOrg+Y));
      }
      for (Y=4; Y<8 ;Y++)
      {
        SetPixel(hDC,winW-X,Y,rgb);
      }
      for (Y=8; Y<=(winH-5) ;Y++)
      {
        SetPixel( hDC, winW - X, Y, rgb);
      }
      for (Y=(winH-4); Y<=(winH-3) ;Y++)
      {
        SetPixel( hDC, winW - X, Y, rgb);
      }
    }
    // Simulate a shadow on the bottom edge...
    for(Y=3; Y<=4 ;Y++)
    {
      for(X=0; X<=3 ;X++)
      {
        SetPixel(hDC,X,winH-Y, GetPixel(hDcDsk,xOrg+X,yOrg+winH-Y));
      }
      for(X=4; X<=7 ;X++)
      {
        SetPixel( hDC, X, winH - Y, rgb);
      }
      for(X=8; X<=(winW-5) ;X++)
      {
        SetPixel( hDC, X, winH - Y, rgb);
      }
    }
  }
  else
  {
    for (X=1; X<=4 ;X++)
    {
      for (Y=0; Y<4 ;Y++)
      {
        SetPixel(hDC,winW-X,Y, GetPixel(hDcDsk,xOrg+winW-X,yOrg+Y) );
      }
      for (Y=4; Y<8 ;Y++)
      {
        COLORREF c = GetPixel(hDcDsk, xOrg + winW - X, yOrg + Y);
        SetPixel(hDC,winW-X,Y,DarkenColor(2* 3 * X * (Y - 3), c));
      }
      for (Y=8; Y<=(winH-5) ;Y++)
      {
        COLORREF c = GetPixel(hDcDsk, xOrg + winW - X, yOrg + Y);
        SetPixel( hDC, winW - X, Y, DarkenColor(2* 15 * X, c) );
      }
      for (Y=(winH-4); Y<=(winH-1) ;Y++)
      {
        COLORREF c = GetPixel(hDcDsk, xOrg + winW - X, yOrg + Y);
        SetPixel( hDC, winW - X, Y, DarkenColor(2* 3 * X * -(Y - winH), c));
      }
    }

    // Simulate a shadow on the bottom edge...
    for(Y=1; Y<=4 ;Y++)
    {
      for(X=0; X<=3 ;X++)
      {
        SetPixel(hDC,X,winH-Y, GetPixel(hDcDsk,xOrg+X,yOrg+winH-Y));
      }
      for(X=4; X<=7 ;X++)
      {
        COLORREF c = GetPixel(hDcDsk, xOrg + X, yOrg + winH - Y);
        SetPixel( hDC, X, winH - Y, DarkenColor(2*3 * (X - 3) * Y, c));
      }
      for(X=8; X<=(winW-5) ;X++)
      {
        COLORREF  c = GetPixel(hDcDsk, xOrg + X, yOrg + winH - Y);
        SetPixel( hDC, X, winH - Y, DarkenColor(2* 15 * Y, c));
      }
    }
  }

  memDC.SelectObject(pOldBitmap);

   Release the desktop hDC...
  //ReleaseDC(0,hDcDsk);
}

#define CX_GRIPPER  3
#define CY_GRIPPER  3
#define CX_BORDER_GRIPPER 2
#define CY_BORDER_GRIPPER 2

void CMenuTheme::UpdateSysColors()
{
	clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
	clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
	clrBtnHilite = ::GetSysColor(COLOR_BTNHIGHLIGHT);
	clrBtnText = ::GetSysColor(COLOR_BTNTEXT);
	clrWindowFrame = ::GetSysColor(COLOR_WINDOWFRAME);
}

void CMenuTheme::UpdateSysMetrics()
{
  m_BorderTopLeft = CSize(2,2);
  if(!IsShadowEnabled())
  {
    m_BorderBottomRight = CSize(5,6);
  }
  else
  {
    m_BorderBottomRight = CSize(2,2);
  }
}

void CMenuTheme::GetBarColor(COLORREF &clrUpperColor, COLORREF &clrMediumColor, COLORREF &clrBottomColor, COLORREF &clrDarkLine)
{
  if(IsMenuThemeActive())
  {
    COLORREF menuColor = CNewMenu::GetMenuBarColor2003();
    // corrections from Andreas Sch鋜er
    switch(menuColor)
    {
    case RGB(163,194,245)://blau
      {
        clrUpperColor = RGB(221,236,254);
        clrMediumColor = RGB(196, 219,249);
        clrBottomColor = RGB(129,169,226);
        clrDarkLine = RGB(59,97,156);
        break;
      }
    case RGB(215,215,229)://silber
      {
        clrUpperColor = RGB(243,244,250);
        clrMediumColor = RGB(225,226,236);
        clrBottomColor = RGB(153,151,181);
        clrDarkLine = RGB(124,124,148);
        break;
      }
    case RGB(218,218,170)://olivgr
      {
        clrUpperColor = RGB(244,247,222);
        clrMediumColor = RGB(209,222,172);
        clrBottomColor = RGB(183,198,145);
        clrDarkLine = RGB(96,128,88);
        break;
      }
    default:
      {
        clrUpperColor = LightenColor(140,menuColor);
        clrMediumColor = LightenColor(115,menuColor);
        clrBottomColor = DarkenColor(40,menuColor);
        clrDarkLine = DarkenColor(110,menuColor);
        break;
      }
    }
  }
  else
  {
    COLORREF menuColor, menuColor2;
    CNewMenu::GetMenuBarColor2003(menuColor, menuColor2, FALSE);
    clrUpperColor = menuColor2;
    clrBottomColor = menuColor;
    clrMediumColor = GetAlphaBlendColor(clrBottomColor, clrUpperColor,100);
    clrDarkLine = DarkenColor(50,clrBottomColor);
  }
}

void CMenuTheme::PaintCorner(CDC *pDC, LPCRECT pRect, COLORREF color)
{
  pDC->SetPixel(pRect->left+1,pRect->top  ,color);
  pDC->SetPixel(pRect->left+0,pRect->top  ,color);
  pDC->SetPixel(pRect->left+0,pRect->top+1,color);

  pDC->SetPixel(pRect->left+0,pRect->bottom  ,color);
  pDC->SetPixel(pRect->left+0,pRect->bottom-1,color);
  pDC->SetPixel(pRect->left+1,pRect->bottom  ,color);

  pDC->SetPixel(pRect->right-1,pRect->top  ,color);
  pDC->SetPixel(pRect->right  ,pRect->top  ,color);
  pDC->SetPixel(pRect->right  ,pRect->top+1,color);

  pDC->SetPixel(pRect->right-1,pRect->bottom  ,color);
  pDC->SetPixel(pRect->right  ,pRect->bottom  ,color);
  pDC->SetPixel(pRect->right  ,pRect->bottom-1,color);
}


void CMenuTheme::DrawGripper(CDC* pDC, const CRect& rect, DWORD dwStyle, 	
                             int m_cxLeftBorder, int m_cxRightBorder,
                             int m_cyTopBorder, int m_cyBottomBorder)
{
  // only draw the gripper if not floating and gripper is specified
  if ((dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER)
  {
    // draw the gripper in the border
    switch (CNewMenu::GetMenuDrawMode())
    {
    case CNewMenu::STYLE_XP:
    case CNewMenu::STYLE_XP_NOBORDER:
      {
        COLORREF col = DarkenColorXP(CNewMenu::GetMenuBarColorXP());
        CPen pen(PS_SOLID,0,col);
        CPen* pOld = pDC->SelectObject(&pen);
        if (dwStyle & CBRS_ORIENT_HORZ)
        {
          for (int n=rect.top+m_cyTopBorder+2*CY_BORDER_GRIPPER;n<rect.Height()-m_cyTopBorder-m_cyBottomBorder-4*CY_BORDER_GRIPPER;n+=2)
          {
            pDC->MoveTo(rect.left+CX_BORDER_GRIPPER+2,n);
            pDC->LineTo(rect.left+CX_BORDER_GRIPPER+CX_GRIPPER+2,n);
          }
        }
        else
        {
          for (int n=rect.top+m_cxLeftBorder+2*CX_BORDER_GRIPPER;n<rect.Width()-m_cxLeftBorder-m_cxRightBorder-2*CX_BORDER_GRIPPER;n+=2)
          {
            pDC->MoveTo(n,rect.top+CY_BORDER_GRIPPER+2);
            pDC->LineTo(n,rect.top+CY_BORDER_GRIPPER+CY_GRIPPER+2);
          }
        }
        pDC->SelectObject(pOld);
      }
      break;

    case CNewMenu::STYLE_ICY:
    case CNewMenu::STYLE_ICY_NOBORDER:
      {
        COLORREF color = DarkenColor(100,CNewMenu::GetMenuColor());
        if (dwStyle & CBRS_ORIENT_HORZ)
        {
          for (int n=rect.top+m_cyTopBorder+2*CY_BORDER_GRIPPER;n<rect.Height()-m_cyTopBorder-m_cyBottomBorder-4*CY_BORDER_GRIPPER;n+=4)
          {
            pDC->FillSolidRect(rect.left+CX_BORDER_GRIPPER+2+m_cxLeftBorder,n  +1,2,2,color);
          }
        }
        else
        {
          for (int n=rect.top+m_cxLeftBorder+2*CX_BORDER_GRIPPER;n<rect.Width()-m_cxRightBorder-2*CX_BORDER_GRIPPER;n+=4)
          {
            pDC->FillSolidRect(n,  rect.top+CY_BORDER_GRIPPER+2+m_cxLeftBorder,2,2,color);
          }
        }
      }
      break;

    case CNewMenu::STYLE_XP_2003_NOBORDER:
    case CNewMenu::STYLE_XP_2003:
    case CNewMenu::STYLE_COLORFUL_NOBORDER:
    case CNewMenu::STYLE_COLORFUL:
      {
        COLORREF clrUpperColor, clrMediumColor, clrBottomColor, clrDarkLine;
        CNewMenu::GetActualMenuTheme()->GetBarColor(clrUpperColor,clrMediumColor,clrBottomColor,clrDarkLine);

        COLORREF color1 = GetSysColor(COLOR_WINDOW);
        //COLORREF color2 = DarkenColor(40,MidColor(GetSysColor(COLOR_BTNFACE),color1));

        if (dwStyle & CBRS_ORIENT_HORZ)
        {
          for (int n=rect.top+m_cyTopBorder+2*CY_BORDER_GRIPPER;n<rect.Height()-m_cyTopBorder-m_cyBottomBorder-4*CY_BORDER_GRIPPER;n+=4)
          {
            pDC->FillSolidRect(rect.left+CX_BORDER_GRIPPER+3+m_cxLeftBorder,n+1+1,2,2,color1);
            pDC->FillSolidRect(rect.left+CX_BORDER_GRIPPER+2+m_cxLeftBorder,n  +1,2,2,clrDarkLine);
          }
        }
        else
        {
          for (int n=rect.top+m_cxLeftBorder+2*CX_BORDER_GRIPPER;n<rect.Width()-m_cxRightBorder-2*CX_BORDER_GRIPPER;n+=4)
          {
            pDC->FillSolidRect(n+1,rect.top+CY_BORDER_GRIPPER+3+m_cxLeftBorder,2,2,color1);
            pDC->FillSolidRect(n,  rect.top+CY_BORDER_GRIPPER+2+m_cxLeftBorder,2,2,clrDarkLine);
          }
        }
      }
      break;

    default:
      {
        //BPO late this can be eliminated (cached?)
	      clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
	      clrBtnHilite = ::GetSysColor(COLOR_BTNHIGHLIGHT);

        CRect temp = rect;
        //temp.left+=2;
        if (dwStyle & CBRS_ORIENT_HORZ)
        {
          pDC->Draw3dRect(rect.left+CX_BORDER_GRIPPER+m_cxLeftBorder,
                          rect.top+m_cyTopBorder,
                          CX_GRIPPER, rect.Height()-m_cyTopBorder-m_cyBottomBorder,
                          clrBtnHilite, clrBtnShadow);
        }
        else
        {
          temp.top+=2;
          pDC->Draw3dRect(rect.left+m_cyTopBorder,
                          rect.top+CY_BORDER_GRIPPER,
                          rect.Width()-m_cyTopBorder-m_cyBottomBorder, CY_GRIPPER,
                          clrBtnHilite, clrBtnShadow);
        }
      }
      break;
    }
  }
}

void CMenuTheme::DrawCorner(CDC* pDC, LPCRECT pRect, DWORD dwStyle)
{
  if ((dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER)
  {
    // draw the gripper in the border
    switch (CNewMenu::GetMenuDrawMode())
    {
    case CNewMenu::STYLE_ICY:
    case CNewMenu::STYLE_ICY_NOBORDER:
      {
        // make round corners
        COLORREF color = GetSysColor(COLOR_3DLIGHT);
        PaintCorner(pDC,pRect,color);
      }
      break;

    case CNewMenu::STYLE_XP_2003_NOBORDER:
    case CNewMenu::STYLE_XP_2003:
    case CNewMenu::STYLE_COLORFUL_NOBORDER:
    case CNewMenu::STYLE_COLORFUL:
      {
        // make round corners
        COLORREF color = CNewMenu::GetMenuBarColor2003();
        PaintCorner(pDC,pRect,color);
      }
      break;
    }
  }
}

void SetWindowShade(HWND hWndMenu, CNewMenuHook::CMenuHookData* pData );

#define CMS_MENUFADE            175
#define MENU_TIMER_ID 0x1234

BOOL CMenuTheme::OnInitWnd(HWND hWnd)
{
  CNewMenuHook::CMenuHookData* pData = CNewMenuHook::GetMenuHookData(hWnd);
  ASSERT(pData);
  if( pData->m_bDoSubclass)
  {
    if(!DoDrawBorder())
    {
      if(g_Shell>=Win2000 && CNewMenu::GetAlpha()!=255)
      {
        // Flag for changing styles
        pData->m_dwData |= 2;
        SetWindowLongPtr (hWnd, GWL_EXSTYLE,(pData->m_dwExStyle| WS_EX_LAYERED));
        SetLayeredWindowAttributes(hWnd, 0, CNewMenu::GetAlpha(), LWA_ALPHA);
        pData->m_dwData |= 4;
        SetTimer(hWnd,MENU_TIMER_ID,50,NULL);
      }
    }
    else
    {
      // Flag for changing styles
      pData->m_dwData |= 2;

      SetWindowLongPtr (hWnd, GWL_STYLE, pData->m_dwStyle & (~WS_BORDER) );

      if(g_Shell>=Win2000 && CNewMenu::GetAlpha()!=255)
      {
        SetWindowLongPtr (hWnd, GWL_EXSTYLE,(pData->m_dwExStyle| WS_EX_LAYERED) & ~(WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME));
        SetLayeredWindowAttributes(hWnd, 0, CNewMenu::GetAlpha(), LWA_ALPHA);
        pData->m_dwData |= 4;
        SetTimer(hWnd,MENU_TIMER_ID,50,NULL);
        //RedrawWindow(hWnd,NULL,NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);  
      }
      else
      {
        SetWindowLongPtr (hWnd, GWL_EXSTYLE,pData->m_dwExStyle & ~(WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME));
      }

      //if(!IsShadowEnabled())
      //{
      //  BOOL bAnimate = FALSE;
      //  if(SystemParametersInfo(SPI_GETMENUANIMATION,0,&bAnimate,0) && bAnimate==TRUE)
      //  {
      //    // All menuanimation should be terminated after 200 ms
      //    pData->m_TimerID = GetSafeTimerID(hWnd,200);
      //  }
      //  else
      //  {
      //    pData->m_TimerID = GetSafeTimerID(hWnd,500);
      //    //SetWindowShade(hWnd, pData);
      //  }
      //}

      return TRUE;
    }
  }
  return FALSE;
}

BOOL CMenuTheme::OnUnInitWnd(HWND hWnd)
{
  CNewMenuHook::CMenuHookData* pData = CNewMenuHook::GetMenuHookData(hWnd);
  if(pData)
  {
    if(pData->m_dwData&4)
    {
      KillTimer(hWnd,MENU_TIMER_ID);
      pData->m_dwData &= ~4;
    }
    HMENU hMenu = pData->m_hMenu;
    if(IsMenu(hMenu))
    {
      CNewMenu* pNewMenu = DYNAMIC_DOWNCAST(CNewMenu,CMenu::FromHandlePermanent(hMenu));

      if(pNewMenu)
      {
        // Redraw menubar on place.
        pNewMenu->OnUnInitPopupMenu();
      }
    }

     Destroy object and window for shading support
    //if(pData->m_TimerID)
    //{
    //  KillTimer(hWnd,pData->m_TimerID);
    //  pData->m_TimerID = NULL;
    //}
    //if(pData->m_hRightShade)
    //{
    //  DestroyWindow(pData->m_hRightShade);
    //  pData->m_hRightShade = NULL;
    //}
    //if(pData->m_hBottomShade)
    //{
    //  DestroyWindow(pData->m_hBottomShade);
    //  pData->m_hBottomShade = NULL;
    //}

    // were windows-style changed?
    if(pData->m_dwData&2)
    {
      SetLastError(0);
      if(!(pData->m_dwData&1))
      {
        SetWindowLongPtr (hWnd, GWL_STYLE,pData->m_dwStyle);
        ShowLastError(_T("Error from Menu: SetWindowLongPtr I"));
      }
      else
      {
        // Restore old Styles for special menu!!
        // (Menu 0x10012!!!) special VISIBLE flag must be set
        SetWindowLongPtr (hWnd, GWL_STYLE,pData->m_dwStyle|WS_VISIBLE);
        ShowLastError(_T("Error from Menu: SetWindowLongPtr I, Special"));
      }

      SetWindowLongPtr (hWnd, GWL_EXSTYLE, pData->m_dwExStyle);
      ShowLastError(_T("Error from Menu: SetWindowLongPtr II"));
      // Normaly when you change the style you shold call next function
      // but in this case you would lose the focus for the menu!!
      //SetWindowPos(hWnd,0,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED|SWP_HIDEWINDOW);
    }
  }
  return TRUE;
}

BOOL CMenuTheme::OnEraseBkgnd(HWND hWnd, HDC hDC)
{
  //  CNewMenuHook::CMenuHookData* pData = CNewMenuHook::GetMenuHookData(hWnd);

  //  Get the size of the menu...
  CDC* pDC = CDC::FromHandle (hDC);
  CRect Rect;
  GetClientRect(hWnd, Rect );
  if(DoDrawBorder())
  {
    Rect.InflateRect(+2,0,-1,0);
  }
  else
  {
    Rect.InflateRect(+2,0,0,0);
  }

  pDC->FillSolidRect (Rect,CNewMenu::GetMenuColor(0));//GetSysColor(COLOR_MENU));

  return TRUE;
}

BOOL CMenuTheme::OnWindowPosChanging(HWND hWnd, LPWINDOWPOS pPos)
{
  UNREFERENCED_PARAMETER(hWnd);

  if(DoDrawBorder())
  {
#ifdef _TRACE_MENU_
    AfxTrace(_T("WindowPosChanging hwnd=0x%lX, (%ld,%ld)(%ld,%ld)\n"),hWnd,pPos->x,pPos->y,pPos->cx,pPos->cy);
#endif

    if(!IsShadowEnabled())
    {
      pPos->cx +=2;
      pPos->cy +=2;
    }
    else
    {
      pPos->cx -=2;
      pPos->cy -=2;
    }
    pPos->y -=1;

#ifdef _TRACE_MENU_
    AfxTrace(_T("WindowPosChanged  hwnd=0x%lX, (%ld,%ld)(%ld,%ld)\n"),hWnd,pPos->x,pPos->y,pPos->cx,pPos->cy);
#endif

    return TRUE;
  }
  return FALSE;
}

BOOL CMenuTheme::OnNcCalcSize(HWND hWnd, NCCALCSIZE_PARAMS* pCalc)
{
  UNREFERENCED_PARAMETER(hWnd);

  if(DoDrawBorder())
  {
#ifdef _TRACE_MENU_
    AfxTrace(_T("OnNcCalcSize 0 hwnd=0x%lX, (top=%ld,bottom=%ld,left=%ld,right=%ld)\n"),hWnd,pCalc->rgrc->top,pCalc->rgrc->bottom,pCalc->rgrc->left,pCalc->rgrc->right);
#endif

    int cx=0,cy=0;
    if(!IsShadowEnabled())
    {
      cx = 5;
      cy = 6;
    }
    else
    {
      cx = 1;
      cy = 2;
    }

    pCalc->rgrc->top  += m_BorderTopLeft.cy;
    pCalc->rgrc->left += m_BorderTopLeft.cx;
    pCalc->rgrc->bottom -= cy;
    pCalc->rgrc->right  -= cx;

#ifdef _TRACE_MENU_
    AfxTrace(_T("OnNcCalcSize 0 hwnd=0x%lX, (top=%ld,bottom=%ld,left=%ld,right=%ld)\n"),hWnd,pCalc->rgrc->top,pCalc->rgrc->bottom,pCalc->rgrc->left,pCalc->rgrc->right);
    AfxTrace(_T("OnNcCalcSize 2 hwnd=0x%lX, (top=%ld,bottom=%ld,left=%ld,right=%ld)\n"),hWnd,pCalc->rgrc[2].top,pCalc->rgrc[2].bottom,pCalc->rgrc[2].left,pCalc->rgrc[2].right);
#endif

    //WNDPROC oldWndProc = (WNDPROC)::GetProp(hWnd, _OldMenuProc);
    //LRESULT result = NULL;
    //BOOL bCallDefault = TRUE;
    //result = CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);

    //return true;
  }
  return FALSE;
}

BOOL CMenuTheme::OnCalcFrameRect(HWND hWnd,LPRECT pRect)
{
  if(GetWindowRect(hWnd,pRect))
  {
    if(DoDrawBorder())
    {
      pRect->top += 2;
      pRect->left += 2;
      if(!IsShadowEnabled())
      {
        pRect->bottom -= 7;
        pRect->right -= 7;
      }
      else
      {
        pRect->bottom -= 3;
        pRect->right -= 3;
      }
    }
    return TRUE;
  }
  return FALSE;
}

void* CMenuTheme::SetScreenBitmap(HWND hWnd, HDC hDC)
{
  UNREFERENCED_PARAMETER(hDC);

  CNewMenuHook::CMenuHookData* pData = CNewMenuHook::GetMenuHookData(hWnd);
  if(pData->m_Screen.m_hObject==NULL)
  {
    // Get the desktop hDC...
    HDC hDcDsk = GetWindowDC(0);
    CDC* pDcDsk = CDC::FromHandle(hDcDsk);

    CDC dc;
    dc.CreateCompatibleDC(pDcDsk);

    CRect rect;
    GetWindowRect(hWnd,rect);
    pData->m_Screen.CreateCompatibleBitmap(pDcDsk,rect.Width()+10,rect.Height()+10);
    CBitmap* pOldBitmap = dc.SelectObject(&pData->m_Screen);
    dc.BitBlt(0,0,rect.Width()+10,rect.Height()+10,pDcDsk,pData->m_Point.x,pData->m_Point.y,SRCCOPY);

    dc.SelectObject(pOldBitmap);
    // Release the desktop hDC...
    ReleaseDC(0,hDcDsk);
  }
  return pData;
}

BOOL CMenuTheme::OnDrawBorder(HWND hWnd, HDC hDC, BOOL bOnlyBorder)
{
  CNewMenuHook::CMenuHookData* pData = (CNewMenuHook::CMenuHookData*)SetScreenBitmap(hWnd,hDC);
  if(DoDrawBorder() && pData)
  {
    CRect rect;
    CRect client;
    CDC* pDC = CDC::FromHandle (hDC);

    // Get the size of the menu...
    GetWindowRect(hWnd, rect );
    GetClientRect(hWnd, client);
    CPoint offset(0,0);
    ClientToScreen(hWnd,&offset);
    client.OffsetRect(offset-rect.TopLeft());

    long winW = rect.Width();
    long winH = rect.Height();

    if(!IsShadowEnabled())
    {
      if(!bOnlyBorder)
      {
        DrawFrame(pDC,CRect(CPoint(1,1),CSize(winW-6,winH-6)),client,CNewMenu::GetMenuColor());
      }
      if(bHighContrast)
      {
        pDC->Draw3dRect(CRect(CPoint(0,0),CSize(winW-4,winH-4)),GetSysColor(COLOR_BTNTEXT ),GetSysColor(COLOR_BTNTEXT ));
      }
      else
      {
        pDC->Draw3dRect(CRect(CPoint(0,0),CSize(winW-4,winH-4)),GetSysColor(COLOR_HIGHLIGHT),GetSysColor(COLOR_HIGHLIGHT));
        DrawShade(hWnd,hDC,pData->m_Point);
      }
    }
    else
    {
      if(!bOnlyBorder)
      {
        DrawFrame(pDC,CRect(CPoint(1,1),CSize(winW-2,winH-2)),client,CNewMenu::GetMenuColor());
        //pDC->FillSolidRect(winW-2,2,2,winH-2,RGB(0,0,255));
      }

      if(bHighContrast)
      {
        pDC->Draw3dRect(CRect(CPoint(0,0),CSize(winW-0,winH-0)),GetSysColor(COLOR_BTNTEXT ),GetSysColor(COLOR_BTNTEXT ));
      }
      else
      {
        pDC->Draw3dRect(CRect(CPoint(0,0),CSize(winW-0,winH-0)),GetSysColor(COLOR_HIGHLIGHT),GetSysColor(COLOR_HIGHLIGHT));
      }
    }
    //DrawSmalBorder(hWnd,hDC);
    return TRUE;
  }
  return FALSE;
}

CMenuThemeXP::CMenuThemeXP(DWORD dwThemeId,
                           pItemMeasureFkt pMeasureItem,
                           pItemDrawFkt pDrawItem,
                           pItemDrawFkt pDrawTitle,
                           DWORD dwFlags)
                           :CMenuTheme(dwThemeId,pMeasureItem,pDrawItem,pDrawTitle,dwFlags)
{
}

BOOL CMenuThemeXP::OnDrawBorder(HWND hWnd, HDC hDC, BOOL bOnlyBorder)
{
  CNewMenuHook::CMenuHookData* pData = (CNewMenuHook::CMenuHookData*)SetScreenBitmap(hWnd,hDC);
  if(DoDrawBorder() && pData)
  {
    UINT nMenuDrawMode = CNewMenu::GetMenuDrawMode();
  
    CRect rect;
    CRect client;
    CDC* pDC = CDC::FromHandle (hDC);

    // Get the size of the menu...
    GetWindowRect(hWnd, rect );
    GetClientRect(hWnd,client);
    CPoint offset(0,0);
    ClientToScreen(hWnd,&offset);
    client.OffsetRect(offset-rect.TopLeft());

    long winW = rect.Width();
    long winH = rect.Height();

    // Same Color as in DrawItem_WinXP
    COLORREF crMenuBar = CNewMenu::GetMenuColor(pData->m_hMenu);
    COLORREF crWindow = GetSysColor(COLOR_WINDOW);
    COLORREF crThinBorder = MixedColor(crWindow,crMenuBar);
    COLORREF clrBorder = DarkenColor(128,crMenuBar);
    COLORREF colorBitmap;

    if (NumScreenColors() > 256)
    {
      colorBitmap = MixedColor(crMenuBar,crWindow);
    }
    else
    {
      colorBitmap = GetSysColor(COLOR_BTNFACE);
    }

    // Better contrast when you have less than 256 colors
    if(pDC->GetNearestColor(crThinBorder)==pDC->GetNearestColor(colorBitmap))
    {
      crThinBorder = crWindow;
      colorBitmap = crMenuBar;
    }

    if(!IsShadowEnabled())
    {
      if(!bOnlyBorder)
      {
        DrawFrame(pDC,CRect(CPoint(1,1),CSize(winW-6,winH-6)),client,crThinBorder);
      }

      if(bHighContrast)
      {
        pDC->Draw3dRect(CRect(CPoint(0,0),CSize(winW-4,winH-4)),GetSysColor(COLOR_BTNTEXT),GetSysColor(COLOR_BTNTEXT));
      }
      else
      {
        pDC->Draw3dRect(CRect(CPoint(1,1),CSize(winW-6,winH-6)),crThinBorder,crThinBorder);
        pDC->FillSolidRect(1,2,1,winH-8,colorBitmap);
        pDC->Draw3dRect(CRect(CPoint(0,0),CSize(winW-4,winH-4)),clrBorder,clrBorder);

        DrawShade(hWnd,pDC->m_hDC,pData->m_Point);
      }
    }
    else
    {
      if(!bOnlyBorder)
      {
        DrawFrame(pDC,CRect(CPoint(1,1),CSize(winW-2,winH-2)),client,crThinBorder);
      }

      if(bHighContrast)
      {
        pDC->Draw3dRect(CRect(CPoint(0,0),CSize(winW-0,winH-0)),GetSysColor(COLOR_BTNTEXT ),GetSysColor(COLOR_BTNTEXT ));
      }
      else
      {
        pDC->Draw3dRect(CRect(CPoint(1,1),CSize(winW-2,winH-2)),crThinBorder,crThinBorder);
        if(nMenuDrawMode==CNewMenu::STYLE_XP_2003 || nMenuDrawMode==CNewMenu::STYLE_XP_2003_NOBORDER)
        {
          pDC->FillSolidRect(1,2,1,winH-4,crWindow);
        }
        else
        {
          pDC->FillSolidRect(1,2,1,winH-4,colorBitmap);
        }
        pDC->Draw3dRect(CRect(CPoint(0,0),CSize(winW-0,winH-0)),clrBorder,clrBorder);
      }
    }
    DrawSmalBorder(hWnd,pDC->m_hDC);

    return TRUE;
  }
  return FALSE;
}

BOOL CMenuThemeXP::OnEraseBkgnd(HWND hWnd, HDC hDC)
{
  CNewMenuHook::CMenuHookData* pData = CNewMenuHook::GetMenuHookData(hWnd);
  if(pData->m_hMenu==NULL)
  {
    return CMenuTheme::OnEraseBkgnd(hWnd,hDC);
  }
  //  Get the size of the menu...
  CDC* pDC = CDC::FromHandle (hDC);
  CRect Rect;
  GetClientRect(hWnd, Rect );
  if(DoDrawBorder())
  {
    Rect.InflateRect(+2,0,-1,0);
  }
  else
  {
    Rect.InflateRect(+2,0,0,0);
  }

  //BPO!!!!!!!!!!  fehler Zeichnet auch in den rand hinein 2
  //pDC->FillSolidRect (Rect,CNewMenu::GetMenuColor());
  pDC->FillSolidRect (Rect,CNewMenu::GetMenuBarColor(pData->m_hMenu));

  return TRUE;
}

/
// CMenuTheme2003 for drawing border and the rest

CMenuTheme2003::CMenuTheme2003( DWORD dwThemeId,
                                pItemMeasureFkt pMeasureItem,
                                pItemDrawFkt pDrawItem,
                                pItemDrawFkt pDrawTitle,
                                DWORD dwFlags)
 : CMenuThemeXP(dwThemeId,pMeasureItem,pDrawItem,pDrawTitle,dwFlags)
{
}

//
// Construction/Destruction
//

const TCHAR _OldMenuProc[] = _T("OldMenuProc");

HMODULE CNewMenuHook::m_hLibrary = NULL;
HMODULE CNewMenuHook::m_hThemeLibrary = NULL;
HHOOK CNewMenuHook::HookOldMenuCbtFilter = NULL;
HMENU CNewMenuHook::m_hLastMenu = NULL;
DWORD CNewMenuHook::m_dwMsgPos = 0;
DWORD CNewMenuHook::m_bSubclassFlag = 0;

#ifdef _TRACE_MENU_LOGFILE
HANDLE CNewMenuHook::m_hLogFile = INVALID_HANDLE_VALUE;
#endif //_TRACE_MENU_LOGFILE


CTypedPtrList<CPtrList, CMenuTheme*>* CNewMenuHook::m_pRegisteredThemesList = NULL;

CTypedPtrMap<CMapPtrToPtr,HWND,CNewMenuHook::CMenuHookData*> CNewMenuHook::m_MenuHookData;

#ifndef SM_REMOTESESSION
#define SM_REMOTESESSION     0x1000
#endif

CNewMenuHook::CNewMenuHook()
{
  if(g_Shell>=Win2000 && GetSystemMetrics(SM_REMOTESESSION))
  {
    bRemoteSession=TRUE;
  }

  { // Detecting wine because we have some issue
    HMODULE hModule = GetModuleHandle(_T("kernel32.dll"));
    bWine = hModule && GetProcAddress(hModule,"wine_get_unix_file_name");
//    if(Wine)
//    {
//      MessageBox(NULL,_T("We are running under wine!!"),_T("wine detected"),MB_OK);
//    }
  }


  HIGHCONTRAST highcontrast = {0};
  highcontrast.cbSize = sizeof(highcontrast);
  if(SystemParametersInfo(SPI_GETHIGHCONTRAST,sizeof(highcontrast),&highcontrast,0) )
  {
    bHighContrast = ((highcontrast.dwFlags&HCF_HIGHCONTRASTON)!=0);
  }

#ifdef _TRACE_MENU_LOGFILE
  m_hLogFile = CreateFile(_T("c:\\NewMenuLog.txt"), GENERIC_WRITE, FILE_SHARE_WRITE,
    NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if(m_hLogFile!=INVALID_HANDLE_VALUE)
  {
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN, m_hLogFile);

    _RPT0(_CRT_WARN,_T("file message\n"));
  }
#endif // _TRACE_MENU_LOGFILE

  // Try to load theme library from XP
  m_hThemeLibrary = LoadLibrary(_T("uxtheme.dll"));
  if(m_hThemeLibrary)
  {
    pIsThemeActive = (FktIsThemeActive)GetProcAddress(m_hThemeLibrary,"IsThemeActive");
    pSetWindowTheme = (FktSetWindowTheme)GetProcAddress(m_hThemeLibrary,"SetWindowTheme");
  }
  else
  {
    pIsThemeActive = NULL;
  }

  // Try to load the library for gradient drawing
  m_hLibrary = LoadLibrary(_T("Msimg32.dll"));

  // Don't use the gradientfill under Win98 because it is buggy!!!
  if(g_Shell!=Win98 && m_hLibrary)
  {
    pGradientFill = (FktGradientFill)GetProcAddress(m_hLibrary,"GradientFill");
  }
  else
  {
    pGradientFill = NULL;
  }

  AddTheme(new CMenuTheme(CNewMenu::STYLE_ICY,
    &CNewMenu::MeasureItem_Icy,
    &CNewMenu::DrawItem_Icy,
    &CNewMenu::DrawMenuTitle,TRUE));

  AddTheme(new CMenuTheme(CNewMenu::STYLE_ICY_NOBORDER,
    &CNewMenu::MeasureItem_Icy,
    &CNewMenu::DrawItem_Icy,
    &CNewMenu::DrawMenuTitle));

  AddTheme(new CMenuTheme(CNewMenu::STYLE_ORIGINAL,
    &CNewMenu::MeasureItem_OldStyle,
    &CNewMenu::DrawItem_OldStyle,
    &CNewMenu::DrawMenuTitle,TRUE));

  AddTheme(new CMenuTheme(CNewMenu::STYLE_ORIGINAL_NOBORDER,
    &CNewMenu::MeasureItem_OldStyle,
    &CNewMenu::DrawItem_OldStyle,
    &CNewMenu::DrawMenuTitle));

  AddTheme(new CMenuThemeXP(CNewMenu::STYLE_XP,
    &CNewMenu::MeasureItem_WinXP,
    &CNewMenu::DrawItem_WinXP,
    &CNewMenu::DrawMenuTitle,TRUE));

  AddTheme(new CMenuThemeXP(CNewMenu::STYLE_XP_NOBORDER,
    &CNewMenu::MeasureItem_WinXP,
    &CNewMenu::DrawItem_WinXP,
    &CNewMenu::DrawMenuTitle));

  AddTheme(new CMenuTheme2003(CNewMenu::STYLE_XP_2003,
    &CNewMenu::MeasureItem_WinXP,
    &CNewMenu::DrawItem_XP_2003,
    &CNewMenu::DrawMenuTitle,TRUE));

  AddTheme(new CMenuTheme2003(CNewMenu::STYLE_XP_2003_NOBORDER,
    &CNewMenu::MeasureItem_WinXP,
    &CNewMenu::DrawItem_XP_2003,
    &CNewMenu::DrawMenuTitle));

  AddTheme(new CMenuThemeXP(CNewMenu::STYLE_COLORFUL,
    &CNewMenu::MeasureItem_WinXP,
    &CNewMenu::DrawItem_XP_2003,
    &CNewMenu::DrawMenuTitle,TRUE));

  AddTheme(new CMenuThemeXP(CNewMenu::STYLE_COLORFUL_NOBORDER,
    &CNewMenu::MeasureItem_WinXP,
    &CNewMenu::DrawItem_XP_2003,
    &CNewMenu::DrawMenuTitle));

  AddTheme(new CMenuTheme(CNewMenu::STYLE_SPECIAL,
    &CNewMenu::MeasureItem_OldStyle,
    &CNewMenu::DrawItem_SpecialStyle,
    &CNewMenu::DrawMenuTitle,TRUE));

  AddTheme(new CMenuTheme(CNewMenu::STYLE_SPECIAL_NOBORDER,
    &CNewMenu::MeasureItem_OldStyle,
    &CNewMenu::DrawItem_SpecialStyle,
    &CNewMenu::DrawMenuTitle));

  //  CNewMenu::m_pActMenuDrawing = FindTheme(CNewMenu::STYLE_ORIGINAL);
  //  CNewMenu::m_pActMenuDrawing = FindTheme(CNewMenu::STYLE_ORIGINAL_NOBORDER);
  CNewMenu::m_pActMenuDrawing = FindTheme(CNewMenu::STYLE_XP);
  //  CNewMenu::m_pActMenuDrawing = FindTheme(CNewMenu::STYLE_XP_NOBORDER);

  if (HookOldMenuCbtFilter == NULL)
  {
    HookOldMenuCbtFilter = ::SetWindowsHookEx(WH_CALLWNDPROC, NewMenuHook, NULL, ::GetCurrentThreadId());
    if (HookOldMenuCbtFilter == NULL)
    {
      ShowLastError(_T("Error from Menu: SetWindowsHookEx"));
      AfxThrowMemoryException();
    }
  }
}

CNewMenuHook::~CNewMenuHook()
{
  if (HookOldMenuCbtFilter != NULL)
  {
    if(!::UnhookWindowsHookEx(HookOldMenuCbtFilter))
    {
      ShowLastError(_T("Error from Menu: UnhookWindowsHookEx"));
    }
    HookOldMenuCbtFilter = NULL;
  }
  // Destroy all registered themes.
  if( m_pRegisteredThemesList!= NULL)
  {
    while(m_pRegisteredThemesList->GetCount())
    {
      CMenuTheme* pTheme = m_pRegisteredThemesList->RemoveTail();
      delete pTheme;
    }
    delete m_pRegisteredThemesList;
    m_pRegisteredThemesList = NULL;
  }

  pIsThemeActive = NULL;
  FreeLibrary(m_hThemeLibrary);

  pGradientFill = NULL;
  FreeLibrary(m_hLibrary);

  // Cleanup for shared menu icons
  if(CNewMenu::m_pSharedMenuIcons)
  {
    delete CNewMenu::m_pSharedMenuIcons;
    CNewMenu::m_pSharedMenuIcons = NULL;
  }

#ifdef _TRACE_MENU_LOGFILE
  if(m_hLogFile!=INVALID_HANDLE_VALUE)
  {
    CloseHandle(m_hLogFile);
    m_hLogFile = INVALID_HANDLE_VALUE;
  }
#endif
}

BOOL CNewMenuHook::AddTheme(CMenuTheme* pTheme)
{
  if( m_pRegisteredThemesList== NULL)
  {
    m_pRegisteredThemesList = new CTypedPtrList<CPtrList, CMenuTheme*>;
  }
  if(m_pRegisteredThemesList->Find(pTheme))
  {
    return FALSE;
  }
  m_pRegisteredThemesList->AddTail(pTheme);
  return TRUE;
}

CMenuTheme* CNewMenuHook::RemoveTheme(DWORD dwThemeId)
{
  CMenuTheme* pTheme = FindTheme(dwThemeId);
  if(pTheme==NULL)
  {
    return NULL;
  }
  POSITION pos = m_pRegisteredThemesList->Find(pTheme);
  ASSERT(pos);
  if(pos)
  {
    m_pRegisteredThemesList->RemoveAt(pos);
    if(m_pRegisteredThemesList->GetCount()==NULL)
    {
      // Destroy the empty list.
      delete m_pRegisteredThemesList;
      m_pRegisteredThemesList = NULL;
    }
  }
  return pTheme;
}

CMenuTheme* CNewMenuHook::FindTheme(DWORD dwThemeId)
{
  if(m_pRegisteredThemesList==NULL)
  {
    return NULL;
  }

  POSITION pos = m_pRegisteredThemesList->GetHeadPosition();
  while(pos)
  {
    CMenuTheme* pTheme = m_pRegisteredThemesList->GetNext(pos);
    if(pTheme->m_dwThemeId==dwThemeId)
    {
      return pTheme;
    }
  }
  return NULL;
}

CNewMenuHook::CMenuHookData* CNewMenuHook::GetMenuHookData(HWND hWnd)
{
  CMenuHookData* pData=NULL;
  if(m_MenuHookData.Lookup(hWnd,pData))
  {
    return pData;
  }
  return NULL;
}

void CNewMenuHook::UnsubClassMenu(HWND hWnd)
{
  AFX_MANAGE_STATE(AfxGetModuleState());

  WNDPROC oldWndProc = (WNDPROC)::GetProp(hWnd, _OldMenuProc);
  ASSERT(oldWndProc != NULL);

  SetLastError(0);
  if(!SetWindowLongPtr(hWnd, GWLP_WNDPROC, (INT_PTR)oldWndProc))
  {
    ShowLastError(_T("Error from Menu: SetWindowLongPtr III"));
  }
  RemoveProp(hWnd, _OldMenuProc);
  GlobalDeleteAtom(GlobalFindAtom(_OldMenuProc));

  // now Clean up
  HMENU hMenu = NULL;
  // Restore old Styles for special menu!! (Menu 0x10012!!!)
  CMenuHookData* pData = GetMenuHookData(hWnd);
  if(pData)
  {
    hMenu = pData->m_hMenu;
    CNewMenu::m_pActMenuDrawing->OnUnInitWnd(hWnd);

    m_MenuHookData.RemoveKey(hWnd);

    delete pData;
  }

#ifdef _TRACE_MENU_
  AfxTrace(_T("Unsubclass Menu=0x%lX, hwnd=0x%lX\n"),hMenu,hWnd);
#endif
}

LRESULT CALLBACK CNewMenuHook::SubClassMenu(HWND hWnd,      // handle to window
                                            UINT uMsg,      // message identifier
                                            WPARAM wParam,  // first message parameter
                                            LPARAM lParam)  // second message parameter
{
  AFX_MANAGE_STATE(AfxGetModuleState());

  WNDPROC oldWndProc = (WNDPROC)::GetProp(hWnd, _OldMenuProc);
  LRESULT result = NULL;
  BOOL bCallDefault = TRUE;


#ifdef _TRACE_MENU_
  static long NestedLevel = 0;
  NestedLevel++;
  MSG msg = {hWnd,uMsg,wParam,lParam,0,0,0};
  TCHAR Buffer[30];
  wsprintf(Buffer,_T("Level %02ld"),NestedLevel);
  MyTraceMsg(Buffer,&msg);
#endif

  CMenuHookData* pData = GetMenuHookData(hWnd);
  if(NULL == pData)
  {
    return ::CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
  }
  ASSERT(pData);

  switch(uMsg)
  {
  case WM_NCPAINT:
    ASSERT(pData);

    if(pData->m_bDoSubclass)
    {
#ifdef _TRACE_MENU_
      AfxTrace(_T("WM_NCPAINT (0x%x) 0x%X, 0x%X\n"),hWnd,wParam,lParam);
#endif
      if(!pData->m_bDrawBorder)
      {
        if(pData->m_hRgn!=(HRGN)wParam)
        {
          if(pData->m_hRgn!=(HRGN)1)
          {
            DeleteObject(pData->m_hRgn);
            pData->m_hRgn=(HRGN)1;
          }
          if(wParam!=1)
          {
            CRgn dest;
            dest.CreateRectRgn( 0, 0, 1, 1);
            dest.CopyRgn(CRgn::FromHandle((HRGN)wParam));
            pData->m_hRgn = (HRGN)dest.Detach();
          }
        }
      }

      if(pData->m_dwData&8)
      {
        // do not call default!!!
        bCallDefault=FALSE;
      }

      if(pData->m_bDrawBorder &&  CNewMenu::m_pActMenuDrawing->DoDrawBorder())
      {
        //HDC hDC = GetWindowDC(hWnd);
        HDC hDC;
        //if(wParam!=1)
        //  hDC = GetDCEx(hWnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
        //else
        hDC = GetWindowDC (hWnd);

#ifdef _TRACE_MENU_
        if(wParam!=1)
        {
          DWORD dwCount = GetRegionData((HRGN)wParam,0,0);
          RGNDATA* pRegionData = (RGNDATA*)_alloca(dwCount);
          GetRegionData((HRGN)wParam,dwCount,pRegionData);

          TRACE(_T("WM_NCPAINT (0x%x) region %ld "),hWnd,pRegionData->rdh.nCount);
          CRect* pRect = (CRect*)pRegionData->Buffer;
          for(DWORD n=0; n<pRegionData->rdh.nCount; n++)
          {
            TRACE( _T("(%ld,%ld,%ld,%ld)"),pRect[n].left,pRect[n].top,pRect[n].right,pRect[n].bottom);
          }
          TRACE(_T("\r\n"));
        }
#endif //  _TRACE_MENU_

        if(hDC)
        {
          if(CNewMenu::m_pActMenuDrawing->OnDrawBorder(hWnd,hDC))
          {
            CRect rect;
            if(CNewMenu::m_pActMenuDrawing->OnCalcFrameRect(hWnd,rect))
            {
              CRgn rgn;
              rect.InflateRect(-1,-1);
              rgn.CreateRectRgnIndirect(rect);
              // do we need a combination of the regions?
              //if(wParam!=1)
              //{
              //  rgn.CombineRgn(&rgn,CRgn::FromHandle((HRGN)wParam),RGN_AND);
              //}
              ASSERT(oldWndProc);

              bCallDefault=FALSE;
              result = CallWindowProc(oldWndProc, hWnd, uMsg, (WPARAM)rgn.m_hObject, lParam);
              //result = CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
              // Redraw the border and shade
              CNewMenu::m_pActMenuDrawing->OnDrawBorder(hWnd,hDC,true);
            }
          }
          ReleaseDC(hWnd,hDC);
        }
      }
      if(CNewMenu::m_pActMenuDrawing->DoDrawBorder() && bCallDefault)
      {
        // Save the background
        HDC hDC = GetWindowDC (hWnd);
        CNewMenu::m_pActMenuDrawing->SetScreenBitmap(hWnd,hDC);
        ReleaseDC(hWnd,hDC);
      }
    }

    break;

  case WM_PRINT:
    if(pData && pData->m_bDoSubclass)
    {
      if(CNewMenu::m_pActMenuDrawing->DoDrawBorder())
      {
        // Mark for WM_PRINT
        pData->m_dwData |= 8;

        //      pData->m_bDrawBorder = FALSE;
        // We need to create a bitmap for drawing
        // We can't clipp or make a offset to the DC because NT2000 (blue-screen!!)
        CRect rect;
        GetWindowRect(hWnd, rect);
        CDC dc;
        CBitmap bitmap;

        CDC* pDC = CDC::FromHandle((HDC)wParam);
        dc.CreateCompatibleDC(pDC);

        bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
        CBitmap* pOldBitmap = dc.SelectObject(&bitmap);

        // new
        //       dc.FillSolidRect(0,0,rect.Width(), rect.Height(),CNewMenu::GetMenuBarColor(pData->m_hMenu));

        CNewMenu::m_pActMenuDrawing->OnDrawBorder(hWnd,dc.m_hDC);

        CRect rectClient;
        if(CNewMenu::m_pActMenuDrawing->OnCalcFrameRect(hWnd,rectClient))
        {
          // might as well clip to the same rectangle
          CRect clipRect = rectClient;
          clipRect.OffsetRect(rectClient.TopLeft()-rect.TopLeft());
          clipRect.InflateRect(-1,-1);
          dc.IntersectClipRect(clipRect);
          result = CallWindowProc(oldWndProc, hWnd, uMsg, (WPARAM)dc.m_hDC, lParam&~PRF_CLIENT);

          pDC->BitBlt(0,0, rect.Width(), rect.Height(), &dc,0,0, SRCCOPY);

          GetClientRect(hWnd,clipRect);
          SelectClipRgn(dc.m_hDC,NULL);
          dc.IntersectClipRect(clipRect);

          SendMessage(hWnd,WM_ERASEBKGND,(WPARAM)dc.m_hDC,0);
          SendMessage(hWnd,WM_PRINTCLIENT,(WPARAM)dc.m_hDC,lParam);

          CPoint wndOffset(0,0);
          ClientToScreen(hWnd,&wndOffset);
          wndOffset -= rect.TopLeft();
          pDC->BitBlt(wndOffset.x,wndOffset.y, clipRect.Width()-1, clipRect.Height(), &dc, 0, 0, SRCCOPY);
          //pDC->BitBlt(wndOffset.x,wndOffset.y, clipRect.Width(), clipRect.Height(), &dc, 0, 0, SRCCOPY);
        }
        //
        dc.SelectObject(pOldBitmap);
        bCallDefault=FALSE;

        // Clear for WM_PRINT
        pData->m_dwData &= ~8;
      }
    }
    break;

  case WM_ERASEBKGND:
    ASSERT(pData);
    if(pData->m_bDoSubclass)
    {
      if(CNewMenu::m_pActMenuDrawing->DoDrawBorder())
      {
        if(!(pData->m_dwData&8) && !pData->m_bDrawBorder )
        {
          pData->m_bDrawBorder = true;
          //SendMessage(hWnd,WM_NCPAINT,(WPARAM)pData->m_hRgn,0);
          SendMessage(hWnd,WM_NCPAINT,(WPARAM)1,0);
        }
      }

      if(CNewMenu::m_pActMenuDrawing->OnEraseBkgnd(hWnd,(HDC)wParam))
      {
        bCallDefault=FALSE;
        result = TRUE;
      }
    }
    break;

  case WM_WINDOWPOSCHANGED:
  case WM_WINDOWPOSCHANGING:
    {
      ASSERT(pData);

      LPWINDOWPOS pPos = (LPWINDOWPOS)lParam;
      if(uMsg==WM_WINDOWPOSCHANGING)
      {
        CNewMenu::m_pActMenuDrawing->OnWindowPosChanging(hWnd,pPos);
      }
      if(!(pPos->flags&SWP_NOMOVE) )
      {
        if(pData->m_Point==CPoint(0,0))
        {
          pData->m_Point = CPoint(pPos->x,pPos->y);
        }
        else if(pData->m_Point!=CPoint(pPos->x,pPos->y))
        {
          /*          CRect rect(0,0,0,0);
          if(!GetWindowRect(hWnd,rect))
          {
          AfxTrace(_T("Error get rect\n"));
          }
          #ifdef _TRACE_MENU_

          DWORD dwPos =GetMessagePos();
          AfxTrace(_T("Rect pos (%ld/%ld), dimensions [%ld,%ld], Delta(%ld/%ld),MPos %lx\n"),
          pData->m_Point.x,pData->m_Point.y,rect.Width(),rect.Height(),
          pData->m_Point.x-pPos->x,pData->m_Point.y-pPos->y,dwPos);
          #endif
          */
          if(!(pPos->flags&SWP_NOSIZE))
          {
            UnsubClassMenu(hWnd);
          }
          else
          {
            pData->m_Point=CPoint(pPos->x,pPos->y);
            pData->m_Screen.DeleteObject();
          }
        }
      }
    }
    break;

  case WM_KEYDOWN:
    if(wParam==VK_ESCAPE)
    {
      if(pData)
      {
        pData->m_dwData |= 4;
      }
    }
    m_dwMsgPos = GetMessagePos();
    break;

  case WM_NCCALCSIZE:
    if(pData->m_bDoSubclass)
    {
      NCCALCSIZE_PARAMS* pCalc = (NCCALCSIZE_PARAMS*)lParam;
      if(CNewMenu::m_pActMenuDrawing->OnNcCalcSize(hWnd,pCalc))
      {
        bCallDefault=FALSE;
      }
    }
    break;

  case WM_SHOWWINDOW:
    // Hide the window ? Test for 98 and 2000
    if(wParam==NULL)
    {
      // Special handling for NT 2000 and WND 0x10012.
      UnsubClassMenu(hWnd);
    }
    break;

  case WM_NCDESTROY:
    UnsubClassMenu (hWnd);
    break;

  case WM_TIMER:
    if(wParam==MENU_TIMER_ID)
    {
      if(g_Shell>=Win2000)
      {
        LONG_PTR dwExStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
        if( !(dwExStyle&WS_EX_LAYERED) )
        {
          SetWindowLongPtr (hWnd, GWL_EXSTYLE,dwExStyle| WS_EX_LAYERED);
          SetLayeredWindowAttributes(hWnd, 0, CNewMenu::GetAlpha(), LWA_ALPHA);
          pData->m_dwData &= ~4;
          KillTimer(hWnd,MENU_TIMER_ID);
        }
      }
    }
    break;

    //  if(pData->m_TimerID && pData->m_TimerID==wParam)
    //  {
    //    bCallDefault = FALSE;
    //    KillTimer(hWnd,pData->m_TimerID);
    //    pData->m_TimerID = NULL;
    //    result = 0;
    //    // Create shade windows
    //    SetWindowShade(hWnd, pData);
    //  }
    //  break;

    //default:
    //  {
    //    static const UINT WBHook = RegisterWindowMessage(_T("WBHook"));
    //    if (uMsg==WBHook)
    //    {
    //      bCallDefault = false;
    //    }
    //  }
    //  break;
  }

  if( bCallDefault )
  {
    ASSERT(oldWndProc != NULL);
    // call original wndproc for default handling
    result = CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
  }

#ifdef _TRACE_MENU_
  NestedLevel--;
#endif

  return result;
}

BOOL CNewMenuHook::CheckSubclassing(HWND hWnd, BOOL bSpecialWnd)
{
  TCHAR Name[20];
  int Count = GetClassName (hWnd,Name,ARRAY_SIZE(Name));
  // Check for the menu-class
  if(Count!=6 || _tcscmp(Name,_T("#32768"))!=0)
  {
    // does not match to menuclass
    return false;
  }
  BOOL bDoNewSubclass = FALSE;
  CMenuHookData* pData=GetMenuHookData(hWnd);
  // check if we have allready some data
  if(pData==NULL)
  {

    // a way for get the menu-handle not documented
    if(!m_hLastMenu)
    {
      // WinNt 4.0 will crash in submenu
      m_hLastMenu = (HMENU)SendMessage(hWnd,0x01E1,0,0);
    }
    CMenu *pMenu = CMenu::FromHandlePermanent(m_hLastMenu);
    // now we support only new menu
    if( !DYNAMIC_DOWNCAST(CNewMenu,pMenu) )
    {
      return false;
    }

    WNDPROC oldWndProc;
    // subclass the window with the proc which does gray backgrounds
    oldWndProc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
    if (oldWndProc != NULL && GetProp(hWnd, _OldMenuProc) == NULL)
    {
      ASSERT(oldWndProc!=SubClassMenu);

      if(!SetProp(hWnd, _OldMenuProc, oldWndProc))
      {
        ShowLastError(_T("Error from Menu: SetProp"));
      }
      if ((WNDPROC)GetProp(hWnd, _OldMenuProc) == oldWndProc)
      {
        GlobalAddAtom(_OldMenuProc);

        CMenuHookData* pData=GetMenuHookData(hWnd);
        ASSERT(pData==NULL);
        if(pData==NULL)
        {
          pData = new CMenuHookData(hWnd,bSpecialWnd);
          m_MenuHookData.SetAt (hWnd,pData);

          SetLastError(0);
          if(!SetWindowLongPtr(hWnd, GWLP_WNDPROC,(INT_PTR)SubClassMenu))
          {
            ShowLastError(_T("Error from Menu: SetWindowLongPtr IV"));
          }
          bDoNewSubclass = TRUE;
#ifdef _TRACE_MENU_
          //SendMessage(hWnd,0x01E1,0,0) a way for get the menu-handle
          AfxTrace(_T("Subclass Menu=0x%lX, hwnd=0x%lX\n"),pData->m_hMenu,hWnd);
#endif
          CNewMenu::m_pActMenuDrawing->OnInitWnd(hWnd);
        }
      }
      else
      {
        ASSERT(0);
      }
    }
  }

  // Menu was set also assign it to this menu.
  if(m_hLastMenu)
  {
    CMenuHookData* pData = GetMenuHookData(hWnd);
    if(pData)
    {
      // Safe actual menu
      pData->SetMenu(m_hLastMenu);
      // Reset for the next menu
      m_hLastMenu = NULL;
      //
      CNewMenu::m_pActMenuDrawing->OnInitWnd(hWnd);
    }
  }
  return bDoNewSubclass;
}

/
// CNewMenuThreadHook class used to hook for threads
// Jan-17-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/

CNewMenuThreadHook::CNewMenuThreadHook()
{
  // set the hook handler for this thread
  m_hHookOldMenuCbtFilter = ::SetWindowsHookEx(WH_CALLWNDPROC, CNewMenuHook::NewMenuHook, NULL, ::GetCurrentThreadId());
} // CNewMenuThreadHook


CNewMenuThreadHook::~CNewMenuThreadHook()
{
  // reset the hook handler
  if (m_hHookOldMenuCbtFilter)
  {
    ::UnhookWindowsHookEx(m_hHookOldMenuCbtFilter);
  }
  // clear the handle
  m_hHookOldMenuCbtFilter = NULL;
} // ~CNewMenuThreadHook


/
// CNewMenuTempHandler class used to add NewMenu to system dialog
class CNewMenuTempHandler : public CObject
{
  CNewMenu m_SystemNewMenu;
  WNDPROC m_oldWndProc;
  HWND m_hWnd;

public:
  CNewMenuTempHandler(HWND hWnd)
  {
    m_hWnd = hWnd;
    VERIFY(SetProp(hWnd,_T("CNewMenuTempHandler"),this));
    // Subclass the dialog control.
    m_oldWndProc = (WNDPROC)(LONG_PTR)SetWindowLongPtr(hWnd, GWLP_WNDPROC,(INT_PTR)TempSubclass);
  }

  ~CNewMenuTempHandler()
  {
    SetWindowLongPtr(m_hWnd, GWLP_WNDPROC,(INT_PTR)m_oldWndProc);
    VERIFY(RemoveProp(m_hWnd,_T("CNewMenuTempHandler")));
  }

  LRESULT Default(UINT uMsg, WPARAM wParam, LPARAM lParam )
  {
    // call original wndproc for default handling
    return CallWindowProc(m_oldWndProc, m_hWnd, uMsg, wParam, lParam);
  }

  LRESULT OnCmd(UINT uMsg, WPARAM wParam, LPARAM lParam)
  {
    MSG msg = {m_hWnd,uMsg,wParam,lParam,0,0,0};
    switch(uMsg)
    {
    case WM_DRAWITEM:
      {
        if(m_SystemNewMenu.m_hMenu)
        {
          DRAWITEMSTRUCT* lpDrawItemStruct = (DRAWITEMSTRUCT*)lParam;
          if (lpDrawItemStruct->CtlType == ODT_MENU)
          {
            CMenu* pMenu = CMenu::FromHandlePermanent((HMENU)lpDrawItemStruct->hwndItem);
            if (DYNAMIC_DOWNCAST(CNewMenu,pMenu))
            {
              pMenu->DrawItem(lpDrawItemStruct);
              return true; // eat it
            }
          }
        }
        return Default(uMsg, wParam, lParam);
      }

    case WM_MEASUREITEM:
      if(CNewMenu::OnMeasureItem(&msg))
      {
        return TRUE;
      }
      break;

    case WM_MENUCHAR:
      {
        CMenu* pMenu = CMenu::FromHandle(UIntToHMenu((UINT)lParam));;
        LRESULT lresult;
        if( DYNAMIC_DOWNCAST(CNewMenu,pMenu) )
          lresult=CNewMenu::FindKeyboardShortcut(LOWORD(wParam), HIWORD(wParam),pMenu );
        else
          lresult=Default(uMsg, wParam, lParam);
        return lresult;
      }
      break;

    case WM_INITMENUPOPUP:
      {
        CMenu* pMenu = CMenu::FromHandle(UIntToHMenu((UINT)wParam));
        LRESULT result = Default(uMsg, wParam, lParam);
        CNewMenu::OnInitMenuPopup(m_hWnd, pMenu, LOWORD(lParam), HIWORD(lParam));
        return result;
      }

    case WM_INITDIALOG:
      if(CNewMenuHook::m_bSubclassFlag&NEW_MENU_DIALOG_SYSTEM_MENU)
      {
        LRESULT bRetval = Default(uMsg, wParam, lParam);
        VERIFY(m_SystemNewMenu.m_hMenu==0);

        HMENU hMenu = ::GetSystemMenu(m_hWnd,FALSE);
        if(IsMenu(hMenu))
        {
          CMenu* pMenu = CMenu::FromHandlePermanent(hMenu);
          // Only attach to CNewMenu once
          if (DYNAMIC_DOWNCAST(CNewMenu,pMenu)==NULL )
          {
            m_SystemNewMenu.Attach(hMenu);
          }
        }
        return bRetval;
      }
      break;

    case WM_DESTROY:
      LRESULT result = Default(uMsg, wParam, lParam);
      delete this;
      return result;
    }

    return Default(uMsg, wParam, lParam);
  }

  // Subclass procedure
  static LRESULT APIENTRY TempSubclass(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  {
    AFX_MANAGE_STATE(AfxGetModuleState());

    CNewMenuTempHandler* pTemp = (CNewMenuTempHandler*)GetProp(hwnd,_T("CNewMenuTempHandler"));
    ASSERT(pTemp);
    return pTemp->OnCmd(uMsg, wParam, lParam);
  }

};

LRESULT CALLBACK CNewMenuHook::NewMenuHook(int code, WPARAM wParam, LPARAM lParam)
{
  AFX_MANAGE_STATE(AfxGetModuleState());

  CWPSTRUCT* pTemp = (CWPSTRUCT*)lParam;
  if(code == HC_ACTION )
  {
    HWND hWnd = pTemp->hwnd;

#ifdef _TRACE_MENU_
    static HWND acthMenu = NULL;
    static HWND acthWnd = NULL;

    // Check if we need to find out the window
    if (hWnd && hWnd!=acthWnd && hWnd!=acthMenu)
    {
      TCHAR Name[20];
      int Count = GetClassName (hWnd,Name,ARRAY_SIZE(Name));
      // Check for the menu-class
      if(Count!=6 || _tcscmp(Name,_T("#32768"))!=0)
      {
        // does not match to menuclass
        acthWnd = hWnd;
      }
      else
      {
        acthMenu = hWnd;
        // AfxTrace(_T("Found new menu HWND: 0x%08X\n"),acthMenu);
      }
    }
    // Trace all menu msg
    if(acthMenu==hWnd && acthMenu)
    {
      MSG msg = {hWnd,pTemp->message,pTemp->wParam,pTemp->lParam,0,0,0};
      MyTraceMsg(_T(" Menu   "),&msg);
    }
#endif

    // Normal and special handling for menu 0x10012
    if(pTemp->message==WM_CREATE || pTemp->message==0x01E2)
    {
      if(!CheckSubclassing(hWnd,pTemp->message==0x01E2))
      {
        if( (m_bSubclassFlag&NEW_MENU_DIALOG_SUBCLASS) && pTemp->message==WM_CREATE)
        {
          TCHAR Name[20];
          int Count = GetClassName (hWnd,Name,ARRAY_SIZE(Name));
          // Check for the Dialog-class
          if(Count==6 && _tcscmp(Name,_T("#32770"))==0 )
          {
            // Only first dialog
            // m_bSubclassFlag &= ~NEW_MENU_DIALOG_SUBCLASS;
            // Freed by WM_DESTROY
            new CNewMenuTempHandler(hWnd);
          }
        }
      }
    }
  }
  return CallNextHookEx(HookOldMenuCbtFilter, code,wParam, lParam);
}

//
// Construction/Destruction
//

IMPLEMENT_DYNAMIC(CNewDialog,CDialog)

BEGIN_MESSAGE_MAP(CNewDialog, CNewFrame<CDialog>)
  //{{AFX_MSG_MAP(CNewDialog)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //    DO NOT EDIT what you see in these blocks of generated code!
  ON_WM_INITMENUPOPUP()
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

CNewDialog::CNewDialog()
{
}

CNewDialog::CNewDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
{
  ASSERT(IS_INTRESOURCE(lpszTemplateName) || AfxIsValidString(lpszTemplateName));

  m_pParentWnd = pParentWnd;
  m_lpszTemplateName = lpszTemplateName;
  if (IS_INTRESOURCE(m_lpszTemplateName))
    m_nIDHelp = LOWORD((DWORD_PTR)m_lpszTemplateName);
}

CNewDialog::CNewDialog(UINT nIDTemplate, CWnd* pParentWnd)
{
  m_pParentWnd = pParentWnd;
  m_lpszTemplateName = MAKEINTRESOURCE(nIDTemplate);
  m_nIDHelp = nIDTemplate;
}

BOOL CNewDialog::OnInitDialog()
{
  BOOL bRetval = CDialog::OnInitDialog();

  HMENU hMenu = m_SystemNewMenu.Detach();
  HMENU hSysMenu = ::GetSystemMenu(m_hWnd,FALSE);
  if(hMenu!=hSysMenu)
  {
    if(IsMenu(hMenu))
    {
      if(!::DestroyMenu(hMenu))
      {
        ShowLastError(_T("Error from Menu: DestroyMenu"));
      }
    }
  }
  m_SystemNewMenu.Attach(hSysMenu);
  m_DefaultNewMenu.LoadMenu(::GetMenu(m_hWnd));

  if(IsMenu(m_DefaultNewMenu.m_hMenu))
  {
    UpdateMenuBarColor(m_DefaultNewMenu);
  }

  return bRetval;
}

extern void AFXAPI AfxCancelModes(HWND hWndRcvr);

// Most of the code is copied from the MFC code from CFrameWnd::OnInitMenuPopup
void CNewDialog::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu)
{
  AfxCancelModes(m_hWnd);

  // don't support system menu
  if (!bSysMenu)
  {
    ASSERT(pMenu != NULL);
    // check the enabled state of various menu items

    CCmdUI state;
    state.m_pMenu = pMenu;
    ASSERT(state.m_pOther == NULL);
    ASSERT(state.m_pParentMenu == NULL);

    // determine if menu is popup in top-level menu and set m_pOther to
    //  it if so (m_pParentMenu == NULL indicates that it is secondary popup)
    HMENU hParentMenu;
    if (AfxGetThreadState()->m_hTrackingMenu == pMenu->m_hMenu)
    {
      state.m_pParentMenu = pMenu;    // parent == child for tracking popup
    }
    else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
    {
      CWnd* pParent = GetTopLevelParent();
      // child windows don't have menus -- need to go to the top!
      if (pParent != NULL &&
        (hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
      {
        int nIndexMax = ::GetMenuItemCount(hParentMenu);
        for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
        {
          if (::GetSubMenu(hParentMenu, nIndex) == pMenu->m_hMenu)
          {
            // when popup is found, m_pParentMenu is containing menu
            state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
            break;
          }
        }
      }
    }

    state.m_nIndexMax = pMenu->GetMenuItemCount();
    for (state.m_nIndex = 0; state.m_nIndex<state.m_nIndexMax; state.m_nIndex++)
    {
      state.m_nID = pMenu->GetMenuItemID(state.m_nIndex);
      if (state.m_nID == 0)
        continue; // menu separator or invalid cmd - ignore it

      ASSERT(state.m_pOther == NULL);
      ASSERT(state.m_pMenu != NULL);
      if (state.m_nID == (UINT)-1)
      {
        // possibly a popup menu, route to first item of that popup
        state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex);
        if (state.m_pSubMenu == NULL ||
          (state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
          state.m_nID == (UINT)-1)
        {
          continue;       // first item of popup can't be routed to
        }
        state.DoUpdate(this, FALSE);    // popups are never auto disabled
      }
      else
      {
        // normal menu item
        // Auto enable/disable if frame window has 'm_bAutoMenuEnable'
        //    set and command is _not_ a system command.
        state.m_pSubMenu = NULL;
        state.DoUpdate(this, state.m_nID < 0xF000);
      }

      // adjust for menu deletions and additions
      UINT nCount = pMenu->GetMenuItemCount();
      if (nCount < state.m_nIndexMax)
      {
        state.m_nIndex -= (state.m_nIndexMax - nCount);
        while (state.m_nIndex < nCount &&
          pMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
        {
          state.m_nIndex++;
        }
      }
      state.m_nIndexMax = nCount;
    }
  }
  // Do the work for update
  CNewFrame<CDialog>::OnInitMenuPopup(pMenu,nIndex,bSysMenu);
}

//
// Construction/Destruction
//

IMPLEMENT_DYNCREATE(CNewMiniFrameWnd,CMiniFrameWnd)
BEGIN_MESSAGE_MAP(CNewMiniFrameWnd, CNewFrame<CMiniFrameWnd>)
  //{{AFX_MSG_MAP(CNewMiniFrameWnd)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //    DO NOT EDIT what you see in these blocks of generated code!
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

IMPLEMENT_DYNCREATE(CNewMDIChildWnd,CMDIChildWnd)
BEGIN_MESSAGE_MAP(CNewMDIChildWnd, CNewFrame<CMDIChildWnd>)
  //{{AFX_MSG_MAP(CNewMDIChildWnd)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //    DO NOT EDIT what you see in these blocks of generated code!
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

IMPLEMENT_DYNCREATE(CNewMiniDockFrameWnd,CMiniDockFrameWnd);
BEGIN_MESSAGE_MAP(CNewMiniDockFrameWnd, CNewFrame<CMiniDockFrameWnd>)
  //{{AFX_MSG_MAP(CNewMiniDockFrameWnd)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //    DO NOT EDIT what you see in these blocks of generated code!
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

//
// Construction/Destruction
//

IMPLEMENT_DYNCREATE(CNewFrameWnd,CFrameWnd)

BEGIN_MESSAGE_MAP(CNewFrameWnd, CNewFrame<CFrameWnd>)
  //{{AFX_MSG_MAP(CNewFrameWnd)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //    DO NOT EDIT what you see in these blocks of generated code!
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

#if _MFC_VER < 0x0700

#include <../src/afximpl.h>

BOOL CNewFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
                             CWnd* pParentWnd, CCreateContext* pContext)
{
  // only do this once
  ASSERT_VALID_IDR(nIDResource);
  ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);

  m_nIDHelp = nIDResource;    // ID for help context (+HID_BASE_RESOURCE)

  CString strFullString;
  if (strFullString.LoadString(nIDResource))
    AfxExtractSubString(m_strTitle, strFullString, 0);    // first sub-string

  VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));

  // attempt to create the window
  LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);
  LPCTSTR lpszTitle = m_strTitle;
  if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault,
    pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext))
  {
    return FALSE;   // will self destruct on failure normally
  }

  // save the default menu handle
  ASSERT(m_hWnd != NULL);
  m_hMenuDefault = ::GetMenu(m_hWnd);

  // load accelerator resource
  LoadAccelTable(MAKEINTRESOURCE(nIDResource));

  if (pContext == NULL)   // send initial update
    SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

  return TRUE;
}
#endif

BOOL CNewFrameWnd::Create(LPCTSTR lpszClassName,
                          LPCTSTR lpszWindowName,
                          DWORD dwStyle,
                          const RECT& rect,
                          CWnd* pParentWnd,
                          LPCTSTR lpszMenuName,
                          DWORD dwExStyle,
                          CCreateContext* pContext)
{
  if (lpszMenuName != NULL)
  {
    m_DefaultNewMenu.LoadMenu(lpszMenuName);
    // load in a menu that will get destroyed when window gets destroyed
    if (m_DefaultNewMenu.m_hMenu == NULL)
    {
#if _MFC_VER < 0x0700
      TRACE0("Warning: failed to load menu for CNewFrameWnd.\n");
#else
      TRACE(traceAppMsg, 0, "Warning: failed to load menu for CNewFrameWnd.\n");
#endif
      PostNcDestroy();            // perhaps delete the C++ object
      return FALSE;
    }
  }
  m_strTitle = lpszWindowName;    // save title for later

  if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
    rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
    pParentWnd->GetSafeHwnd(), m_DefaultNewMenu.m_hMenu, (LPVOID)pContext))
  {
#if _MFC_VER < 0x0700
    TRACE0("Warning: failed to create CNewFrameWnd.\n");
#else
    TRACE(traceAppMsg, 0, "Warning: failed to create CNewFrameWnd.\n");
#endif

    return FALSE;
  }

  UpdateMenuBarColor(m_DefaultNewMenu);

  return TRUE;
}

#ifdef USE_NEW_DOCK_BAR

//Bug in compiler??

#ifdef _AFXDLL
// control bar docking
// dwDockBarMap
const DWORD CFrameWnd::dwDockBarMap[4][2] =
{
  { AFX_IDW_DOCKBAR_TOP,      CBRS_TOP    },
  { AFX_IDW_DOCKBAR_BOTTOM,   CBRS_BOTTOM },
  { AFX_IDW_DOCKBAR_LEFT,     CBRS_LEFT   },
  { AFX_IDW_DOCKBAR_RIGHT,    CBRS_RIGHT  },
};
#endif

// dock bars will be created in the order specified by dwDockBarMap
// this also controls which gets priority during layout
// this order can be changed by calling EnableDocking repetitively
// with the exact order of priority
void CNewFrameWnd::EnableDocking(DWORD dwDockStyle)
{
  // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);

  m_pFloatingFrameClass = RUNTIME_CLASS(CNewMiniDockFrameWnd);
  for (int i = 0; i < 4; i++)
  {
    if (dwDockBarMap[i][1] & dwDockStyle & CBRS_ALIGN_ANY)
    {
      CDockBar* pDock = (CDockBar*)GetControlBar(dwDockBarMap[i][0]);
      if (pDock == NULL)
      {
        pDock = new CNewDockBar;
        if (!pDock->Create(this,
          WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE |
          dwDockBarMap[i][1], dwDockBarMap[i][0]))
        {
          AfxThrowResourceException();
        }
      }
    }
  }
}
#endif

//
// Construction/Destruction
//

IMPLEMENT_DYNAMIC(CNewMDIFrameWnd,CMDIFrameWnd)

BEGIN_MESSAGE_MAP(CNewMDIFrameWnd, CNewFrame<CMDIFrameWnd>)
  //{{AFX_MSG_MAP(CNewMDIFrameWnd)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //    DO NOT EDIT what you see in these blocks of generated code!
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CNewMDIFrameWnd::ShowMenu(BOOL bShow)
{
  // Gets the actual menu
  HMENU hMenu = ::GetMenu(m_hWnd);
  if(bShow)
  {
    if(m_hShowMenu)
    {
      ::SetMenu(m_hWnd, m_hShowMenu);
      DrawMenuBar();
      m_hShowMenu = NULL;
      return FALSE;
    }
    return TRUE;
  }
  else
  {
    m_hShowMenu = hMenu;
    if(m_hShowMenu)
    {
      ::SetMenu(m_hWnd, NULL);
      DrawMenuBar();
      return TRUE;
    }
    return FALSE;
  }
}



#if _MFC_VER < 0x0700

BOOL CNewMDIFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
                                CWnd* pParentWnd, CCreateContext* pContext)
{
  // only do this once
  ASSERT_VALID_IDR(nIDResource);
  ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);

  m_nIDHelp = nIDResource;    // ID for help context (+HID_BASE_RESOURCE)

  CString strFullString;
  if (strFullString.LoadString(nIDResource))
    AfxExtractSubString(m_strTitle, strFullString, 0);    // first sub-string

  VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));

  // attempt to create the window
  LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);
  LPCTSTR lpszTitle = m_strTitle;
  if (!Create(lpszClass, lpszTitle, dwDefaultStyle, rectDefault,
    pParentWnd, MAKEINTRESOURCE(nIDResource), 0L, pContext))
  {
    return FALSE;   // will self destruct on failure normally
  }

  // save the default menu handle
  ASSERT(m_hWnd != NULL);
  m_hMenuDefault = ::GetMenu(m_hWnd);

  // load accelerator resource
  LoadAccelTable(MAKEINTRESOURCE(nIDResource));

  if (pContext == NULL)   // send initial update
    SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

  // save menu to use when no active MDI child window is present
  ASSERT(m_hWnd != NULL);
  m_hMenuDefault = ::GetMenu(m_hWnd);
  if (m_hMenuDefault == NULL)
    TRACE0("Warning: CMDIFrameWnd without a default menu.\n");
  return TRUE;
}
#endif

BOOL CNewMDIFrameWnd::Create( LPCTSTR lpszClassName,
                             LPCTSTR lpszWindowName,
                             DWORD dwStyle,
                             const RECT& rect,
                             CWnd* pParentWnd,
                             LPCTSTR lpszMenuName,
                             DWORD dwExStyle,
                             CCreateContext* pContext)
{
  if (lpszMenuName != NULL)
  {
    m_DefaultNewMenu.LoadMenu(lpszMenuName);
    // load in a menu that will get destroyed when window gets destroyed
    if (m_DefaultNewMenu.m_hMenu == NULL)
    {
#if _MFC_VER < 0x0700
      TRACE0("Warning: failed to load menu for CNewMDIFrameWnd.\n");
#else
      TRACE(traceAppMsg, 0, "Warning: failed to load menu for CNewMDIFrameWnd.\n");
#endif
      PostNcDestroy();            // perhaps delete the C++ object
      return FALSE;
    }
  }

  m_strTitle = lpszWindowName;    // save title for later

  if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
    rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
    pParentWnd->GetSafeHwnd(), m_DefaultNewMenu.m_hMenu, (LPVOID)pContext))
  {
#if _MFC_VER < 0x0700
    TRACE0("Warning: failed to create CNewMDIFrameWnd.\n");
#else
    TRACE(traceAppMsg, 0, "Warning: failed to create CNewMDIFrameWnd.\n");
#endif

    return FALSE;
  }

  UpdateMenuBarColor(m_DefaultNewMenu);

  return TRUE;
}

#ifdef USE_NEW_DOCK_BAR

// dock bars will be created in the order specified by dwDockBarMap
// this also controls which gets priority during layout
// this order can be changed by calling EnableDocking repetitively
// with the exact order of priority
void CNewMDIFrameWnd::EnableDocking(DWORD dwDockStyle)
{
  // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);

  m_pFloatingFrameClass = RUNTIME_CLASS(CNewMiniDockFrameWnd);
  for (int i = 0; i < 4; i++)
  {
    if (dwDockBarMap[i][1] & dwDockStyle & CBRS_ALIGN_ANY)
    {
      CDockBar* pDock = (CDockBar*)GetControlBar(dwDockBarMap[i][0]);
      if (pDock == NULL)
      {
        pDock = new CNewDockBar;
        if (!pDock->Create(this,
          WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE |
          dwDockBarMap[i][1], dwDockBarMap[i][0]))
        {
          AfxThrowResourceException();
        }
      }
    }
  }
}
#endif

//
// Construction/Destruction
//

IMPLEMENT_DYNAMIC(CNewMultiDocTemplate,CMultiDocTemplate)

CNewMultiDocTemplate::CNewMultiDocTemplate(UINT nIDResource,
                                           CRuntimeClass* pDocClass,
                                           CRuntimeClass* pFrameClass,
                                           CRuntimeClass* pViewClass)
                                           : CMultiDocTemplate(nIDResource,pDocClass,pFrameClass,pViewClass)
{
  if (m_nIDResource != 0 && m_hMenuShared)
  {
    // Attach the menu.
    m_NewMenuShared.LoadMenu(m_hMenuShared);
    // Try to load icons to the toolbar.
    m_NewMenuShared.LoadToolBar(m_nIDResource);
  }
}

CNewMultiDocTemplate::~CNewMultiDocTemplate()
{
  // Let only the CNewMenu to destroy the menu.
  if(m_hMenuShared==m_NewMenuShared.m_hMenu)
  {
    m_hMenuShared = NULL;
  }
}


//
// Construction/Destruction
//

CNewMenuHelper::CNewMenuHelper(DWORD dwFlags)
{
  m_dwOldFlags = CNewMenuHook::m_bSubclassFlag;
  CNewMenuHook::m_bSubclassFlag = dwFlags;

  m_OldMenuDrawStyle = CNewMenu::GetMenuDrawMode();
  if(CNewMenuHook::m_bSubclassFlag&NEW_MENU_DEFAULT_BORDER)
  {
    CNewMenu::SetMenuDrawMode(m_OldMenuDrawStyle|1);
  }
}

CNewMenuHelper::CNewMenuHelper(CNewMenu::EDrawStyle setTempStyle)
{
  m_dwOldFlags = CNewMenuHook::m_bSubclassFlag;
  m_OldMenuDrawStyle = CNewMenu::SetMenuDrawMode(setTempStyle);
}

CNewMenuHelper::~CNewMenuHelper()
{
  // Restore the old border style
  CNewMenu::SetMenuDrawMode(m_OldMenuDrawStyle);
  CNewMenuHook::m_bSubclassFlag = m_dwOldFlags;
}


// CNewDockBar

IMPLEMENT_DYNCREATE(CNewDockBar, CDockBar)

CNewDockBar::CNewDockBar(BOOL bFloating):CDockBar(bFloating)
{
}

CNewDockBar::~CNewDockBar()
{
}

BEGIN_MESSAGE_MAP(CNewDockBar, CDockBar)
  //{{AFX_MSG_MAP(CNewDockBar)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //    DO NOT EDIT what you see in these blocks of generated code!
  //}}AFX_MSG_MAP
  ON_WM_ERASEBKGND()
  ON_WM_NCPAINT()
END_MESSAGE_MAP()


// CNewDockBar diagnostics

#if defined(_DEBUG) || defined(_AFXDLL)
void CNewDockBar::AssertValid() const
{
  CDockBar::AssertValid();
}

void CNewDockBar::Dump(CDumpContext& dc) const
{
  CDockBar::Dump(dc);
}
#endif //_DEBUG


// CNewDockBar message handlers
void CNewDockBar::EraseNonClient()
{
  // get window DC that is clipped to the non-client area
  CWindowDC dc(this);
  CRect rectClient;
  GetClientRect(rectClient);
  CRect rectWindow;
  GetWindowRect(rectWindow);
  ScreenToClient(rectWindow);
  rectClient.OffsetRect(-rectWindow.left, -rectWindow.top);
  dc.ExcludeClipRect(rectClient);

  // draw borders in non-client area
  rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top);

  //DrawBorders(&dc, rectWindow);

  // erase parts not drawn
  dc.IntersectClipRect(rectWindow);
  SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC);

  // draw gripper in non-client area
  DrawGripper(&dc, rectWindow);
}

BOOL CNewDockBar::OnEraseBkgnd(CDC* pDC)
{
  MENUINFO menuInfo = {0};
  menuInfo.cbSize = sizeof(menuInfo);
  menuInfo.fMask = MIM_BACKGROUND;

  //if(::GetMenuInfo(::GetMenu(::GetParent(m_hWnd)),&menuInfo) && menuInfo.hbrBack)
  CBrush *pBrush = GetMenuBarBrush();
  if(pBrush)
  {
    CRect rectA;
    CRect rectB;
    GetWindowRect(rectA);
    ::GetWindowRect(::GetParent(m_hWnd),rectB);

    // need for win95/98/me
    VERIFY(pBrush->UnrealizeObject());
    CPoint oldOrg = pDC->SetBrushOrg(-(rectA.left-rectB.left),0);
    CRect rect;
    pDC->GetClipBox(rect);
    pDC->FillRect(rect,pBrush);
    pDC->SetBrushOrg(oldOrg);
    return true;
  }
  else
  {
    // do default drawing
    return CDockBar::OnEraseBkgnd(pDC);
  }
}

void CNewDockBar::OnNcPaint()
{
  // Do not call CDockBar::OnNcPaint() for painting messages
  EraseNonClient();
}

DWORD CNewDockBar::RecalcDelayShow(AFX_SIZEPARENTPARAMS* lpLayout)
{
  DWORD result = CDockBar::RecalcDelayShow(lpLayout);

#ifdef USE_NEW_MENU_BAR

  // we want to have the menubar on its own row or column and align to border
  int nCount = (int)m_arrBars.GetSize();
  for(int nPos=0;nPos<nCount;nPos++)
  {
    CControlBar *pBar = GetDockedControlBar(nPos);
    if(DYNAMIC_DOWNCAST(CNewMenuBar,pBar))
    {
      if(nPos && GetDockedControlBar(nPos-1))
      {
        // insert a row break befor the menubar
        m_arrBars.InsertAt(nPos,(void*)0);
        nPos++;
        nCount++;
      }
      CRect rect;
      pBar->GetWindowRect(rect);
      ScreenToClient(rect);
      if(pBar->m_dwStyle&CBRS_ORIENT_HORZ)
      {
        if(rect.left>0)
        {
          pBar->SetWindowPos(NULL,-5,rect.top,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_FRAMECHANGED);
        }
      }
      else
      {
        if(rect.top>0)
        {
          pBar->SetWindowPos(NULL,rect.left,-5,0,0,SWP_NOZORDER|SWP_NOSIZE|SWP_FRAMECHANGED);
        }
      }

      if((nPos+1)<nCount && GetDockedControlBar(nPos+1))
      {
        // insert a row break after the menubar
        m_arrBars.InsertAt(nPos+1,(void*)0);
        nCount++;
      }
    }
  }
#endif //USE_NEW_MENU_BAR

  return result;
}

TCHAR szShadeWindowClass[] = _T("ShadeWindow");

typedef struct
{
  CRect parentRect;
  HWND hParent;
  BOOL bSideShade;
}SShadeInfo;


void DrawWindowShade(HDC hDC, CRect rect, COLORREF blendColor)
{
  if (NumScreenColors() <= 256)
  {
    DWORD rgb = ::GetSysColor(COLOR_BTNSHADOW);
    COLORREF oldColor = ::SetBkColor(hDC, rgb);
    ::ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
    ::SetBkColor(hDC, oldColor);
  }
  else
  {
    COLORREF ref;
    int width = rect.Width();
    int height = rect.Height();
    int X,Y;

    if(width<height)
    {
      for (X=0; X<=4 ;X++)
      {
        for (Y=0; Y<=4 ;Y++)
        {
          // Simulate a shadow on the left edge...
          ref = GetAlphaBlendColor(blendColor,GetPixel(hDC,X,Y),255-(4-X)*Y*10);
          SetPixel(hDC,X,Y,ref);
        }
        for (;Y<height;Y++)
        {
          // Simulate a shadow on the left...
          ref = GetAlphaBlendColor(blendColor,GetPixel(hDC,X,Y),240-(4-X)*40);
          SetPixel(hDC,X,Y,ref);
        }
      }
    }
    else
    {
      for(Y=0; Y<=4 ;Y++)
      {
        // Simulate a shadow on the bottom edge...
        for(X=0; X<=4 ;X++)
        {
          ref = GetAlphaBlendColor(blendColor,GetPixel(hDC,X,Y),255-(4-Y)*X*10);
          SetPixel(hDC,X,Y,ref);
        }
        // Simulate a shadow on the bottom...
        for(;X<=(width-5);X++)
        {
          ref = GetAlphaBlendColor(blendColor,GetPixel(hDC,X,Y),240-(4-Y)*40);
          SetPixel(hDC,X,Y,ref);
        }
        // Simulate a shadow on the bottom edge...
        for(;X<width;X++)
        {
          ref = GetAlphaBlendColor(blendColor,GetPixel(hDC,X,Y),255-((width-1-X)*(4-Y))*10);
          SetPixel(hDC,X,Y,ref);
        }
      }
    }
  }

}
//
//  FUNCTION: ShadeWndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the shade window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT  - Paint the main window
//  WM_DESTROY  - post a quit message and return


LRESULT CALLBACK ShadeWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  //  static long NestedLevel = 0;
  //  NestedLevel++;
  //  MSG msg = {hWnd,message,wParam,lParam,0,0,0};
  //  TCHAR Buffer[30];
  //  wsprintf(Buffer,_T("Level %02ld"),NestedLevel);
  //  MyTraceMsg(Buffer,&msg);

  LRESULT result = 0;
  switch (message)
  {
  case WM_MOVE:
    result = DefWindowProc(hWnd, message, wParam, lParam);
    InvalidateRect(hWnd,NULL,TRUE);
    break;

  case WM_ERASEBKGND:
    {
      CRect rect;
      GetClientRect(hWnd,&rect);
      COLORREF blendColor = ::GetSysColor(COLOR_ACTIVECAPTION);//RGB(255,0,0);

      DrawWindowShade((HDC) wParam, rect, blendColor);
      ValidateRect(hWnd,&rect);
    }
    return FALSE;

  case WM_NCHITTEST:
    return HTTRANSPARENT;

  case WM_PAINT:
    {
      PAINTSTRUCT ps;
      HDC hDC = BeginPaint(hWnd, &ps);
      CRect rect;
      COLORREF blendColor = ::GetSysColor(COLOR_ACTIVECAPTION);//RGB(255,0,0);
      GetClientRect(hWnd,&rect);

      DrawWindowShade(hDC, rect, blendColor);

      ValidateRect(hWnd,&rect);

      EndPaint(hWnd, &ps);
    }
    break;

  case WM_TIMER:
    {
      KillTimer(hWnd,wParam);
      CRect rect;
      HWND hParent = GetParent(hWnd);
      GetWindowRect(hParent,rect);
      SetWindowPos(hWnd,0,rect.right,rect.top,6,rect.Height(),SWP_NOZORDER|SWP_SHOWWINDOW);
    }

    break;

  case WM_WINDOWPOSCHANGED :
    //if (true)
    {
      result = DefWindowProc(hWnd, message, wParam, lParam);
      WINDOWPOS *pWP = (WINDOWPOS*)lParam;
      if (pWP->hwnd != hWnd)
        SetWindowPos (hWnd, HWND_TOP, 0, 0, 0, 0,SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
    }
    break;

  case WM_SHOWWINDOW:
    {
      result = DefWindowProc(hWnd, message, wParam, lParam);
      //if(wParam)
      //{
      //  // window is show
      //  //InvalidateRect(hWnd,NULL,FALSE);
      //  SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW|SWP_NOACTIVATE);
      //}
      //else
      //{
      //  // window disappear
      //  InvalidateRect(hWnd,NULL,FALSE);
      //}
    }
    break;

  case WM_CREATE:
    {
      LPCREATESTRUCT pCreate = (LPCREATESTRUCT)lParam;
      ASSERT(pCreate);
      //CRect rect;
      //GetWindowRect(pCreate->hwndParent,rect);
      result = DefWindowProc(hWnd, message, wParam, lParam);
      SShadeInfo *pShadeInfo = (SShadeInfo*)pCreate->lpCreateParams;
      ASSERT(pShadeInfo);
      if(pShadeInfo->bSideShade)
      {
        SetWindowPos(hWnd,HWND_TOPMOST,
          pShadeInfo->parentRect.left+5,pShadeInfo->parentRect.bottom,
          pShadeInfo->parentRect.Width(),5,
          SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOZORDER);
      }
      else
      {
        SetWindowPos(hWnd,HWND_TOPMOST,
          pShadeInfo->parentRect.right,pShadeInfo->parentRect.top+5,
          5,pShadeInfo->parentRect.Height()-5,
          SWP_SHOWWINDOW|SWP_NOACTIVATE);
      }
      //GetSafeTimerID(hWnd,200);
    }
    break;

  default:
    return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return result;
}


//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
BOOL ShadeRegisterClass()
{
  WNDCLASS wndcls;

  wndcls.style         = CS_HREDRAW | CS_VREDRAW;
  wndcls.lpfnWndProc   = (WNDPROC)ShadeWndProc;
  wndcls.cbClsExtra    = 0;
  wndcls.cbWndExtra    = 0;
  wndcls.hInstance     = AfxGetInstanceHandle();
  wndcls.hIcon         = (HICON)NULL;
  wndcls.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wndcls.hbrBackground = (HBRUSH)NULL;
  wndcls.lpszMenuName  = (LPCTSTR)NULL;
  wndcls.lpszClassName = szShadeWindowClass;

  return AfxRegisterClass(&wndcls);
}

void SetWindowShade(HWND hWndParent,LPRECT pRect)
{
  ShadeRegisterClass();

  SShadeInfo shadeInfo;

  shadeInfo.hParent = hWndParent;
  if(pRect!=NULL)
  {
    shadeInfo.parentRect = *pRect;
  }
  else
  {
    GetWindowRect(hWndParent,&shadeInfo.parentRect);
  }

  shadeInfo.bSideShade = true;
  HWND hWnd = CreateWindowEx(WS_EX_TRANSPARENT|WS_EX_TOPMOST ,
    szShadeWindowClass,
    NULL,
    WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
    CW_USEDEFAULT, 0,
    CW_USEDEFAULT, 0,
    hWndParent, (HMENU)0,
    AfxGetInstanceHandle(),
    &shadeInfo);

  shadeInfo.bSideShade = false;
  hWnd = CreateWindowEx( WS_EX_TRANSPARENT|WS_EX_TOPMOST ,
    szShadeWindowClass,
    NULL,
    WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
    CW_USEDEFAULT, 0,
    CW_USEDEFAULT, 0,
    hWndParent, (HMENU)0,
    AfxGetInstanceHandle(),
    &shadeInfo);
}

//void SetWindowShade(HWND hWndMenu, CNewMenuHook::CMenuHookData* pData )
//{
//  if(pData==NULL || pData->m_hRightShade!=NULL || pData->m_hBottomShade)
//  {
//    return;
//  }
//
//  ShadeRegisterClass();
//
//  HWND hWndParent = AfxGetMainWnd()->GetSafeHwnd();
//  SShadeInfo shadeInfo;
//  shadeInfo.hParent = hWndMenu;
//  GetWindowRect(hWndMenu,&shadeInfo.parentRect);
//
//  shadeInfo.bSideShade = true;
//
//  pData->m_hRightShade = CreateWindowEx(WS_EX_TRANSPARENT|WS_EX_TOPMOST ,
//                                        szShadeWindowClass,
//                                        NULL,
//                                        WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
//                                        CW_USEDEFAULT, 0,
//                                        CW_USEDEFAULT, 0,
//                                        hWndParent, (HMENU)0,
//                                        AfxGetInstanceHandle(),
//                                        &shadeInfo);
//
//  shadeInfo.bSideShade = false;
//  pData->m_hBottomShade = CreateWindowEx( WS_EX_TRANSPARENT|WS_EX_TOPMOST ,
//                                          szShadeWindowClass,
//                                          NULL,
//                                          WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
//                                          CW_USEDEFAULT, 0,
//                                          CW_USEDEFAULT, 0,
//                                          hWndParent, (HMENU)0,
//                                          AfxGetInstanceHandle(),
//                                          &shadeInfo);
//}


#ifdef _AFXDLL

static void ForceVectorDelete()
{
  // this function is only need for exporting all template
  // functions

  // never called
  ASSERT(FALSE);

  new CNewFrameWnd[2];

  new CNewMDIChildWnd[2];
  new CNewMDIFrameWnd[2];

  new CNewDialog[2];

  new CNewMiniDockFrameWnd[2];
  new CNewMiniFrameWnd[2];
}

void (*_ForceVectorDelete)() = &ForceVectorDelete;

#endif

头文件:

//------------------------------------------------------------------------------
// File    : NewMenu.h 
// Version : 1.25
// Date    : 25. June 2005
// Author  : Bruno Podetti
// Email   : podetti@gmx.net
// Web     : www.podetti.com/NewMenu 
// Systems : VC6.0/7.0 and VC7.1 (Run under (Window 98/ME), Windows Nt 2000/XP)
//           for all systems it will be the best when you install the latest IE
//           it is recommended for CNewToolBar
//
// You are free to use/modify this code but leave this header intact.
// This class is public domain so you are free to use it any of your 
// applications (Freeware, Shareware, Commercial). 
// All I ask is that you let me know so that if you have a real winner I can
// brag to my buddies that some of my code is in your app. I also wouldn't 
// mind if you sent me a copy of your application since I like to play with
// new stuff.
//------------------------------------------------------------------------------
#ifndef __CNewMenu_H_
#define __CNewMenu_H_

// new constant for having the same color in the toolbar, you can define this
// also in the projekt definition
//#define USE_NEW_DOCK_BAR

// for using my CNewMenu in the GuiToolkit see
// http://www.codeproject.com/library/guitoolkit.asp
// you need to #define _GUILIB_   in the ExtLib.h  and include this file
// the constant for exporting importing these classes can be changed in the 
// next release GUILIBDLLEXPORT!!!

#ifdef NEW_MENU_DLL
  #ifdef NEW_MENU_DLL_EXPORT
    #define GUILIBDLLEXPORT __declspec(dllexport)
  #else
    #define GUILIBDLLEXPORT __declspec(dllimport)

#if _MSC_VER >= 1300
    // older compiler have a bug. static template member were not exported corectly
    // so we need this
    #define _GUILIB_
#endif

  #endif
#endif

#ifndef GUILIBDLLEXPORT
#define GUILIBDLLEXPORT
#endif

#pragma warning(push)
#pragma warning(disable : 4211)

#include <afxtempl.h>
#include <afxpriv.h>

// Flagdefinitions 
#define MFT_TITLE       0x0001
#define MFT_TOP_TITLE   0x0000
#define MFT_SIDE_TITLE  0x0002
#define MFT_GRADIENT    0x0004
#define MFT_SUNKEN      0x0008
#define MFT_LINE        0x0010
#define MFT_ROUND       0x0020
#define MFT_CENTER      0x0040

// Typedefinition for compatibility to MFC 7.0
#ifndef DWORD_PTR
typedef DWORD DWORD_PTR, *PDWORD_PTR;
#endif

#ifndef ULONG_PTR
typedef unsigned long ULONG_PTR, *PULONG_PTR;
#endif

#ifndef LONG_PTR
typedef long LONG_PTR, *PLONG_PTR;
#endif

// Additional flagdefinition for highlighting
#ifndef ODS_HOTLIGHT
#define ODS_HOTLIGHT        0x0040
#endif

#ifndef ODS_INACTIVE
#define ODS_INACTIVE        0x0080
#endif

// Typedefinition for old compatibility lesser than MFC 8.0
#if _MFC_VER < 0x0800  
#define _tcscpy_s(strDestination,sizeInTchar,strSource )  _tcscpy(strDestination,strSource)
#define _tcsncpy_s(strDestination,sizeInTchar,strSource,sizeCopyInTchar) _tcsncpy(strDestination,strSource,sizeCopyInTchar)
#endif


// new define menustyles
#define ODS_SELECTED_OPEN   0x0800
#define ODS_RIGHTJUSTIFY    0x1000
#define ODS_WRAP            0x2000
#define ODS_HIDDEN          0x4000
#define ODS_DRAW_VERTICAL   0x8000


/
// Constans for detecting OS-Type
enum Win32Type
{
  Win32s,
  WinNT3,
  Win95,
  Win98,
  WinME,
  WinNT4,
  Win2000,
  WinXP
};

Win32Type GUILIBDLLEXPORT IsShellType();

extern const Win32Type GUILIBDLLEXPORT g_Shell;
extern BOOL GUILIBDLLEXPORT bRemoteSession;
BOOL GUILIBDLLEXPORT IsMenuThemeActive();

/
// Support for getting menuinfo without runtime-error

#if(WINVER < 0x0500)

#define MNS_NOCHECK         0x80000000
#define MNS_MODELESS        0x40000000
#define MNS_DRAGDROP        0x20000000
#define MNS_AUTODISMISS     0x10000000
#define MNS_NOTIFYBYPOS     0x08000000
#define MNS_CHECKORBMP      0x04000000

#define MIM_MAXHEIGHT               0x00000001
#define MIM_BACKGROUND              0x00000002
#define MIM_HELPID                  0x00000004
#define MIM_MENUDATA                0x00000008
#define MIM_STYLE                   0x00000010
#define MIM_APPLYTOSUBMENUS         0x80000000


typedef struct tagMENUINFO
{
  DWORD   cbSize;
  DWORD   fMask;
  DWORD   dwStyle;
  UINT    cyMax;
  HBRUSH  hbrBack;
  DWORD   dwContextHelpID;
  ULONG_PTR dwMenuData;
}   MENUINFO, FAR *LPMENUINFO;
typedef MENUINFO CONST FAR *LPCMENUINFO;

BOOL GUILIBDLLEXPORT GetMenuInfo( HMENU hMenu, LPMENUINFO pInfo);
BOOL GUILIBDLLEXPORT SetMenuInfo( HMENU hMenu, LPCMENUINFO pInfo);

#define WS_EX_LAYOUTRTL         0x00400000L // Right to left mirroring

#define LAYOUT_RTL              0x00000001  // Right to left

DWORD GUILIBDLLEXPORT GetLayout(HDC hDC);
DWORD GUILIBDLLEXPORT SetLayout(HDC hDC, DWORD dwLayout);

#endif

inline bool IsMirroredHdc(HDC hDC)
{
  return (GetLayout(hDC)&LAYOUT_RTL)?true:false;
}

inline bool IsMirroredWnd(HWND hWnd)
{
  return (GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL)?true:false;
}

CRect GUILIBDLLEXPORT GetScreenRectFromWnd(HWND hWnd);
CRect GUILIBDLLEXPORT GetScreenRectFromRect(LPCRECT pRect);
BOOL GUILIBDLLEXPORT TrackPopupMenuSpecial(CMenu *pMenu, UINT uFlags, CRect rcTBItem, CWnd* pWndCommand, BOOL bOnSide);

/
// Forwarddeclaration and global function for menu drawing
void GUILIBDLLEXPORT DrawGradient(CDC* pDC,CRect& Rect,
                                  COLORREF StartColor,COLORREF EndColor, 
                                  BOOL bHorizontal,BOOL bUseSolid=FALSE);

void GUILIBDLLEXPORT MenuDrawText(HDC hDC ,LPCTSTR lpString,int nCount,LPRECT lpRect,UINT uFormat);


COLORREF GUILIBDLLEXPORT DarkenColorXP(COLORREF color);
COLORREF GUILIBDLLEXPORT DarkenColor( long lScale, COLORREF lColor);

COLORREF GUILIBDLLEXPORT MixedColor(COLORREF colorA,COLORREF colorB);
COLORREF GUILIBDLLEXPORT MidColor(COLORREF colorA,COLORREF colorB);

COLORREF GUILIBDLLEXPORT LightenColor( long lScale, COLORREF lColor);

COLORREF GUILIBDLLEXPORT BleachColor(int Add, COLORREF color);
COLORREF GUILIBDLLEXPORT GetAlphaBlendColor(COLORREF blendColor, COLORREF pixelColor,int weighting);

COLORREF GUILIBDLLEXPORT GetXpHighlightColor();
COLORREF GUILIBDLLEXPORT GrayColor(COLORREF crColor); 

/
// Global helperfunctions
UINT GUILIBDLLEXPORT GetSafeTimerID(HWND hWnd, const UINT uiElapse);

BOOL GUILIBDLLEXPORT DrawMenubarItem(CWnd* pWnd,CMenu* pMenu, UINT nItemIndex,UINT nState);
void GUILIBDLLEXPORT UpdateMenuBarColor(HMENU hMenu=NULL);
CBrush GUILIBDLLEXPORT *GetMenuBarBrush();

int GUILIBDLLEXPORT NumScreenColors();
WORD GUILIBDLLEXPORT NumBitmapColors(LPBITMAPINFOHEADER lpBitmap);
HBITMAP GUILIBDLLEXPORT LoadColorBitmap(LPCTSTR lpszResourceName, HMODULE hInst, int* pNumcol=NULL);

COLORREF GUILIBDLLEXPORT MakeGrayAlphablend(CBitmap* pBitmap, int weighting, COLORREF blendcolor);
HBITMAP GUILIBDLLEXPORT CreateBitmapMask(HBITMAP hbmColour, COLORREF crTransparent);

/
// Forwarddeclaration for drawing purpose
class CNewMenu;
class CMenuTheme;
class CNewDockBar;

/
// CMenuTheme for drawing border and the rest

typedef void (CNewMenu::*pItemMeasureFkt) (LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenubar);
typedef void (CNewMenu::*pItemDrawFkt) (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenubar);
typedef BOOL (CNewMenu::*pEraseBkgndFkt) (HWND hWnd, HDC hDC);

typedef void (CMenuTheme::*pDrawMenuBorder)( HWND hWnd, HDC hDC, CPoint screen);

class GUILIBDLLEXPORT CMenuTheme
{
public:
  CMenuTheme();

  CMenuTheme(DWORD dwThemeId,
    pItemMeasureFkt pMeasureItem,
    pItemDrawFkt pDrawItem,
    pItemDrawFkt pDrawTitle,
    DWORD dwFlags=0);

  virtual ~CMenuTheme();
  virtual BOOL OnInitWnd(HWND hWnd);
  virtual BOOL OnUnInitWnd(HWND hWnd);

  virtual BOOL DoDrawBorder();

  virtual void UpdateSysColors();
  virtual void UpdateSysMetrics();

  virtual BOOL OnDrawBorder(HWND hWnd, HDC hDC, BOOL bOnlyBorder=FALSE);
  virtual BOOL OnEraseBkgnd(HWND hWnd, HDC hDC);
  virtual BOOL OnNcCalcSize(HWND hWnd, NCCALCSIZE_PARAMS* pCalc);
  virtual BOOL OnWindowPosChanging(HWND hWnd, LPWINDOWPOS pPos);
  virtual BOOL OnCalcFrameRect(HWND hWnd,LPRECT pRect);

  virtual void DrawGripper( CDC* pDC, const CRect& rect, DWORD dwStyle, 	
                            int m_cxLeftBorder, int m_cxRightBorder,
                            int m_cyTopBorder, int m_cyBottomBorder);

  virtual void DrawCorner ( CDC* pDC, LPCRECT pRect, DWORD dwStyle);

  void PaintCorner(CDC *pDC, LPCRECT pRect, COLORREF color);

  virtual void GetBarColor(COLORREF &clrUpperColor, COLORREF &clrMediumColor, COLORREF &clrBottomColor, COLORREF &clrDarkLine);

  void DrawShade( HWND hWnd, HDC hDC, CPoint screen);
  void DrawSmalBorder( HWND hWnd, HDC hDC);
  void DrawFrame(CDC* pDC, CRect rectOuter, CRect rectInner, COLORREF crBorder);

  void* SetScreenBitmap(HWND hWnd, HDC hDC);

public:
  DWORD m_dwThemeId;
  DWORD m_dwFlags;

  pItemMeasureFkt m_pMeasureItem;
  pItemDrawFkt m_pDrawItem;
  pItemDrawFkt m_pDrawTitle;

  CSize m_BorderTopLeft;
  CSize m_BorderBottomRight;

	// color values of system colors used for CToolBar
	COLORREF clrBtnFace, clrBtnShadow, clrBtnHilite;
	COLORREF clrBtnText, clrWindowFrame;
};

/
// CMenuThemeXP for drawing border and the rest

class GUILIBDLLEXPORT CMenuThemeXP :public CMenuTheme
{
public:
  CMenuThemeXP(DWORD dwThemeId,
    pItemMeasureFkt pMeasureItem,
    pItemDrawFkt pDrawItem,
    pItemDrawFkt pDrawTitle,
    DWORD dwFlags=0);

  virtual BOOL OnDrawBorder(HWND hWnd, HDC hDC, BOOL bOnlyBorder=FALSE);
  virtual BOOL OnEraseBkgnd(HWND hWnd, HDC hDC);
};

/
// CMenuTheme2003 for drawing border and the rest
class GUILIBDLLEXPORT CMenuTheme2003 :public CMenuThemeXP
{
public:
  CMenuTheme2003(DWORD dwThemeId,
    pItemMeasureFkt pMeasureItem,
    pItemDrawFkt pDrawItem,
    pItemDrawFkt pDrawTitle,
    DWORD dwFlags=0);
};

/
// CNewMenuIcons menu icons for drawing

class GUILIBDLLEXPORT CNewMenuIcons : public CObject
{
  DECLARE_DYNCREATE(CNewMenuIcons)

public:
  CNewMenuIcons();
  virtual ~CNewMenuIcons();

public:
  BOOL GetIconSize(int* cx, int* cy);
  CSize GetIconSize();

  virtual int FindIndex(UINT nID);
  virtual void OnSysColorChange();

  virtual BOOL LoadToolBar(LPCTSTR lpszResourceName, HMODULE hInst);
  virtual BOOL LoadToolBar(WORD* pToolInfo, COLORREF crTransparent=CLR_NONE);
  virtual BOOL LoadToolBar(HBITMAP hBitmap, CSize size, UINT* pID, COLORREF crTransparent=CLR_NONE);

  virtual BOOL DoMatch(LPCTSTR lpszResourceName, HMODULE hInst);
  virtual BOOL DoMatch(WORD* pToolInfo, COLORREF crTransparent=CLR_NONE);
  virtual BOOL DoMatch(HBITMAP hBitmap, CSize size, UINT* pID);

  virtual BOOL LoadBitmap(int nWidth, int nHeight, LPCTSTR lpszResourceName, HMODULE hInst=NULL);

  //  virtual BOOL SetBlendImage();
  virtual int AddGloomIcon(HICON hIcon, int nIndex=-1);
  virtual int AddGrayIcon(HICON hIcon, int nIndex=-1);
  virtual BOOL MakeImages();

  void SetResourceName(LPCTSTR lpszResourceName);

  int AddRef();
  int Release();

#if defined(_DEBUG) || defined(_AFXDLL)
  // Diagnostic Support
  virtual void AssertValid() const;
  virtual void Dump(CDumpContext& dc) const;
#endif

public:
  LPCTSTR m_lpszResourceName;
  HMODULE m_hInst;
  HBITMAP m_hBitmap;
  int m_nColors;
  COLORREF m_crTransparent;

  CImageList m_IconsList;

  CArray<UINT,UINT&> m_IDs;
  DWORD m_dwRefCount;
};

/
// CNewMenuBitmaps menu icons for drawing
class GUILIBDLLEXPORT CNewMenuBitmaps : public CNewMenuIcons
{
  DECLARE_DYNCREATE(CNewMenuBitmaps)

public:
  CNewMenuBitmaps();
  virtual ~CNewMenuBitmaps();

public:
  int Add(UINT nID, COLORREF crTransparent=CLR_NONE);
  int Add(HICON hIcon, UINT nID=0);
  int Add(CBitmap* pBitmap, COLORREF crTransparent=CLR_NONE);

  virtual void OnSysColorChange();

  CArray<COLORREF,COLORREF&> m_TranspColors;
};

/
// CNewMenuItemData menu item data for drawing

class GUILIBDLLEXPORT CNewMenuItemData : public CObject
{
  DECLARE_DYNCREATE(CNewMenuItemData)

public:
  CNewMenuItemData();
  virtual ~CNewMenuItemData();

public:
  // get the item text, 
  // hAccel=INVALID_HANDLE_VALUE = gets the default from the frame
  // hAccel=NULL disable accelerator support
  virtual CString GetString(HACCEL hAccel=NULL);
  virtual void SetString(LPCTSTR szMenuText);

#if defined(_DEBUG) || defined(_AFXDLL)
  // Diagnostic Support
  virtual void AssertValid() const;
  virtual void Dump(CDumpContext& dc) const;
#endif

public:
  CString m_szMenuText;

  UINT m_nTitleFlags;
  UINT m_nFlags;
  UINT m_nID;
  UINT m_nSyncFlag;

  CNewMenuIcons* m_pMenuIcon;
  int m_nMenuIconOffset;

  void* m_pData;
};

/
// CNewMenuItemDataTitle menu item data for drawing menu Title

class GUILIBDLLEXPORT CNewMenuItemDataTitle : public CNewMenuItemData
{
  DECLARE_DYNCREATE(CNewMenuItemDataTitle)

public:
  CNewMenuItemDataTitle();
  virtual ~CNewMenuItemDataTitle();

public:
  COLORREF m_clrTitle;
  COLORREF m_clrLeft;
  COLORREF m_clrRight;

  CFont m_Font;
};

/
// CNewMenu the new menu class

class GUILIBDLLEXPORT CNewMenu : public CMenu
{
  friend class CNewMenuHook;
  friend class CNewMenuIcons;

  DECLARE_DYNCREATE(CNewMenu)

public:
  // how the menu's are drawn, either original or XP style
  typedef enum 
  { 
    STYLE_ORIGINAL=0,
    STYLE_ORIGINAL_NOBORDER=1,

    STYLE_XP=2,
    STYLE_XP_NOBORDER=3,

    STYLE_SPECIAL=4,
    STYLE_SPECIAL_NOBORDER=5,

    STYLE_ICY=6,
    STYLE_ICY_NOBORDER=7,

    STYLE_XP_2003=8,
    STYLE_XP_2003_NOBORDER=9,

    STYLE_COLORFUL=10,
    STYLE_COLORFUL_NOBORDER=11,

    STYLE_LAST = 11,

    STYLE_UNDEFINED = -1

  } EDrawStyle;

  // how seperators are handled when removing a menu (Tongzhe Cui)
  typedef enum {NONE, HEAD, TAIL, BOTH} ESeperator;

public:
  CNewMenu(HMENU hParent=0); 
  virtual ~CNewMenu();

  // Functions for loading and applying bitmaps to menus (see example application)
  virtual BOOL LoadMenu(HMENU hMenu);
  virtual BOOL LoadMenu(LPCTSTR lpszResourceName);
  virtual BOOL LoadMenu(int nResource);

  BOOL LoadToolBar(HBITMAP hBitmap, CSize size, UINT* pID, COLORREF crTransparent=CLR_NONE);
  BOOL LoadToolBar(WORD* pIconInfo, COLORREF crTransparent=CLR_NONE);
  BOOL LoadToolBar(LPCTSTR lpszResourceName, HMODULE hInst = NULL);
  BOOL LoadToolBar(UINT nToolBar, HMODULE hInst = NULL);
  BOOL LoadToolBars(const UINT *arID,int n, HMODULE hInst = NULL);
  // Jan-12-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
  BOOL LoadToolBar(UINT n16ToolBarID, UINT n256BitmapID, COLORREF transparentColor, HMODULE hInst = NULL);

  BOOL LoadFromToolBar(UINT nID,UINT nToolBar,int& xoffset);
  BOOL AddBitmapToImageList(CImageList *list,UINT nResourceID);

  static HBITMAP LoadSysColorBitmap(int nResourceId);
  // custom check mark bitmaps
  void LoadCheckmarkBitmap(int unselect, int select); 

  // functions for appending a menu option, use the AppendMenu call
  BOOL AppendMenu(UINT nFlags,UINT nIDNewItem=0,LPCTSTR lpszNewItem=NULL,int nIconNormal=-1);
  BOOL AppendMenu(UINT nFlags,UINT nIDNewItem,LPCTSTR lpszNewItem,CImageList *il,int xoffset);
  BOOL AppendMenu(UINT nFlags,UINT nIDNewItem,LPCTSTR lpszNewItem,CBitmap *bmp);

  BOOL AppendODMenu(LPCTSTR lpstrText, UINT nFlags = MF_OWNERDRAW, UINT nID = 0, int nIconNormal = -1);  
  BOOL AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID, CBitmap* pbmp);
  BOOL AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID, CImageList *il, int xoffset);
  BOOL AppendODMenu(LPCTSTR lpstrText, UINT nFlags, UINT nID, CNewMenuIcons* pIcons, int nIndex);

  // for appending a popup menu (see example application)
  CNewMenu* AppendODPopupMenu(LPCTSTR lpstrText);

  // functions for inserting a menu option, use the InsertMenu call (see above define)
  BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT nIDNewItem=0,LPCTSTR lpszNewItem=NULL,int nIconNormal=-1);
  BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT nIDNewItem,LPCTSTR lpszNewItem,CImageList *il,int xoffset);
  BOOL InsertMenu(UINT nPosition,UINT nFlags,UINT nIDNewItem,LPCTSTR lpszNewItem,CBitmap *bmp);

  BOOL InsertODMenu(UINT nPosition,LPCTSTR lpstrText, UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);  
  BOOL InsertODMenu(UINT nPosition,LPCTSTR lpstrText, UINT nFlags, UINT nID, CBitmap* pBmp);
  BOOL InsertODMenu(UINT nPosition,LPCTSTR lpstrText, UINT nFlags, UINT nID, CImageList *il,int xoffset);
  BOOL InsertODMenu(UINT nPosition,LPCTSTR lpstrText, UINT nFlags, UINT nID, CNewMenuIcons* pIcons, int nIndex);

  // Same as ModifyMenu but replacement for CNewMenu
  BOOL ModifyODMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem = 0,LPCTSTR lpszNewItem = NULL);
  BOOL ModifyODMenu(UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp);

  // functions for modifying a menu option, use the ModifyODMenu call (see above define)
  BOOL ModifyODMenu(LPCTSTR lpstrText, UINT nID=0, int nIconNormal=-1);
  BOOL ModifyODMenu(LPCTSTR lpstrText, UINT nID, CImageList *il, int xoffset);
  BOOL ModifyODMenu(LPCTSTR lpstrText, UINT nID, CNewMenuIcons* pIcons, int nIndex);

  BOOL ModifyODMenu(LPCTSTR lpstrText,UINT nID,CBitmap *bmp);
  BOOL ModifyODMenu(LPCTSTR lpstrText,LPCTSTR OptionText,int nIconNormal);
  // use this method for adding a solid/hatched colored square beside a menu option
  // courtesy of Warren Stevens
  BOOL ModifyODMenu(LPCTSTR lpstrText,UINT nID,COLORREF fill,COLORREF border,int hatchstyle=-1);

  // for deleting and removing menu options
  BOOL  DeleteMenu(UINT uiId,UINT nFlags);
  BOOL  RemoveMenu(UINT uiId,UINT nFlags);
  int RemoveMenu(LPCTSTR pText, ESeperator sPos=CNewMenu::NONE);

  // function for retrieving and setting a menu options text (use this function
  // because it is ownerdrawn)
  BOOL GetMenuText(UINT id,CString &string,UINT nFlags = MF_BYPOSITION);
  BOOL SetMenuText(UINT id,CString string, UINT nFlags = MF_BYPOSITION);

  // Getting a submenu from it's name or position
  CMenu* GetSubMenu (LPCTSTR lpszSubMenuName) const;
  CMenu* GetSubMenu (int nPos) const;
  int GetMenuPosition(LPCTSTR pText);

  // Destoying
  virtual BOOL DestroyMenu();

  // Drawing: 
  // Draw an item
  virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
  // Measure an item  
  virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS);
  // Draw title of the menu
  virtual void DrawTitle(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar);
  // Erase the Background of the menu
  virtual BOOL EraseBkgnd(HWND hWnd, HDC hDC);

  static COLORREF GetMenuBarColor2003();
  static void GetMenuBarColor2003(COLORREF& color1, COLORREF& color2, BOOL bBackgroundColor = TRUE);
  static COLORREF GetMenuBarColorXP();
  static COLORREF GetMenuBarColor(HMENU hMenu=NULL);
  static COLORREF GetMenuColor(HMENU hMenu=NULL);

  static void SetMenuTitleFont(CFont* pFont);
  static void SetMenuTitleFont(LOGFONT* pLogFont);
  static LOGFONT GetMenuTitleFont();

  // Menutitle function
  BOOL SetMenuTitle(LPCTSTR pTitle, UINT nTitleFlags=MFT_TOP_TITLE, int nIconNormal = -1);
  BOOL SetMenuTitle(LPCTSTR pTitle, UINT nTitleFlags, CBitmap* pBmp);
  BOOL SetMenuTitle(LPCTSTR pTitle, UINT nTitleFlags, CImageList *pil, int xoffset);
  BOOL SetMenuTitle(LPCTSTR pTitle, UINT nTitleFlags, CNewMenuIcons* pIcons, int nIndex);

  BOOL SetMenuTitleColor(COLORREF clrTitle=CLR_DEFAULT, COLORREF clrLeft=CLR_DEFAULT, COLORREF clrRight=CLR_DEFAULT);

  BOOL RemoveMenuTitle();

  // Function to set how menu is drawn, either original or XP style
  static UINT GetMenuDrawMode();
  static UINT SetMenuDrawMode(UINT mode);

  static CMenuTheme* GetActualMenuTheme(){ return m_pActMenuDrawing;}

  // Function to set how disabled items are drawn 
  //(mode=FALSE means they are not drawn selected)
  static BOOL SetSelectDisableMode(BOOL mode);
  static BOOL GetSelectDisableMode();

  // Function to set how icons were drawn in normal mode 
  //(enable=TRUE means they are drawn blended)
  static BOOL SetXpBlending(BOOL bEnable=TRUE);
  static BOOL GetXpBlending();

  // Jan-12-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
  // added SetGloomFactor() and GetGloomFactor() so that the glooming can be done in a more or less subtle way
  static int SetGloomFactor(int nGloomFactor);
  static int GetGloomFactor();

  // Function to set how default menu border were drawn
  //(enable=TRUE means that all menu in the application has the same border)
  static BOOL SetNewMenuBorderAllMenu(BOOL bEnable=TRUE);
  static BOOL GetNewMenuBorderAllMenu();

  static void OnSysColorChange();

  // Static functions used for handling menu's in the mainframe
  static LRESULT FindKeyboardShortcut(UINT nChar,UINT nFlags,CMenu *pMenu);
  static BOOL OnMeasureItem(const MSG* pMsg);
  static void OnInitMenuPopup(HWND hWnd, CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);

  // Helperfunction to find the menu to the item
  static CMenu* FindPopupMenuFromID(CMenu* pMenu, UINT nID);
  static CMenu* FindPopupMenuFromID(HMENU hMenu, UINT nID);

  static CMenu* FindPopupMenuFromIDData(CMenu* pMenu, UINT nID, ULONG_PTR pData);
  static CMenu* FindPopupMenuFromIDData(HMENU hMenu, UINT nID, ULONG_PTR pData);

  virtual void OnInitMenuPopup();
  virtual BOOL OnUnInitPopupMenu();

  // Customizing:
  // Set icon size
  void SetIconSize(int width, int height);
  CSize GetIconSize();

  // set the color in the bitmaps that is the background transparent color
  COLORREF SetBitmapBackground(COLORREF newColor);
  COLORREF GetBitmapBackground(); 

  // Return the last itemrect from a menubaritem.
  CRect GetLastActiveMenuRect();
  void SetLastMenuRect(HDC hDC, LPRECT pRect);
  void SetLastMenuRect(LPRECT pRect);

  HMENU GetParent();
  BOOL IsPopup();
  BOOL SetPopup(BOOL bIsPopup=TRUE);

  BOOL SetItemData(UINT uiId, DWORD_PTR dwItemData, BOOL fByPos = FALSE);
  BOOL SetItemDataPtr(UINT uiId, void* pItemData, BOOL fByPos = FALSE);

  DWORD_PTR GetItemData(UINT uiId, BOOL fByPos = FALSE) const;
  void* GetItemDataPtr(UINT uiId, BOOL fByPos = FALSE) const;

  BOOL SetMenuData(DWORD_PTR dwMenuData);
  BOOL SetMenuDataPtr(void* pMenuData);

  DWORD_PTR GetMenuData() const;
  void* GetMenuDataPtr() const;

  // enable or disable the global accelerator drawing
  static BOOL SetAcceleratorsDraw (BOOL bDraw);
  static BOOL GetAcceleratorsDraw ();

  // Set Alphablending of the menu only win2000 /XP/2003
  // When bAlpha is 255, the window is opaque
  static BYTE SetAlpha(BYTE bAlpha);
  static BYTE GetAlpha();

  // INVALID_HANDLE_VALUE = Draw default frame's accel. NULL = Off
  HACCEL SetAccelerator (HACCEL hAccel);
  HACCEL GetAccelerator ();

  // can set icons from a global saved icons-list
  DWORD SetMenuIcons(CNewMenuIcons* pMenuIcons);

  // Miscellaneous Protected Member functions
protected:
  CNewMenuIcons* GetMenuIcon(int &nIndex, UINT nID, CImageList *pil, int xoffset);
  CNewMenuIcons* GetMenuIcon(int &nIndex, int nID);
  CNewMenuIcons* GetMenuIcon(int &nIndex, CBitmap* pBmp);

  CNewMenuIcons* GetToolbarIcons(UINT nToolBar, HMODULE hInst=NULL);

  BOOL Replace(UINT nID, UINT nNewID);

  static BOOL IsNewShell();
  BOOL IsMenuBar(HMENU hMenu=NULL);

  CNewMenuItemData* FindMenuItem(UINT nID);
  CNewMenu* FindMenuOption(int nId, int& nLoc);
  CNewMenu* FindMenuOption(LPCTSTR lpstrText, int& nLoc);

  CNewMenu* FindAnotherMenuOption(int nId, int& nLoc, CArray<CNewMenu*,CNewMenu*>&newSubs, CArray<int,int&>&newLocs);

  CNewMenuItemData* NewODMenu(UINT pos, UINT nFlags, UINT nID, LPCTSTR string);
  CNewMenuItemDataTitle* GetMemuItemDataTitle();

  void SynchronizeMenu();
  void InitializeMenuList(int value);
  void DeleteMenuList();

  CNewMenuItemData* FindMenuList(UINT nID);
  CNewMenuItemData* CheckMenuItemData(ULONG_PTR nItemData) const;

  void DrawSpecial_OldStyle(CDC* pDC, LPCRECT pRect, UINT nID, DWORD dwStyle);
  void DrawSpecial_WinXP(CDC* pDC, LPCRECT pRect, UINT nID, DWORD dwStyle);

  void DrawSpecialCharStyle(CDC* pDC, LPCRECT pRect, TCHAR Sign, DWORD dwStyle);
  void DrawSpecialChar(CDC* pDC, LPCRECT pRect, TCHAR Sign, BOOL bBold);

  void DrawMenuTitle(LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar);

  // Measure an item
  void MeasureItem_OldStyle( LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenuBar); 
  void DrawItem_OldStyle (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenubar);

  void MeasureItem_Icy( LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenuBar); 
  void DrawItem_Icy (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenubar);
  BOOL Draw3DCheckmark(CDC* dc, CRect rc, HBITMAP hbmpChecked, HBITMAP hbmpUnchecked, DWORD dwState);

  void MeasureItem_WinXP( LPMEASUREITEMSTRUCT lpMIS, BOOL bIsMenuBar); 
  void DrawItem_WinXP (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar);

  void DrawItem_XP_2003 (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenuBar);

  void DrawItem_SpecialStyle (LPDRAWITEMSTRUCT lpDIS, BOOL bIsMenubar);

  //  BOOL ImageListDuplicate(CImageList* il,int xoffset,CImageList* newlist);
  void ColorBitmap(CDC* pDC, CBitmap& bmp, CSize size, COLORREF fill, COLORREF border, int hatchstyle=-1);


  // Member Variables
public:
  static DWORD m_dwLastActiveItem;

protected: 
  // Stores list of menu items
  CTypedPtrArray<CPtrArray, CNewMenuItemData*> m_MenuItemList;   
  // When loading an owner-drawn menu using a Resource, CNewMenu must keep track of
  // the popup menu's that it creates. Warning, this list *MUST* be destroyed
  // last item first :)
  // Stores list of sub-menus
  CTypedPtrArray<CPtrArray, HMENU>  m_SubMenus;

  static BOOL m_bEnableXpBlending;
  static BOOL m_bNewMenuBorderAllMenu;
  static BOOL m_bSelectDisable;
  // Jan-12-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/
  // added gloom factor
  static int m_nGloomFactor;
  static CMenuTheme* m_pActMenuDrawing;
  static LOGFONT m_MenuTitleFont;
  static CTypedPtrList<CPtrList, CNewMenuIcons*>* m_pSharedMenuIcons;
  static BOOL m_bDrawAccelerators;
  static BYTE m_bAlpha;

  int m_iconX;
  int m_iconY;

  HWND m_hTempOwner;

  COLORREF m_bitmapBackground;

  CImageList* m_checkmaps;
  BOOL m_checkmapsshare;

  int m_selectcheck;
  int m_unselectcheck;

  BOOL m_bDynIcons;

  HMENU m_hParentMenu;

  BOOL m_bIsPopupMenu;

  CRect m_LastActiveMenuRect;

  DWORD m_dwOpenMenu;

  void* m_pData;

  HACCEL  m_hAccelToDraw;
};

/
// CNewMenuThreadHook class for hooking in a new thread
// Jan-17-2005 - Mark P. Peterson - mpp@rhinosoft.com - http://www.RhinoSoft.com/

class GUILIBDLLEXPORT CNewMenuThreadHook
{
// Initialization
public:
  CNewMenuThreadHook();
  virtual ~CNewMenuThreadHook();

// Attributes
private:
  HHOOK m_hHookOldMenuCbtFilter;
};

/
// CNewFrame<> template for easy using of the new menu

template<class baseClass>
class GUILIBDLLEXPORT CNewFrame : public baseClass
{
  typedef CNewFrame<baseClass> MyNewFrame;
public:
  CNewMenu m_DefaultNewMenu;
  CNewMenu m_SystemNewMenu;

public:

  CNewFrame()
  {
    m_bInMenuLoop = FALSE;
    m_TimerID = NULL;
    m_menubarItemIndex = UINT(-1);
  }

  // control bar docking
  void EnableDocking(DWORD dwDockStyle)
  {
    baseClass::EnableDocking(dwDockStyle);
    // Owerite registering for floating frame
    m_pFloatingFrameClass = RUNTIME_CLASS(CNewMiniDockFrameWnd);
  }

private:
  static const AFX_MSGMAP_ENTRY _messageEntries[];

protected: 
  static const AFX_MSGMAP messageMap;

  BOOL m_bInMenuLoop;
  UINT m_TimerID;
  UINT m_menubarItemIndex;


#if _MFC_VER < 0x0700 
  static const AFX_MSGMAP* PASCAL _GetBaseMessageMap()
  { 
    return &baseClass::messageMap; 
  };
#else
  static const AFX_MSGMAP* PASCAL GetThisMessageMap()
  {
    return &CNewFrame<baseClass>::messageMap; 
  }
#endif

  virtual const AFX_MSGMAP* GetMessageMap() const 
  {
    return &CNewFrame<baseClass>::messageMap; 
  }
	//{{AFX_MSG(CNewFrame)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG

  static const AFX_MSGMAP_ENTRY* GetMessageEntries()
  {
#if _MFC_VER >= 0x0800  
    typedef MyNewFrame ThisClass;
#endif
    static const AFX_MSGMAP_ENTRY Entries[] =
    {
        ON_WM_MEASUREITEM()
        ON_WM_MENUCHAR()
        ON_WM_INITMENUPOPUP()
        ON_WM_ENTERMENULOOP()
        ON_WM_EXITMENULOOP() 
        ON_WM_TIMER()
        ON_WM_CREATE()
        ON_WM_NCHITTEST()
        ON_WM_DESTROY()
        ON_WM_SYSCOLORCHANGE()
#ifdef USE_NEW_DOCK_BAR
        ON_WM_NCPAINT()
        ON_WM_PAINT()
        ON_WM_ACTIVATEAPP()
        ON_WM_ACTIVATE()
#endif //USE_NEW_DOCK_BAR
      {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
    }; 
    return Entries;
  }

  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct)
  {
    if (baseClass::OnCreate(lpCreateStruct) == -1)
      return -1;

    if(m_SystemNewMenu.m_hMenu)
    {
      ::DestroyMenu(m_SystemNewMenu.Detach());
    }
    m_SystemNewMenu.Attach(::GetSystemMenu(m_hWnd,FALSE));
    return 0;
  }

  afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
  {
    baseClass::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
    CNewMenu::OnInitMenuPopup(m_hWnd,pPopupMenu, nIndex, bSysMenu);
  }

  afx_msg void OnSysColorChange() 
  {
    baseClass::OnSysColorChange();
    CNewMenu::OnSysColorChange();
    UpdateMenuBarColor(m_DefaultNewMenu);
  }

  afx_msg void OnEnterMenuLoop(BOOL bIsTrackPopupMenu)
  {
    m_bInMenuLoop = TRUE;
    if(m_TimerID!=NULL)
    {
      KillTimer(m_TimerID);
      m_TimerID = NULL;
    }
    if (m_menubarItemIndex!=UINT(-1))
    {
      DrawMenubarItem(this,GetMenu(),m_menubarItemIndex,NULL);
      m_menubarItemIndex=UINT(-1);
    }
    baseClass::OnEnterMenuLoop(bIsTrackPopupMenu);
  }

  afx_msg void OnExitMenuLoop(BOOL bIsTrackPopupMenu)
  {
    m_bInMenuLoop = FALSE;
    baseClass::OnExitMenuLoop(bIsTrackPopupMenu);
  }

  afx_msg void OnTimer(UINT_PTR nIDEvent)
  {
    baseClass::OnTimer(nIDEvent);
    if(m_TimerID==nIDEvent)
    {   
      CPoint pt;
      GetCursorPos(&pt);
      SendMessage(WM_NCHITTEST, 0, MAKELPARAM(pt.x, pt.y));
    }
  }

  afx_msg void OnDestroy()
  {
    if(m_TimerID!=NULL)
    {
      KillTimer(m_TimerID);
      m_TimerID = NULL;
    }
    baseClass::OnDestroy();
  }

 #if _MFC_VER < 0x0800  
  afx_msg UINT OnNcHitTest(CPoint point)
  {
    UINT nHitCode = baseClass::OnNcHitTest(point);
#else
  afx_msg LRESULT OnNcHitTest(CPoint point)
  {
    UINT nHitCode = (UINT)baseClass::OnNcHitTest(point);
#endif
    // Test Win95/98/me and Win NT 4.0
    if(g_Shell<Win2000 || bRemoteSession)
    {
      UINT nStatus;
      UINT nHotlightStatus;

      if( IsChild(GetFocus()) )
      { 
        nStatus = 0; 
        nHotlightStatus = ODS_HOTLIGHT;
      }
      else if(g_Shell==Win95 || g_Shell==WinNT4)
      { // Win95 or winNt 4.0 do not have an inactive menubar
        nStatus = 0; 
        nHotlightStatus = 0;
      }
      else
      { 
        nStatus = ODS_INACTIVE;
        nHotlightStatus = ODS_HOTLIGHT|ODS_INACTIVE;
      }

      CNewMenu* pNewMenu = DYNAMIC_DOWNCAST(CNewMenu,GetMenu());
      if (!m_bInMenuLoop && nHitCode == HTMENU)
      {
        // I support only CNewMenu ownerdrawings menu!!
        if(pNewMenu)
        {
          UINT nItemIndex = MenuItemFromPoint(m_hWnd, pNewMenu->m_hMenu, point);

          if ( nItemIndex!=(UINT)-1 )
          {
            if(m_menubarItemIndex!=nItemIndex)
            { 
              // Clear the old Item
              DrawMenubarItem(this,pNewMenu,m_menubarItemIndex,nStatus);

              // Draw the hotlight item.
              if(DrawMenubarItem(this,pNewMenu,nItemIndex,nHotlightStatus))
              {
                // Set a new Timer
                if(m_TimerID==NULL)
                {
                  m_TimerID=GetSafeTimerID(m_hWnd,100);
                }
                m_menubarItemIndex = nItemIndex;
              }
              else
              {
                m_menubarItemIndex = UINT(-1);
              }
            }
            else
            {
              // Draw the hotlight item again.
              if(CNewMenu::m_dwLastActiveItem==NULL && 
                DrawMenubarItem(this,pNewMenu,nItemIndex,nHotlightStatus))
              {
                // Set a new Timer
                if(m_TimerID==NULL)
                {
                  m_TimerID=GetSafeTimerID(m_hWnd,100);
                }
                m_menubarItemIndex = nItemIndex;
              }
            }
            return nHitCode;
          }
        }
      }

      if (m_menubarItemIndex!=UINT(-1))
      {
        DrawMenubarItem(this,pNewMenu,m_menubarItemIndex,nStatus);
        m_menubarItemIndex=UINT(-1);
      }
      if(m_TimerID!=NULL)
      {
        KillTimer(m_TimerID);
        m_TimerID=NULL;
      }
    }
    return nHitCode;
  }

  afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMIS) 
  {
    if(!CNewMenu::OnMeasureItem(GetCurrentMessage()))
    {
      CMenu* pMenu;
      _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
      if (pThreadState && pThreadState->m_hTrackingWindow == m_hWnd)
      {
        // start from popup
        pMenu = CMenu::FromHandle(pThreadState->m_hTrackingMenu);
      }
      else
      {
        // start from menubar
        pMenu = GetMenu();
      }
      if(pMenu)
      {
        baseClass::OnMeasureItem(nIDCtl, lpMIS);
      }
    } 
  }

  afx_msg LRESULT OnMenuChar(UINT nChar, UINT nFlags, CMenu* pMenu) 
  {
    LRESULT lresult;
    if( DYNAMIC_DOWNCAST(CNewMenu,pMenu) )
      lresult=CNewMenu::FindKeyboardShortcut(nChar, nFlags, pMenu);
    else
      lresult=baseClass::OnMenuChar(nChar, nFlags, pMenu);

    return lresult;
  }

#ifdef USE_NEW_DOCK_BAR
  afx_msg void OnNcPaint()
  {
    baseClass::OnNcPaint();
    DrawSmallBorder();
  }

  afx_msg void OnPaint()
  {
    baseClass::OnPaint();
    DrawSmallBorder();
  }

#if _MFC_VER < 0x0700 
  afx_msg void OnActivateApp(BOOL bActive, HTASK hTask)
  {
    baseClass::OnActivateApp(bActive, hTask);
    DrawSmallBorder();
  }
#else
  afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID)
  {
    baseClass::OnActivateApp(bActive, dwThreadID);
    DrawSmallBorder();
  }
#endif

  afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized )
  {
    baseClass::OnActivate(nState,pWndOther, bMinimized );
    DrawSmallBorder();
  }

  void DrawSmallBorder()
  {
    // To eliminate small border between menu and client rect
    MENUINFO menuInfo = {0};
    menuInfo.cbSize = sizeof(menuInfo);
    menuInfo.fMask = MIM_BACKGROUND;
    if(::GetMenuInfo(::GetMenu(m_hWnd),&menuInfo) && menuInfo.hbrBack)
    {
      CDC* pDC = GetWindowDC(); 
      CRect clientRect;
      GetClientRect(clientRect);
      ClientToScreen(clientRect);
      CRect windowRect;
      GetWindowRect(windowRect);
      CRect rect(clientRect.left-windowRect.left,clientRect.top-windowRect.top-1,clientRect.right-windowRect.left,clientRect.top-windowRect.top);

      CBrush *pBrush = CBrush::FromHandle(menuInfo.hbrBack);
      // need for win95/98/me
      VERIFY(pBrush->UnrealizeObject());
      CPoint oldOrg = pDC->SetBrushOrg(0,0);
      pDC->FillRect(rect,pBrush);
      pDC->SetBrushOrg(oldOrg);
      // must be called
      ReleaseDC(pDC);
    }
  }
#endif
};

/
// CNewMiniDockFrameWnd for docking toolbars with new menu

class GUILIBDLLEXPORT CNewMiniDockFrameWnd: public CNewFrame<CMiniDockFrameWnd> 
{
  DECLARE_DYNCREATE(CNewMiniDockFrameWnd) 
  DECLARE_MESSAGE_MAP()
};

/
// CNewDialog for dialog implementation

class GUILIBDLLEXPORT CNewDialog : public CNewFrame<CDialog>
{
  DECLARE_DYNAMIC(CNewDialog);

public:
  CNewDialog();
  CNewDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);
  CNewDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);

  // Overridables (special message map entries)
  virtual BOOL OnInitDialog();

protected:
  // Generated message map functions
  //{{AFX_MSG(CNewDialog)
  afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
  //}}AFX_MSG

  DECLARE_MESSAGE_MAP()
};

/
// CNewMiniFrameWnd for menu to documents

class GUILIBDLLEXPORT CNewMiniFrameWnd : public CNewFrame<CMiniFrameWnd>
{
  DECLARE_DYNCREATE(CNewMiniFrameWnd)
	//{{AFX_MSG(CNewMiniFrameWnd)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};

/
// CNewMDIChildWnd for menu to documents

class GUILIBDLLEXPORT CNewMDIChildWnd : public CNewFrame<CMDIChildWnd>
{
  DECLARE_DYNCREATE(CNewMDIChildWnd)
	//{{AFX_MSG(CNewMDIChildWnd)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};

/
// CNewFrameWnd for menu to documents

class GUILIBDLLEXPORT CNewFrameWnd : public CNewFrame<CFrameWnd>
{
  DECLARE_DYNCREATE(CNewFrameWnd)

public:
#if _MFC_VER < 0x0700 
  // dynamic creation - load frame and associated resources
  virtual BOOL LoadFrame(UINT nIDResource,
    DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
    CWnd* pParentWnd = NULL,
    CCreateContext* pContext = NULL);
#endif

  // under MFC 7.0 the next function is virtual so we don't neet to owerwrite
  // loadframe
  BOOL Create(LPCTSTR lpszClassName,
    LPCTSTR lpszWindowName,
    DWORD dwStyle = WS_OVERLAPPEDWINDOW,
    const RECT& rect = rectDefault,
    CWnd* pParentWnd = NULL,        // != NULL for popups
    LPCTSTR lpszMenuName = NULL,
    DWORD dwExStyle = 0,
    CCreateContext* pContext = NULL);

#ifdef USE_NEW_DOCK_BAR
  // control bar docking
  void EnableDocking(DWORD dwDockStyle);
#endif
	//{{AFX_MSG(CNewFrameWnd)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

/
// CNewMDIFrameWnd for menu to documents

class GUILIBDLLEXPORT CNewMDIFrameWnd : public CNewFrame<CMDIFrameWnd>
{
  DECLARE_DYNCREATE(CNewMDIFrameWnd);
  HMENU m_hShowMenu;

public: 
  CNewMDIFrameWnd():m_hShowMenu(NULL){};

  BOOL ShowMenu(BOOL bShow);

#if _MFC_VER < 0x0700 
  // dynamic creation - load frame and associated resources
  virtual BOOL LoadFrame(UINT nIDResource,
    DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
    CWnd* pParentWnd = NULL,
    CCreateContext* pContext = NULL);
#endif
  // under MFC 7.0 the next function is virtual so we don't neet to owerwrite
  // loadframe
  BOOL Create(LPCTSTR lpszClassName,
    LPCTSTR lpszWindowName,
    DWORD dwStyle = WS_OVERLAPPEDWINDOW,
    const RECT& rect = rectDefault,
    CWnd* pParentWnd = NULL,        // != NULL for popups
    LPCTSTR lpszMenuName = NULL,
    DWORD dwExStyle = 0,
    CCreateContext* pContext = NULL);

#ifdef USE_NEW_DOCK_BAR
  // control bar docking
  void EnableDocking(DWORD dwDockStyle);
#endif

	//{{AFX_MSG(CNewMDIFrameWnd)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};


/
// CNewMultiDocTemplate for menu to documents

class GUILIBDLLEXPORT CNewMultiDocTemplate: public CMultiDocTemplate
{
  DECLARE_DYNAMIC(CNewMultiDocTemplate)

public:
  CNewMenu m_NewMenuShared;

  // Constructors
public:
  CNewMultiDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
    CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);

  ~CNewMultiDocTemplate();
};


/
// CNewMemDC helperclass for drawing off screen 

class GUILIBDLLEXPORT CNewMemDC: public CDC
{
  CRect m_rect;
  CBitmap* m_pOldBitmap;
  CBitmap  m_memBitmap;
  BOOL m_bCancel;

  HDC m_hDcOriginal;

public:
  CNewMemDC(LPCRECT pRect, HDC hdc):m_rect(pRect),m_bCancel(FALSE),m_hDcOriginal(hdc)
  {
    CDC *pOrgDC = CDC::FromHandle(m_hDcOriginal);
    CreateCompatibleDC(pOrgDC);

    m_memBitmap.CreateCompatibleBitmap (pOrgDC,m_rect.Width (),m_rect.Height());
    m_pOldBitmap = SelectObject (&m_memBitmap);
    SetWindowOrg(m_rect.left, m_rect.top);
  }

  // Abborting to copy image from memory dc to client
  void DoCancel(){m_bCancel=TRUE;}

  ~CNewMemDC()
  {
    if(!m_bCancel)
    {
      CDC *pOrgDC = CDC::FromHandle(m_hDcOriginal);
      pOrgDC->BitBlt (m_rect.left,m_rect.top,m_rect.Width (),m_rect.Height (),this,m_rect.left,m_rect.top,SRCCOPY);
    }
    SelectObject (m_pOldBitmap);
  }
};

/
// CNewMenuHelper for enabling / disabling menu border, replacing system menu.

#define  NEW_MENU_DIALOG_SUBCLASS     1
#define  NEW_MENU_DIALOG_SYSTEM_MENU  2
#define  NEW_MENU_DEFAULT_BORDER      4
#define  NEW_MENU_CHANGE_MENU_STYLE   8

class GUILIBDLLEXPORT CNewMenuHelper
{
private:
  DWORD m_dwOldFlags;
  int m_OldMenuDrawStyle;

public: 
  CNewMenuHelper(DWORD dwFlags);
  CNewMenuHelper(CNewMenu::EDrawStyle setTempStyle);

  ~CNewMenuHelper();
};

/
// CNewDockBar support for office2003 colors.
class GUILIBDLLEXPORT CNewDockBar : public CDockBar
{
  DECLARE_DYNCREATE(CNewDockBar)
public:
  CNewDockBar(BOOL bFloating = FALSE);   // TRUE if attached to CMiniDockFrameWnd
  virtual ~CNewDockBar();

#if defined(_DEBUG) || defined(_AFXDLL)
  virtual void AssertValid() const;
  virtual void Dump(CDumpContext& dc) const;
#endif

public:

  virtual DWORD RecalcDelayShow(AFX_SIZEPARENTPARAMS* lpLayout);
  void EraseNonClient();

  afx_msg BOOL OnEraseBkgnd(CDC* pDC);
  afx_msg void OnNcPaint();

protected:
	//{{AFX_MSG(CNewDockBar)
		// NOTE - the ClassWizard will add and remove member functions here.
		//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG
  DECLARE_MESSAGE_MAP()
};

#ifndef _GUILIB_
  #ifdef _AFXDLL
    #if _MFC_VER < 0x0700 
      template<class baseClass>
      const AFX_MSGMAP CNewFrame<baseClass>::messageMap = { &CNewFrame<baseClass>::_GetBaseMessageMap, GetMessageEntries()};
    #else
      template<class baseClass>
      const AFX_MSGMAP CNewFrame<baseClass>::messageMap = { &baseClass::GetThisMessageMap, GetMessageEntries()};
    #endif
  #else
    #if _MFC_VER < 0x0800 
      template<class baseClass>
      const AFX_MSGMAP CNewFrame<baseClass>::messageMap = { &baseClass::messageMap, GetMessageEntries()};
    #else
      template<class baseClass>
      const AFX_MSGMAP CNewFrame<baseClass>::messageMap = { &baseClass::GetThisMessageMap, GetMessageEntries()};
    #endif
  #endif // _AFXDLL
#endif // _GUILIB_


#pragma warning(pop)

#endif // __CNewMenu_H_



然后在需要创建邮件菜单的时候调用以下代码(示例)

CNewMenu menu;
 menu.CreatePopupMenu();

menu.InsertMenu(index,MF_BYPOSITION,msgBaseNumber,expand[LanguageID],&m_setImage,19);//参数需根据自己的项目进行更改
menu.SetMenuTitle(logText[LanguageID],MFT_GRADIENT|MFT_SIDE_TITLE|MFT_LINE);    //设置菜单的名字
  menu.TrackPopupMenu(TPM_LEFTALIGN,point.x ,point.y,this);  //设置弹出菜单的位置

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Visual C++编程技巧精选500例》pdf Visual C++编程技巧精选500例.pdf 第1章 消息框 001 如何创建消息框? 002 如何设置消息框标题? 003 如何使用资源串创建消息框? 004 如何使用资源串动态显示消息框内容? 005 如何使消息框显示问号图标? 006 如何使消息框显示“是/否”按钮? 007 如何使消息框显示“重试/取消”按钮? 第2章 常用控件 008 如何使用滑块控件? 009 如何使用标签控件? 010 如何使用树形控件? 011 如何使用列表控件? 012 如何使用进度条控件? 013 如何使用滚动条控件? 014 如何设置按钮控件标签? 015 如何设置按钮控件字体? 016 如何动态创建按钮控件? 017 如何禁用和启用按钮控件? 018 如何隐藏和显示按钮控件? 019 如何在按钮控件上加载图标? 020 如何在按钮控件上加载位图? 021 如何在程序窗口创建按钮控件? 022 如何限制编辑控件输入的字符类型? 023 如何显示载有RichEdit控件的对话框? 024 如何在列表框中自动装载磁盘文件列表? 025 如何使1istContro1控件支持整栏选择? 026 如何使用PictureBox控件浏览多种格式的图像? 第3章 通用对话框 027 如何使用字体对话框? 028 如何使用颜色对话框? 029 如何使用页面设置对话框? 030 如何使用查找与替换对话框? 031 如何设置文件保存对话框? 032 如何设置文件对话框标题? 033 如何设置文件对话框过滤器? 034 如何设置文件对话框多重选择功能? 035 如何设置文件对话框打开时的目录位置? 036 如何从文件对话框中选择文件夹? 037 如何从文件对话框中新建文件夹? 038 如何在文件对话框中预览位图文件? 039 如何从文件对话框中获取文件扩展名? 040 如何从文件对话框中获取文件标题? 041 如何获取文件对话框选择的多个文件? 042 如何在程序启动时弹出文件打开对话框? 第4章 标题栏与菜单栏 043 如何获取标题栏高度? 044 如何设置标题栏文字? 045 如何获取标题栏文字颜色? 046 如何设置标题栏文字颜色? 047 如何在文档类中设置标题栏文字? 048 如何防止在标题栏上显示文档名? 049 如何禁止标题栏的最小化按钮?… 050 如何禁止标题栏的最大化按钮? 051 如何禁止标题栏的关闭按钮? 052 如何获取标题栏的按钮尺寸? 053 如何自定义标题栏? 054 如何获取IE浏览器标题内容? 055 如何取消标题栏的右键系统菜单? 056 如何在标题栏右键菜单中增加菜单项? 057 如何动态增加菜单? 058 如何动态删除菜单? 059 如何启用和禁用菜单命令? 060 如何为菜单添加复选标记? 061 如何为菜单添加单选标记? 062 如何动态删除系统菜单项? 063 如何动态增加系统菜单项? 064 如何触发一个菜单命令? 065 如何创建一个弹出菜单? 066 如何设计自定义快捷菜单? 067 如何在对话框类型的应用程序中加载菜单? 068 如何获取菜单栏高度? 069 如何取消应用程序菜单栏? 070 如何取消对菜单状态的限制? 071 如何确定顶层菜单所占的行数? 072 如何在子菜单中记录历史文件? 第5章 工具栏与状态栏 073 如何给工具栏分组? 074 如何关闭默认工具栏? 075 如何设置工具栏标题? 076 如何设置工具栏按钮提示? 077 如何关闭工具栏按钮提示? 078 如何启用和禁用工具栏按钮? 079 如何设置下压式工具栏按钮? 080 如何给工具栏按钮设置下拉箭头? 081 如何为工具栏添加动态真彩按钮? 082 如何为工具栏按钮添加文字? 083 如何为IE工具栏添加按钮? 084 如何在工具栏上加载动画? 085 如何在工具栏上加载组合框? 086 如何在工具栏上加载字体组合框? 087 如何使用代码获取工具栏的指针? 088 如何在对话框程序中加入工具栏? 089 如何控制工具栏的停靠位置? 090 如何使用对话栏? 091 如何增加状态栏窗格? 092 如何更新状态栏窗格? 093 如何关闭默认状态栏? 094 如何在状态栏上加载图像? 095 如何在状态栏上加载进度条? 096 如何在状态栏上显示滚动文本? 097 如何在状态栏上显示当前时间? 098 如何在状态栏上显示鼠标当前位置? 099 如何使用代码获取状态栏指针? 第6章 图标与光标 100 如何设置光标? 101 如何裁剪光标? 102 如何捕捉光标热区? 103 如何创建一个等待光标? 104 如何结束一个等待光标? 105 如何获取默认光标大小? 106 如何装入一个系统预定义光标? 107 如何获取系统图标? 108 如何获取默认图标大小? 109 如何获取应用程序图标? 110 如何设置应用程序图标? 111 如何在系统托盘中设置图标? 112 如何直接从文件中装入一个图标? 113 如何使应用程序标题栏图标旋转? 第7章 程序窗口 114 如何切分同视图窗口? 115 如何切分多视图窗口? 116 如何判断程序窗口是否为切分窗口? 117 如何创建非矩形窗口? 118 如何实现无标题窗口的拖动? 119 如何将应用程序窗口居中显示? 049 如何禁止标题栏的最小化按钮?… 050 如何禁止标题栏的最大化按钮? 051 如何禁止标题栏的关闭按钮? 052 如何获取标题栏的按钮尺寸? 053 如何自定义标题栏? 054 如何获取IE浏览器标题内容? 055 如何取消标题栏的右键系统菜单? 056 如何在标题栏右键菜单中增加菜单项? 057 如何动态增加菜单? 058 如何动态删除菜单? 059 如何启用和禁用菜单命令? 060 如何为菜单添加复选标记? 061 如何为菜单添加单选标记? 062 如何动态删除系统菜单项? 063 如何动态增加系统菜单项? 064 如何触发一个菜单命令? 065 如何创建一个弹出菜单? 066 如何设计自定义快捷菜单? 067 如何在对话框类型的应用程序中加载菜单? 068 如何获取菜单栏高度? 069 如何取消应用程序菜单栏? 070 如何取消对菜单状态的限制? 071 如何确定顶层菜单所占的行数? 072 如何在子菜单中记录历史文件? 第5章 工具栏与状态栏 073 如何给工具栏分组? 074 如何关闭默认工具栏? 075 如何设置工具栏标题? 076 如何设置工具栏按钮提示? 077 如何关闭工具栏按钮提示? 078 如何启用和禁用工具栏按钮? 079 如何设置下压式工具栏按钮? 080 如何给工具栏按钮设置下拉箭头? 081 如何为工具栏添加动态真彩按钮? 082 如何为工具栏按钮添加文字? 083 如何为IE工具栏添加按钮? 084 如何在工具栏上加载动画? 085 如何在工具栏上加载组合框? 086 如何在工具栏上加载字体组合框? 087 如何使用代码获取工具栏的指针? 088 如何在对话框程序中加入工具栏? 089 如何控制工具栏的停靠位置? 090 如何使用对话栏? 091 如何增加状态栏窗格? 092 如何更新状态栏窗格? 093 如何关闭默认状态栏? 094 如何在状态栏上加载图像? 095 如何在状态栏上加载进度条? 096 如何在状态栏上显示滚动文本? 097 如何在状态栏上显示当前时间? 098 如何在状态栏上显示鼠标当前位置? 099 如何使用代码获取状态栏指针? 第6章 图标与光标 100 如何设置光标? 101 如何裁剪光标? 102 如何捕捉光标热区? 103 如何创建一个等待光标? 104 如何结束一个等待光标? 105 如何获取默认光标大小? 106 如何装入一个系统预定义光标? 107 如何获取系统图标? 108 如何获取默认图标大小? 109 如何获取应用程序图标? 110 如何设置应用程序图标? 111 如何在系统托盘中设置图标? 112 如何直接从文件中装入一个图标? 113 如何使应用程序标题栏图标旋转? 第7章 程序窗口 114 如何切分同视图窗口? 115 如何切分多视图窗口? 116 如何判断程序窗口是否为切分窗口? 117 如何创建非矩形窗口? 118 如何实现无标题窗口的拖动? 119 如何将应用程序窗口居中显示? 176 如何终止当前进程? 177 如何获取系统进程? 178 如何终止指定进程? 179 如何在程序中启动程序? 180 如何使用事件对象同步进程? 181 如何在两个执行程序间进行数据通信? 182 如何使用工作线程? 183 如何正常终止线程? 184 如何异常终止线程? 185 如何获取线程退出码? 186 如何使用线程优先级? 187 如何使用用户界面线程? 188 如何实现多线程多任务? 189 如何使用临界区同步线程? 190 如何调用帮助文件(.chm)? 第10章 字符串 191 如何对字符串进行连接? 192 如何对字符串进行比较? 193 如何从字符串中存取字符? 194 如何计算一个字符串的大小? 195 如何快速格式化一个字符串? 196 如何将CString类型转换成int类型? l97 如何将CString类型转换成loat类型? 198 如何将CString中的字符串赋值给字符指针? 199 如何折行显示字符串? 200 如何旋转显示字符串? 20l 如何显示星期月份字符串? 202 如何显示包括制表符的字符串? 203 如何使用BIG5显示一个字符串? 204 如何使字符串输出具有立体效果? 205 如何用省略号显示字符串的其余部分? 第11章 文件读写操作 206 如何打开文件? 207 如何关闭文件? 208 如何读文件? 209 如何写文件? 210 如何定位文件? 2ll 如何判断文件大小? 212 如何获取文件错误类型? 213 如何检测文件是否已经发生更改? 214 如何判断文件在磁盘上是否存在? 215 如何读写INI文件? 216 如何创建一个临时文件? 217 如何创建一个特大型文件? 218 如何创建一个文本文件? 219 如何删除一个文本文件? 220 如何更名一个文本文件? 221 如何对文本文件进行查找与替换? 222 如何从文本文件中读取一个字符串? 第12章 文件与文件夹属-操作 223 如何判断文件只读属性? 224 如何设置文件只读属性? 225 如何判断文件隐藏属性? 226 如何设置文件隐藏属性? 227 如何判断文件归档属性? 228 如何设置文件归档属性? 229 如何取消文件所有属性? 230 如何获取文件大小? 231 如何获取文件类型? 232 如何获取系统所有文件类型? 233 如何获取文件创建时间? 234 如何获取文件修改时间? 235 如何获取文件访问时间? 236 如何设置文件创建时间? 237 如何设置文件修改时间? 238 如何设置文件访问时间? 239 如何获取文件夹创建时间? 240 如何获取文件夹修改时间? 241 如何获取文件夹访问时间? 242 如何设置文件夹创建时间? 243 如何设置文件夹修改时间? 244 如何设置文件夹访问时间? 245 如何判断文件夹真假? 第13章 文件与文件夹系统操作 246 如何复制文件? 247 如何删除文件? 248 如何移动文件? 249 如何更名文件? 250 如何显示文件复制过程对话框? 251 如何复制文件夹? 252 如何创建文件夹? 253 如何删除文件夹? 254 如何更名文件夹? 255 如何创建多层文件夹? 256 如何删除多层文件夹? 第14章 系统控制操作 257 如何隐藏操作系统任务栏? 258 如何取消隐藏操作系统任务栏? 259 如何检索系统任务栏各窗口标题? 260 如何关闭计算机? 261 如何注销当前用户? 262 如何重新启动计算机? 263 如何关闭计算机并关闭电源? 264 如何设置系统启动自运行程序? 265 如何在程序中将其他窗口程序调至前台? 266 如何获取当前系统时间? 267 如何设置当前系统时间? 268 如何计算时间差? 269 如何获取系统显示元素的颜色? 270 如何获取系统当前的显示模式? 271 如何获取系统支持的显示模式? 272 如何设置系统当前的显示模式? 273 如何设置桌面墙纸? 274 如何删除桌面快捷方式? 275 如何清空回收站? 276 如何清空IE历史记录? 277 如何清除IE地址栏历史记录? 278 如何添加IE浏览器收藏夹内容? 279 如何使用默认浏览器打开指定网页? 280 如何清除上次登录用户历史记录? 281 如何强制操作系统只执行规定的程序? 282 如何在系统“控制面板/添加删除程序”中添加程序? 283 如何注册COM服务组件? 284 如何取消COM服务组件注册? 285 如何隐式链接DLL? 286 如何显式链接DLL? 287 如何使用AFX EXT CLASS导出类? 288 如何使用declspec(dllexport)导出DLL函数? 第15章 程序版权信息 289 如何查询程序说明? 290 如何查询程序开发商? 291 如何查询程序内部名称? 292 如何查询程序产品名称? 293 如何查询程序关联注释? 294 如何查询程序注册商标? 295 如何查询程序版权声明? 296 如何查询程序使用语言? 297 如何查询程序原始文件名? 298 如何查询程序私有版本信息? 299 如何查询程序特殊内部版本信息? 300 如何查询程序版本号? 301 如何查询程序产品版本号? 302 如何查询程序内部版本号? 303 如何查询程序产品专用部件号? 304 如何查询程序版本号的主版本号? 305 如何查询程序版本号的次版本号? 306 如何查询程序产品的内部版本号? 307 如何查询程序产品版本号的主版本号? 308 如何查询程序产品版本号的次版本号? 第16章 系统软件信息 309 如何获取用户名称? 310 如何获取计算机名称? 311 如何设置计算机名称? 312 如何获取计算机所有者名称? 313 如何获取计算机所有者单位名称? 314 如何获取操作系统安装序列号? 315 如何获取操作系统的产品名称? 316 如何获取IE浏览器的版本号? 317 如何获取Windows的版本号? 318 如何获取Windows的内建号? 319 如何获取Windows的版本名称? 320 如何获取当前文件夹的位置? 321 如何获取文件夹的根目录位置? 322 如何获取文件夹的上层目录位置? 323 如何获取文件夹中的所有文件? 324 如何获取文件夹中的所有子文件夹? 325 如何获取启动文件夹位置? 326 如何获取临时文件夹位置? 327 如何获取桌面文件夹位置? 328 如何获取字体文件夹位置? 329 如何获取网上邻居文件夹位置? 330 如何获取我的文档文件夹位置? 331 如何获取System文件夹位置? 332 如何获取Windows文件夹位置? 第17章 系统硬件信息 333 如何获取CPU名称? 334 如何获取CPU标识? 335 如何获取CPU制造商名称? 336 如何获取CPU主频? 337 如何获取CPU个数? 338 如何判断CPU是否支持3DNow? 339 如何判断CPU是否支持MMX? 340 如何判断是否提供安全特性? 341 如何判断低档处理器? 342 如何获取显卡BIOS版本号? 343 如何获取显卡BIOS更新日期? 344 如何获取系统BIOS版本号? 345 如何获取系统BIOS更新日期? 第18章 存储设备管理 346 如何获取磁盘序列号? 347 如何获取磁盘卷标名称? 348 如何设置磁盘卷标名称? 349 如何获取磁盘容量大小? 350 如何获取磁盘文件系统名称? 351 如何获取系统所有磁盘驱动器? 352 如何设置磁盘图标? 353 如何隐藏磁盘驱动器? 354 如何判断磁盘驱动器类型? 355 如何启用光驱的自动播放功能? 356 如何指定使用什么程序播放CD? 357 如何在程序中打开/关闭光驱? 358 如何获取系统内存的使用情况? 359 如何映射网络驱动器? 360 如何取消网络驱动器映射? 第19章 鼠标及键盘 361 如何禁止交换鼠标左右键? 362 如何判断鼠标左右键是否交换? 363 如何判断系统是否安装鼠标? 364 如何判断鼠标是否有滚轮? 365 如何禁止使用鼠标滚轮? 366 如何获取鼠标按键个数? 367 如何模仿鼠标操作? 368 如何跟踪鼠标当前位置? 369 如何获取鼠标活动范围? 370 如何获取鼠标双击范围大小? 371 如何获取鼠标双击响应速度? 372 如何设置鼠标双击响应速度? 373 如何判断鼠标单击标题栏操作? 374 如何判断鼠标是否与Ctrl键共同操作? 375 如何捕获键盘Home等虚键?. 376 如何设置键盘输入响应速度? 377 如何使用回车键切换输入焦点? 378 如何为应用程序自定义快捷键? 379 如何捕获AR和Shift+Alt组合键? 380 如何捕获Ctrl和Ctrl+Shift组合键? 381 如何捕获Ctrl、Ctrl+Alt和Ctrl+Alt+Shifl组合键? 第20章 声音和视频 382 如何调节系统音量? 383 如何设置背景音乐? 384 如何播放AVI动画文件? 385 如何播放VCD视频文件? 386 如何播放WAV简单声音文件? 387 如何播放系统默认声音文件? 388 如何使用MCI播放WAV声音文件? 389 如何使用MCI播放MIDI声音文件? 第21章 图形和图像 390 如何通过读取位图资源显示位图? 391 如何通过读取位图文件显示位图? 392 如何通过装入位图文件显示位图? 393 如何缩放显示位图? 394 如何截取当前屏幕? 395 如何任意裁剪图片? 396 如何利用掩码位图制作透明图片? 397 如何实现图形的拉伸显示效果? 398 如何通过位图文件直接得到位图大小? 399 如何获取屏幕上某点的颜色? 400 如何设置屏幕上某点的颜色? 401 如何读取与显示JPG等格式图像文件? 402 如何转换图像文件大小? 403 如何转换图像文件格式? 404 如何将彩色图像转换成黑白图像? 405 如何实现图像的底片化效果? 406 如何实现图像的雾化效果? 407 如何实现图像的锐化效果? 408 如何实现图像的柔化效果? 409 如何实现图像的马赛克效果? 410 如何实现图像的百叶窗效果? 411 如何复制图像? 412 如何剪切图像? 413 如何粘贴图像? 414 如何实现画线拉伸效果? 415 如何绘制渐变色图形? 416 如何绘制渐变色文字? 第22章 网络 417 如何初始化Socket? 418 如何创建Socket? 419 如何处理网络监听Socket? 420 如何处理C/S互连? 421 如何处理C/S数据发送? 422 如何处理C/S数据接收? 423 如何实现无连接的通信? 424 如何实现有连接的通信? 425 如何用有连接方式实现网络会议? 426 如何获取网卡地址? 427 如何扫描端口状态? 428 如何进行连续的Ping? 429 如何获取主机名和IP地址? 430 如何搜索局域网内的计算机? 431 如何创建拨号网络? 432 如何检查电子邮件数量? 433 如何发送和接收电子邮件? 434 如何连接FTP服务器? 435 如何获取FTP服务器的文件列表? 436 如何向FTP服务器上传文件? 437 如何从FTP服务器下载文件? 438 如何查询HTTP站点? 439 如何查询FTP站点? 440 如何查询Gopher站点? 第23章 数据库 441 如何使用ODBC连接数据源? 442 如何使用ODBC实现应用程序与数据库记录的交换? 443 如何使用ODBC浏览数据库记录? 444 如何使用ODBC增加数据库记录? 445 如何使用ODBC删除数据库记录? 446 如何使用ODBC修改数据库记录? 447 如何使用ODBC排序数据库记录? 448 如何使用ODBC查询数据库记录? 449 如何使用SQL语句查询排序数据厍记录? 450 如何使用ODBC创建EXCEL文件? 451 如何使用ODBC读取EXCEL文件信息? 452 如何获取系统已经安装的ODBC驱动程序? 453 如何安装Visual C++.NET中的MS Server服务管理器桌面引擎? 454 如何在Visual C++.NET中创建 MS SQL Server数据库? 455 如何使用.NET类库访问数据库? 456 如何使用DAO新建数据库? 457 如何使用DAO打开数据库? 458 如何使用DAO关闭数据库? 459 如何使用DAO新建数据库表? 460 如何使用DAO打开数据库表? 461 如何使用DAO删除数据库表? 462 如何使用DAO浏览数据库表字段? 463 如何使用DAO增加数据库表字段? 464 如何使用DAO删除数据库表字段? 465 如何使用DAO新建数据库表查询? 466 如何使用DAO浏览数据库表查询? 467 如何使用DAO删除数据库表查询? 468 如何使用DAO自定义记录集类? 469 如何使用DAO浏览数据库记录? 470 如何使用DAO增加数据库记录? 471 如何使用DAO删除数据库记录? 472 如何使用DAO修改数据库记录? 473 如何使用DAO查询数据库记录? 474 如何使用DAO排序数据库记录? 475 如何使用DAO处理数据库异常? 476 如何判断数据集是否允许更新? 477 如何实现ADO对象与数据源的连接? 478 如何导入ADO动态链接库? 479 如何使用ADO对象浏览数据库记录? 480 如何使用ADO对象增加数据库记录? 481 如何使用ADO对象删除数据库记录? 482 如何使用ADO对象修改数据库记录? 483 如何使用ADO对象排序数据库记录? 484 如何使用ADO对象查询数据库记录? 485 如何使用ADO处理数据库异常? 486 如何存取数据库图像字段? 487 如何创建数据库操作事务? 488 如何在程序中注册数据源? 489 如何创建ODBC数据源? 490 如何使用SQL模糊查询语句? 491 如何使用SQL语句检索时间段? 第24章 开发工具 492 如何设置条件断点? 493 如何设置堆栈大小? 494 如何产生全局惟一标识符? 495 如何删除项目文件中的类? 496 如何打开和编辑二进制文件? 497 如何检测代码括号是否匹配? 498 如何查看一个宏的原始定义? 499 如何添加.1ib文件到当前项目? 500 如何调整对话框模板上的控件的Tab键顺序?
前言 第1章 消息框和对话框 1.如何在窗口程序中创建消息框 2.如何使用资源字符串设置消息框内容 3.如何在消息框中动态显示资源字符串 4.如何设置消息提示框的标题文字 5.如何使消息提示框的标题右对齐 6.如何在消息提示框中绘制表格 7.如何在消息提示框中设置图标 8.如何在消息提示框中显示问号图标 9.如何在消息提示框中设置按钮 10.如何在消息提示框中显示“是”、“否”按钮 11.如何在消息提示框中显示“重试”、“取消”按钮 12.如何设置消息提示框的默认选择按钮 13.如何确定用户在消息框中选择的按钮 14.如何设置“文件”对话框的标题文字 15.如何设置“文件”对话框的过滤器 16.如何设置“文件”对话框的初始目录 17.如何设置“文件”对话框的初始文件名 18.如何使“文件”对话框自动添加扩展名 19.如何实现“文件”对话框的多重选择功能 20.如何在“文件”对话框中选择多个文件 21.如何从“文件”对话框中获取文件标题名 22.如何从“文件”对话框中获取文件扩展名 23.如何在“文件”对话框中预览位图文件 24.如何创建一个文件“保存”对话框 25.如何在程序启动时弹出“文件”对话框 26.如何从“文件夹”对话框中选择文件夹 27.如何在“文件夹”对话框中新建文件夹 28.如何使用“颜色”对话框设置颜色 29.如何在“颜色”对话框中显示帮助按钮 30.如何禁止显示“颜色”对话框的自定义颜色 31.如何禁止“颜色”对话框的自定义颜色按钮 32.如何使用“字体”对话框设置字体和颜色 33.如何使用“查找与替换”对话框 34.如何显示操作系统默认的“关于”对话框 第2章 常用控件和组件 35.如何设置按钮控件的标签文本 36.如何设置按钮控件的显示字体 37.如何动态禁用和启用按钮控件 38.如何动态隐藏和显示按钮控件 39.如何在按钮控件上动态加载图标 40.如何在按钮控件上动态加载位图 4 1.如f可制作图标和文本共存的按钮 42.如何制作不规则的多边形按钮 43.如何制作GIF动画效果的按钮 44.如何制作AVI视频效果的按钮 45.如何在程序中动态创建按钮控件 46.如何在视图窗口创建按钮控件 47.如何获取鼠标指向的按钮控件标题 48.如何创建文本和颜色共存的ComboBox 49.如何创建自动完成列表项的ComboBox 50.如何使ComboBox控件自动适应列表项 5l.如何使ComboBox控件自动装入文件名列表 52.如何在编辑框中限制输入的字符类型 53.如何为编辑框添加自动完成匹配功能 54.如何设置编辑框的背景颜色和文本颜色 55.如何使编辑框的宽度自动适应窗体大小 56.如何获取在编辑框中选择的文本内容 57.如何获取在编辑框中显示的文本行数 58.如何重置编辑框默认的右键菜单 59.如何显示载有RichEdit控件的对话框 60.如何在RichEdit中实现查找和定位字符 61.如何在RichEdit中混合显示图片和文本 62.如何使List列表控件支持整行选择 63.如何使用List列表控件填充表格数据 64.如何使用数据库记录填充List列表控件 65.如何创建单元格可编辑的List列表控件 66.如何在ListBox中查找指定的字符串 67.如何为超长的ListBox列表项添加提示 68.如何将ListBox转换成CheckListBox 69.如何在视图窗口中绘制ListBox控件 70.如何使用Progress控件显示完成进度 71.如何使用Scroll控件控制滚动范围值 72.如何使用Slider控件控制滑动刻度值 73.如何使用Tab标签页(选项卡)控件 74.如何使用Tree控件显示目录树形结构 75.如何为树控件的子节点添加复选功能 76.如何为控件添加浮动提示窗口功能 77.如何使用回车键切换窗体控件焦点 78.如何遍历应用程序窗体中的各个控件 79.如何使窗体中的控件跟随鼠标移动而移动 80.如何设置静态文本控件的背景和文本颜色 81.如何通过控件实现鼠标拖动文本效果 第3章 标题栏和菜单栏 82.如何获取程序窗口标题栏的高度 83.如何获取程序窗口标题栏的按钮尺寸 84.如何获取程序窗口标题栏的文字 85.如何获取程序窗口标题栏的文字颜色 86.如何设置程序窗口标题栏的文字颜色 87.如何在窗口标题栏中滚动显示文字 88.如何在对话框程序中设置标题栏文字 89.如何在单文档程序中设置标题栏文字 90.如何禁止在窗口标题栏上显示文档名 91.如何自定义单文档程序窗口的标题栏 92.如何取消单文档程序标题栏的右键菜单 93.如何隐藏或显示应用程序的标题栏 94.如何获取IE浏览器窗口的标题栏文字 95.如何修改IE浏览器的标题栏内容 96.如何禁止标题栏响应鼠标双击事件 97.如何在标题栏右键菜单中新增菜单项 98.如何禁止单文档程序的关闭按钮 99.如何禁止单文档程序的最大化按钮 100.如何禁止单文档程序的最小化按钮 101.如何获取顶层菜单所占的行数 102.如何获取单文档程序菜单栏的高度 103.如何获取菜单项的标题文本内容 104.如何以渐变色绘制选择的菜单项 105.如何在组菜单项的左侧绘制纵向标题 106.如何在菜单项中同时显示图标和文本 107.如何在单文档程序主菜单中删除菜单 108.如何在单文档程序主菜单中增加菜单 109.如何启用和禁用主菜单组中的子菜单 110.如何删除单文档程序的主菜单 111.如何根据数据库记录动态创建菜单 112.如何取消无消息响应菜单的状态限制 113.如何显示或隐藏菜单项的复选标记 114.如何创建单选按钮效果的菜单组 115.如何在“最近的文件”子菜单中显示记录 116.如何在视图窗口创建弹出式跟踪菜单 117.如何在视图窗口创建上下文快捷菜单 118.如何禁止运行默认系统菜单按钮命令 119.如何设置默认系统菜单的字体为粗体 120.如何为默认系统菜单文字添加下划线 121.如何增加对话框应用程序的系统菜单项 122.如何删除对话框程序的系统菜单项 l23.如何在对话框应用程序中加载菜单 124.如何为不同控件添加不同的右键菜单 125.如何在操作系统任务栏上添加托盘菜单 126.如何触发操作系统的“开始”菜单 127.如何隐藏IE浏览器的右键菜单组 第4章 工具栏和状态栏 128.如何获取工具栏中的图标资源 129.如何在工具栏上设置背景图像 130.如何在工具栏上加载动画窗口 131.如何在工具栏上加载组合框控件 132.如何在工具栏上加载孚体组合框 133.如何为工具栏添加动态真彩按钮 134.如何为工具栏按钮设置下拉箭头 135.如何为工具栏按钮添加下压效果 136.如何在工具栏上显示图标和文字 137.如何设置工具栏按钮的标题文字 138.如何设置工具栏按钮的提示信息 139.如何为对话框工具栏按钮添加提示 140.如何隐藏工具栏按钮的提示信息 141.如何在工具栏上增加删除按钮 142.如何动态隐藏或显示工具栏按钮 143.如何动态启用或禁用工具栏按钮 144.如何动态改变工具栏按钮的位置 145.如何对工具栏中的按钮进行分组 146.如何在对话框程序中加载工具栏 147.如何隐藏或显示应用程序的工具栏 148.如何在程序主窗口中停靠工具栏 149.如何使用对话栏实现工具栏效果 150.如何在IE浏览器工具栏上添加按钮 l51.如何使用代码设置工具栏图标 152.如何使用代码获取工具栏指针 153.如何使用代码获取状态栏指针 154.如何隐藏或显示应用程序的状态栏 155.如何在状态栏中增加新的窗格 156.如何更新状态栏窗格中的显示内容 157.如何同步状态栏与对话框窗体的改变 158.如何在状态栏窗格中显示当前时间 159.如何在状态栏窗格中显示鼠标位置 160.如何在状态栏窗格中滚动显示文本 161.如何在状态栏窗格中加载进度条 162.如何在状态栏窗格中加载图像 163.如何在状态栏窗格中播放视频动画 第5章 光标和图标的应用 164.如何获取系统默认的光标大小 165.如何装入操作系统预置的光标 166.如何设置当前程序显示的光标 167.如何创建沙漏效果的等待光标 168.如何使用十字光标定位画线坐标 169.如何使用动画文件设置程序光标 170.如何捕捉光标指向的热区范围 171.如何将光标限制在指定范围内 172.如何获取光标当前的活动范围 173.如何获取系统默认的图标大小 174.如何获取可执行文件中的图标 175.如何提取动态链接库中的图标 176.如何提取图标文件中的图标 177.如何以发送消息方式设置图标 178.如何使程序标题栏中的图标旋转 179.如何在操作系统托盘中设置图标 第6章 程序主窗口界面 180.如何创建一个向导式的对话框窗体 181.如何创建一个属性页的对话框窗体 182.如何创建列表视图类型的程序窗体 183.如何创建不规则的对话框窗体 184.如何创建圆角状的非矩形窗体 185.如何使用文字线条填充窗体轮廓 186.如何根据图片的形状创建程序窗体 187.如何在窗体中创建切分多视图窗口 188.如何在窗体中创建切分同视图窗口 189.如何判断程序窗体是否为切分窗体 190.如何设置单文档程序窗体的背景颜色 191.如何在对话框窗体中创建渐变色背景 192.如何随机更换对话框窗体的背景图像 193.如何设置HTML对话框窗体的背景图像 l94.如何获取默认的程序窗体边界宽度 195.如何获取窗体水平滚动条箭头宽度 196.如何获取窗体垂直滚动条箭头宽度 197.如何设置多文档程序的主窗口标题 198.如何设置多文档程序的子窗口标题 199.如何设置多文档程序的主窗口图标 200.如何设置多文档程序的子窗口图标 201.如何限制多文档程序子窗口的大小 202.如何禁止用户拖动标题栏移动窗体 203.如何闪烁应用程序窗体的标题栏 204.如何定制窗体的边框线和标题栏 205.如何拖动没有标题栏的程序窗体. 206.如何拖动非标题栏区域移动窗体 207.如何拖动对话框主窗体移动程序 208.如何动态隐藏或显示应用程序窗体 209.如何动态移动和改变程序窗体的位置 210.如何动态改变应用程序窗口的大小 211.如何限制改变应用程序窗口的大小 212.如何限制应用程序窗口的缩放范围 213.如何固定单文档程序窗体的大小 214.如何使用网页作为程序的主窗体 215.如何发送消息最大化显示程序窗口 216.如何发送消息最小化隐藏程序窗口 217.如何发送消息还原(恢复)程序窗口 218.如何使MDI程序子窗口最大化启动 219.如何使SDI程序窗口最大化启动 220.如何使SDI程序窗口最小化启动 221.如何以不同方式居中显示程序窗口 222.如何使单文档程序窗口最顶层显示 223.如何实现全屏显示应用程序窗口 224.如何使程序窗口以任意透明度显示 225.如何透明显示程序窗口的部分区域 226.如何将程序的窗口缩放到托盘显示 227.如何获取在任务栏显示的窗口程序 228.如何将其他窗口程序调至前台显示 229.如何以淡入的效果显示程序窗口 230.如何以淡出的效果隐藏程序窗口 231.如何以扩展的效果显示程序窗口 232.如何以动画收缩效果隐藏程序窗口 233.如何以扩展收缩效果展开程序窗口 234.如何以异步方式控制显示程序窗口 235.如何设置对话框程序窗口的启动位置 236.如何在上次关闭位置启动程序窗体 237.如何显示和关闭非模式对话框 238.如何在对话框程序中加入闪屏效果 239.如何在单文档程序中加入闪屏效果 240.如何使程序窗口自动适应图像尺寸 241.如何使用桌面区域填充程序窗口 242.如何在程序视图窗口中添加插入符 243.如何实现QQ抽屉导航效果的界面 244.如何使用树形视图导航程序界面 第7章 程序管理和控制 245.如何捕获按下的Home等功能键 246.如何捕获按下的Air或Shift+Alt组合键 247.如何捕获按下的Ctrl或Clrl+Alt组合键 248.如何捕获按下的Ctrl或Ctrl+Shift组合键 249.如何捕获用户按下键盘的任一按键 250.如何使用钩子技术监视键盘的按键操作 251.如何使用小键盘数字键模拟鼠标单击 252.如何禁止使用Esc键关闭对话框程序 253.如何禁止使用Air+F4组合键关闭程序 254.如何使用回车键切换编辑框的输入焦点 255.如何为应用程序自定义加速键 256.如何创建热键及其消息处理函数 257.如何判断是否同时按下了鼠标键和Ctrl键 258.如何判断鼠标按键是否单击了标题栏 259.如何跟踪显示鼠标移动的当前位置 260.如何在桌面上创建应用程序快捷方式 261.如何查询快捷方式所属的源程序名称 262.如何禁止在任务栏显示单文档程序标题 263.如何禁止多文档程序启动时创建新文档 264.如何直接以发送消息方式关闭程序 265.如何重定向菜单消息命令到对话框 266.如何添加命令响应范围消息处理函数 267.如何在应用程序中创建自定义消息 268.如何在应用程序中寄送自定义消息 269.如何使用定时器响应间隔发生的操作 270.如何使用互斥量禁止运行多个实例 271.如何使用映射文件禁止运行多个实例 272.如何在应用程序中执行其他应用程序 273.如何查找当前系统停止响应的程序 274.如何判断指定窗口程序是否已经运行 275.如何使单文档程序启动时显示对话框 276.如何在程序运行时禁止关闭计算机 277.如何在关闭单文档程序时给予提示 278.如何处理Windows程序的命令行参数 279.如何在应用程序中运行命令行命令 280.如何获取执行程序的版权声明信息 281.如何创建最简单的MFC应用程序 282.如何使:MFC程序架构支持一档多视 283.如何在MFC:程序中浏览PDF格式文件 第8章 打印机和打印实现 第9章 进程和线程管理 第10章 文件读写操作 第11章 文件和文件夹管理 第12章 字符串和数据转换 第13章 操作系统维护 第14章 计算机设备管理 第15章 文字和图像显示 第16章 音频和视频 第17章 网络通信 第18章 数据库管理 第19章 数据库访问 第20章 数据库查询 第21章 Word和Excel应用 第22章 WMI查询和管理 第23章 注册表综合应用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值