BCMenu.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. //*************************************************************************
  2. // BCMenu.h : header file
  3. // Version : 3.02
  4. // Date : March 2002
  5. // Author : Brent Corkum
  6. // Email : corkum@rocscience.com
  7. // Latest Version : http://www.rocscience.com/~corkum/BCMenu.html
  8. //
  9. // Bug Fixes and portions of code supplied by:
  10. //
  11. // Ben Ashley,Girish Bharadwaj,Jean-Edouard Lachand-Robert,
  12. // Robert Edward Caldecott,Kenny Goers,Leonardo Zide,
  13. // Stefan Kuhr,Reiner Jung,Martin Vladic,Kim Yoo Chul,
  14. // Oz Solomonovich,Tongzhe Cui,Stephane Clog,Warren Stevens,
  15. // Damir Valiulin,David Kinder,Marc Loiry
  16. //
  17. // You are free to use/modify this code but leave this header intact.
  18. // This class is public domain so you are free to use it any of
  19. // your applications (Freeware,Shareware,Commercial). All I ask is
  20. // that you let me know so that if you have a real winner I can
  21. // brag to my buddies that some of my code is in your app. I also
  22. // wouldn't mind if you sent me a copy of your application since I
  23. // like to play with new stuff.
  24. //*************************************************************************
  25. #ifndef BCMenu_H
  26. #define BCMenu_H
  27. #include <afxtempl.h>
  28. // BCMenuData class. Fill this class structure to define a single menu item:
  29. class BCMenuData
  30. {
  31. wchar_t *m_szMenuText;
  32. public:
  33. BCMenuData () {menuIconNormal=-1;xoffset=-1;bitmap=NULL;pContext=NULL;
  34. nFlags=0;nID=0;syncflag=0;m_szMenuText=NULL;global_offset=-1;threeD=FALSE;};
  35. void SetAnsiString(LPCSTR szAnsiString);
  36. void SetWideString(const wchar_t *szWideString);
  37. const wchar_t *GetWideString(void) {return m_szMenuText;};
  38. ~BCMenuData ();
  39. CString GetString(void);//returns the menu text in ANSI or UNICODE
  40. int xoffset,global_offset;
  41. BOOL threeD;
  42. int menuIconNormal;
  43. UINT nFlags,nID,syncflag;
  44. CImageList *bitmap;
  45. void *pContext; // used to attach user data
  46. };
  47. //struct CMenuItemInfo : public MENUITEMINFO {
  48. struct CMenuItemInfo : public
  49. //MENUITEMINFO
  50. #ifndef UNICODE //SK: this fixes warning C4097: typedef-name 'MENUITEMINFO' used as synonym for class-name 'tagMENUITEMINFOA'
  51. tagMENUITEMINFOA
  52. #else
  53. tagMENUITEMINFOW
  54. #endif
  55. {
  56. CMenuItemInfo()
  57. {
  58. memset(this, 0, sizeof(MENUITEMINFO));
  59. cbSize = sizeof(MENUITEMINFO);
  60. }
  61. };
  62. // how the menu's are drawn, either original or XP style
  63. typedef enum {BCMENU_DRAWMODE_ORIGINAL,BCMENU_DRAWMODE_XP} BC_MenuDrawMode;
  64. // how seperators are handled when removing a menu (Tongzhe Cui)
  65. typedef enum {BCMENU_NONE, BCMENU_HEAD, BCMENU_TAIL, BCMENU_BOTH} BC_Seperator;
  66. // defines for unicode support
  67. #ifndef UNICODE
  68. #define AppendMenu AppendMenuA
  69. #define InsertMenu InsertMenuA
  70. #define InsertODMenu InsertODMenuA
  71. #define AppendODMenu AppendODMenuA
  72. #define AppendODPopupMenu AppendODPopupMenuA
  73. #define ModifyODMenu ModifyODMenuA
  74. #else
  75. #define AppendMenu AppendMenuW
  76. #define InsertMenu InsertMenuW
  77. #define InsertODMenu InsertODMenuW
  78. #define AppendODMenu AppendODMenuW
  79. #define ModifyODMenu ModifyODMenuW
  80. #define AppendODPopupMenu AppendODPopupMenuW
  81. #endif
  82. class BCMenu : public CMenu
  83. {
  84. DECLARE_DYNAMIC( BCMenu )
  85. public:
  86. BCMenu();
  87. virtual ~BCMenu();
  88. // Functions for loading and applying bitmaps to menus (see example application)
  89. virtual BOOL LoadMenu(LPCTSTR lpszResourceName);
  90. virtual BOOL LoadMenu(int nResource);
  91. BOOL LoadToolbar(UINT nToolBar);
  92. BOOL LoadToolbars(const UINT *arID,int n);
  93. void AddFromToolBar(CToolBar* pToolBar, int nResourceID);
  94. BOOL LoadFromToolBar(UINT nID,UINT nToolBar,int& xoffset);
  95. BOOL AddBitmapToImageList(CImageList *list,UINT nResourceID);
  96. static HBITMAP LoadSysColorBitmap(int nResourceId);
  97. void LoadCheckmarkBitmap(int unselect,int select); // custom check mark bitmaps
  98. // functions for appending a menu option, use the AppendMenu call (see above define)
  99. BOOL AppendMenuA(UINT nFlags,UINT nIDNewItem=0,const char *lpszNewItem=NULL,int nIconNormal=-1);
  100. BOOL AppendMenuA(UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CImageList *il,int xoffset);
  101. BOOL AppendMenuA(UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CBitmap *bmp);
  102. BOOL AppendMenuW(UINT nFlags,UINT nIDNewItem=0,wchar_t *lpszNewItem=NULL,int nIconNormal=-1);
  103. BOOL AppendMenuW(UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CImageList *il,int xoffset);
  104. BOOL AppendMenuW(UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CBitmap *bmp);
  105. BOOL AppendODMenuA(LPCSTR lpstrText,UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
  106. BOOL AppendODMenuW(wchar_t *lpstrText,UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
  107. BOOL AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT nID,CImageList *il,int xoffset);
  108. BOOL AppendODMenuW(wchar_t *lpstrText,UINT nFlags,UINT nID,CImageList *il,int xoffset);
  109. // for appending a popup menu (see example application)
  110. BCMenu* AppendODPopupMenuA(LPCSTR lpstrText);
  111. BCMenu* AppendODPopupMenuW(wchar_t *lpstrText);
  112. // functions for inserting a menu option, use the InsertMenu call (see above define)
  113. BOOL InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem=0,const char *lpszNewItem=NULL,int nIconNormal=-1);
  114. BOOL InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CImageList *il,int xoffset);
  115. BOOL InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CBitmap *bmp);
  116. BOOL InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem=0,wchar_t *lpszNewItem=NULL,int nIconNormal=-1);
  117. BOOL InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CImageList *il,int xoffset);
  118. BOOL InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CBitmap *bmp);
  119. BOOL InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
  120. BOOL InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
  121. BOOL InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT nID,CImageList *il,int xoffset);
  122. BOOL InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT nID,CImageList *il,int xoffset);
  123. // functions for modifying a menu option, use the ModifyODMenu call (see above define)
  124. BOOL ModifyODMenuA(const char *lpstrText,UINT nID=0,int nIconNormal=-1);
  125. BOOL ModifyODMenuA(const char *lpstrText,UINT nID,CImageList *il,int xoffset);
  126. BOOL ModifyODMenuA(const char *lpstrText,UINT nID,CBitmap *bmp);
  127. BOOL ModifyODMenuA(const char *lpstrText,const char *OptionText,int nIconNormal);
  128. BOOL ModifyODMenuW(wchar_t *lpstrText,UINT nID=0,int nIconNormal=-1);
  129. BOOL ModifyODMenuW(wchar_t *lpstrText,UINT nID,CImageList *il,int xoffset);
  130. BOOL ModifyODMenuW(wchar_t *lpstrText,UINT nID,CBitmap *bmp);
  131. BOOL ModifyODMenuW(wchar_t *lpstrText,wchar_t *OptionText,int nIconNormal);
  132. // use this method for adding a solid/hatched colored square beside a menu option
  133. // courtesy of Warren Stevens
  134. BOOL ModifyODMenuA(const char *lpstrText,UINT nID,COLORREF fill,COLORREF border,int hatchstyle=-1,CSize *pSize=NULL);
  135. BOOL ModifyODMenuW(wchar_t *lpstrText,UINT nID,COLORREF fill,COLORREF border,int hatchstyle=-1,CSize *pSize=NULL);
  136. // for deleting and removing menu options
  137. BOOL RemoveMenu(UINT uiId,UINT nFlags);
  138. BOOL DeleteMenu(UINT uiId,UINT nFlags);
  139. // sPos means Seperator's position, since we have no way to find the seperator's position in the menu
  140. // we have to specify them when we call the RemoveMenu to make sure the unused seperators are removed;
  141. // sPos = None no seperator removal;
  142. // = Head seperator in front of this menu item;
  143. // = Tail seperator right after this menu item;
  144. // = Both seperators at both ends;
  145. // remove the menu item based on their text, return -1 if not found, otherwise return the menu position;
  146. int RemoveMenu(char* pText, BC_Seperator sPos=BCMENU_NONE);
  147. int RemoveMenu(wchar_t* pText, BC_Seperator sPos=BCMENU_NONE);
  148. int DeleteMenu(char* pText, BC_Seperator sPos=BCMENU_NONE);
  149. int DeleteMenu(wchar_t* pText, BC_Seperator sPos=BCMENU_NONE);
  150. // Destoying
  151. virtual BOOL DestroyMenu();
  152. // function for retrieving and setting a menu options text (use this function
  153. // because it is ownerdrawn)
  154. BOOL GetMenuText(UINT id,CString &string,UINT nFlags = MF_BYPOSITION);
  155. BOOL SetMenuText(UINT id,CString string, UINT nFlags = MF_BYPOSITION);
  156. // Getting a submenu from it's name or position
  157. BCMenu* GetSubBCMenu(char* lpszSubMenuName);
  158. BCMenu* GetSubBCMenu(wchar_t* lpszSubMenuName);
  159. CMenu* GetSubMenu (LPCTSTR lpszSubMenuName);
  160. CMenu* GetSubMenu (int nPos);
  161. int GetMenuPosition(char* pText);
  162. int GetMenuPosition(wchar_t* pText);
  163. // Drawing:
  164. virtual void DrawItem( LPDRAWITEMSTRUCT); // Draw an item
  165. virtual void MeasureItem( LPMEASUREITEMSTRUCT ); // Measure an item
  166. // Static functions used for handling menu's in the mainframe
  167. static void UpdateMenu(CMenu *pmenu);
  168. static BOOL IsMenu(CMenu *submenu);
  169. static BOOL IsMenu(HMENU submenu);
  170. static LRESULT FindKeyboardShortcut(UINT nChar,UINT nFlags,CMenu *pMenu);
  171. // Function to set how menu is drawn, either original or XP style
  172. static void SetMenuDrawMode(UINT mode){
  173. BCMenu::original_drawmode=mode;
  174. BCMenu::xp_drawmode=mode;
  175. };
  176. // Function to set how disabled items are drawn (mode=FALSE means they are not drawn selected)
  177. static void SetSelectDisableMode(BOOL mode){
  178. BCMenu::original_select_disabled=mode;
  179. BCMenu::xp_select_disabled=mode;
  180. };
  181. static int BCMenu::GetMenuDrawMode(void);
  182. static BOOL BCMenu::GetSelectDisableMode(void);
  183. // how the bitmaps are drawn in XP Luna mode
  184. static void SetXPBitmap3D(BOOL val){
  185. BCMenu::xp_draw_3D_bitmaps=val;
  186. };
  187. static BOOL GetXPBitmap3D(void){return BCMenu::xp_draw_3D_bitmaps;}
  188. // Customizing:
  189. // Set icon size
  190. void SetIconSize (int, int);
  191. // set the color in the bitmaps that is the background transparent color
  192. void SetBitmapBackground(COLORREF color);
  193. void UnSetBitmapBackground(void);
  194. // obsolete functions for setting how menu images are dithered for disabled menu options
  195. BOOL GetDisableOldStyle(void);
  196. void SetDisableOldStyle(void);
  197. void UnSetDisableOldStyle(void);
  198. static COLORREF LightenColor(COLORREF col,double factor);
  199. static COLORREF DarkenColor(COLORREF col,double factor);
  200. // Miscellaneous Protected Member functions
  201. protected:
  202. static BOOL IsNewShell(void);
  203. static BOOL IsWinXPLuna(void);
  204. static BOOL IsLunaMenuStyle(void);
  205. static BOOL IsWindowsClassicTheme(void);
  206. BCMenuData *BCMenu::FindMenuItem(UINT nID);
  207. BCMenu *FindMenuOption(int nId,int& nLoc);
  208. BCMenu *FindAnotherMenuOption(int nId,int& nLoc,CArray<BCMenu*,BCMenu*>&bcsubs,
  209. CArray<int,int&>&bclocs);
  210. BCMenuData *FindMenuOption(wchar_t *lpstrText);
  211. void InsertSpaces(void);
  212. void DrawCheckMark(CDC *pDC,int x,int y,COLORREF color);
  213. void DrawRadioDot(CDC *pDC,int x,int y,COLORREF color);
  214. BCMenuData *NewODMenu(UINT pos,UINT nFlags,UINT nID,CString string);
  215. void SynchronizeMenu(void);
  216. void BCMenu::InitializeMenuList(int value);
  217. void BCMenu::DeleteMenuList(void);
  218. BCMenuData *BCMenu::FindMenuList(UINT nID);
  219. void DrawItem_Win9xNT2000 (LPDRAWITEMSTRUCT lpDIS);
  220. void DrawItem_WinXP (LPDRAWITEMSTRUCT lpDIS);
  221. BOOL Draw3DCheckmark(CDC *dc, const CRect& rc,BOOL bSelected,HBITMAP hbmCheck);
  222. BOOL DrawXPCheckmark(CDC *dc, const CRect& rc, HBITMAP hbmCheck,COLORREF &colorout);
  223. void DitherBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth,
  224. int nHeight, HBITMAP hbm, int nXSrc, int nYSrc,COLORREF bgcolor);
  225. void DitherBlt2(CDC *drawdc, int nXDest, int nYDest, int nWidth,
  226. int nHeight, CBitmap &bmp, int nXSrc, int nYSrc,COLORREF bgcolor);
  227. BOOL GetBitmapFromImageList(CDC* pDC,CImageList *imglist,int nIndex,CBitmap &bmp);
  228. BOOL ImageListDuplicate(CImageList *il,int xoffset,CImageList *newlist);
  229. static WORD NumBitmapColors(LPBITMAPINFOHEADER lpBitmap);
  230. void ColorBitmap(CDC* pDC, CBitmap& bmp,CSize bitmap_size,CSize icon_size,COLORREF fill,COLORREF border,int hatchstyle=-1);
  231. void RemoveTopLevelOwnerDraw(void);
  232. int GetMenuStart(void);
  233. void GetFadedBitmap(CBitmap &bmp);
  234. void GetShadowBitmap(CBitmap &bmp);
  235. int AddToGlobalImageList(CImageList *il,int xoffset,int nID);
  236. int GlobalImageListOffset(int nID);
  237. BOOL CanDraw3DImageList(int offset);
  238. // Member Variables
  239. protected:
  240. CTypedPtrArray<CPtrArray, BCMenuData*> m_MenuList; // Stores list of menu items
  241. // When loading an owner-drawn menu using a Resource, BCMenu must keep track of
  242. // the popup menu's that it creates. Warning, this list *MUST* be destroyed
  243. // last item first :)
  244. CTypedPtrArray<CPtrArray, HMENU> m_SubMenus; // Stores list of sub-menus
  245. // Stores a list of all BCMenu's ever created
  246. static CTypedPtrArray<CPtrArray, HMENU> m_AllSubMenus;
  247. // Global ImageList
  248. static CImageList m_AllImages;
  249. static CArray<int,int&> m_AllImagesID;
  250. // icon size
  251. int m_iconX,m_iconY;
  252. COLORREF m_bitmapBackground;
  253. BOOL m_bitmapBackgroundFlag;
  254. BOOL disable_old_style;
  255. static UINT original_drawmode;
  256. static BOOL original_select_disabled;
  257. static UINT xp_drawmode;
  258. static BOOL xp_select_disabled;
  259. static BOOL xp_draw_3D_bitmaps;
  260. CImageList *checkmaps;
  261. BOOL checkmapsshare;
  262. int m_selectcheck;
  263. int m_unselectcheck;
  264. BOOL m_bDynIcons;
  265. BOOL m_loadmenu;
  266. };
  267. class BCMenuToolBar : public CToolBar{
  268. public:
  269. BCMenuToolBar() : CToolBar() {m_iconX=m_iconY=0;}
  270. BOOL LoadToolBar(LPCTSTR lpszResourceName);
  271. BOOL LoadToolBar(UINT nIDResource){
  272. return LoadToolBar(MAKEINTRESOURCE(nIDResource));
  273. }
  274. BOOL LoadBitmap(LPCTSTR lpszResourceName);
  275. void GetIconSize(int &iconx,int &icony){iconx=m_iconX;icony=m_iconY;}
  276. protected:
  277. int m_iconX,m_iconY;
  278. };
  279. #define BCMENU_USE_MEMDC
  280. #ifdef BCMENU_USE_MEMDC
  281. //////////////////////////////////////////////////
  282. // BCMenuMemDC - memory DC
  283. //
  284. // Author: Keith Rule
  285. // Email: keithr@europa.com
  286. // Copyright 1996-1997, Keith Rule
  287. //
  288. // You may freely use or modify this code provided this
  289. // Copyright is included in all derived versions.
  290. //
  291. // History - 10/3/97 Fixed scrolling bug.
  292. // Added print support.
  293. // 25 feb 98 - fixed minor assertion bug
  294. //
  295. // This class implements a memory Device Context
  296. class BCMenuMemDC : public CDC
  297. {
  298. public:
  299. // constructor sets up the memory DC
  300. BCMenuMemDC(CDC* pDC,LPCRECT lpSrcRect) : CDC()
  301. {
  302. ASSERT(pDC != NULL);
  303. m_rect.CopyRect(lpSrcRect);
  304. m_pDC = pDC;
  305. m_pOldBitmap = NULL;
  306. m_bMemDC = !pDC->IsPrinting();
  307. if (m_bMemDC) // Create a Memory DC
  308. {
  309. CreateCompatibleDC(pDC);
  310. m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
  311. m_pOldBitmap = SelectObject(&m_bitmap);
  312. SetWindowOrg(m_rect.left, m_rect.top);
  313. }
  314. else // Make a copy of the relevent parts of the current DC for printing
  315. {
  316. m_bPrinting = pDC->m_bPrinting;
  317. m_hDC = pDC->m_hDC;
  318. m_hAttribDC = pDC->m_hAttribDC;
  319. }
  320. }
  321. // Destructor copies the contents of the mem DC to the original DC
  322. ~BCMenuMemDC()
  323. {
  324. if (m_bMemDC)
  325. {
  326. // Copy the offscreen bitmap onto the screen.
  327. m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
  328. this, m_rect.left, m_rect.top, SRCCOPY);
  329. //Swap back the original bitmap.
  330. SelectObject(m_pOldBitmap);
  331. } else {
  332. // All we need to do is replace the DC with an illegal value,
  333. // this keeps us from accidently deleting the handles associated with
  334. // the CDC that was passed to the constructor.
  335. m_hDC = m_hAttribDC = NULL;
  336. }
  337. }
  338. // Allow usage as a pointer
  339. BCMenuMemDC* operator->() {return this;}
  340. // Allow usage as a pointer
  341. operator BCMenuMemDC*() {return this;}
  342. private:
  343. CBitmap m_bitmap; // Offscreen bitmap
  344. CBitmap* m_pOldBitmap; // bitmap originally found in BCMenuMemDC
  345. CDC* m_pDC; // Saves CDC passed in constructor
  346. CRect m_rect; // Rectangle of drawing area.
  347. BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.
  348. };
  349. #endif
  350. #endif
  351. //*************************************************************************