1 // Windows/Menu.h
2 
3 #ifndef __WINDOWS_MENU_H
4 #define __WINDOWS_MENU_H
5 
6 #include "../Common/MyString.h"
7 
8 #include "Defs.h"
9 
10 namespace NWindows {
11 
12 struct CMenuItem
13 {
14   UString StringValue;
15   UINT fMask;
16   UINT fType;
17   UINT fState;
18   UINT wID;
19   HMENU hSubMenu;
20   HBITMAP hbmpChecked;
21   HBITMAP hbmpUnchecked;
22   ULONG_PTR dwItemData;
23   // LPTSTR dwTypeData;
24   // UINT cch;
25   // HBITMAP hbmpItem;
IsStringCMenuItem26   bool IsString() const // change it MIIM_STRING
27     { return ((fMask & MIIM_TYPE) != 0 && (fType == MFT_STRING)); }
IsSeparatorCMenuItem28   bool IsSeparator() const { return (fType == MFT_SEPARATOR); }
CMenuItemCMenuItem29   CMenuItem(): fMask(0), fType(0), fState(0), wID(0), hSubMenu(0), hbmpChecked(0),
30     hbmpUnchecked(0), dwItemData(0) {}
31 };
32 
33 class CMenu
34 {
35   HMENU _menu;
36 public:
CMenu()37   CMenu(): _menu(NULL) {};
HMENU()38   operator HMENU() const { return _menu; }
Attach(HMENU menu)39   void Attach(HMENU menu) { _menu = menu; }
40 
Detach()41   HMENU Detach()
42   {
43     HMENU menu = _menu;
44     _menu = NULL;
45     return menu;
46   }
47 
Create()48   bool Create()
49   {
50     _menu = ::CreateMenu();
51     return (_menu != NULL);
52   }
53 
CreatePopup()54   bool CreatePopup()
55   {
56     _menu = ::CreatePopupMenu();
57     return (_menu != NULL);
58   }
59 
Destroy()60   bool Destroy()
61   {
62     if (_menu == NULL)
63       return false;
64     return BOOLToBool(::DestroyMenu(Detach()));
65   }
66 
GetItemCount()67   int GetItemCount()
68   {
69     #ifdef UNDER_CE
70     for (int i = 0;; i++)
71     {
72       CMenuItem item;
73       item.fMask = MIIM_STATE;
74       if (!GetItem(i, true, item))
75         return i;
76     }
77     #else
78     return GetMenuItemCount(_menu);
79     #endif
80   }
81 
GetSubMenu(int pos)82   HMENU GetSubMenu(int pos) { return ::GetSubMenu(_menu, pos); }
83   #ifndef UNDER_CE
84   /*
85   bool GetItemString(UINT idItem, UINT flag, CSysString &result)
86   {
87     result.Empty();
88     int len = ::GetMenuString(_menu, idItem, 0, 0, flag);
89     int len2 = ::GetMenuString(_menu, idItem, result.GetBuf(len + 2), len + 1, flag);
90     if (len > len2)
91       len = len2;
92     result.ReleaseBuf_CalcLen(len + 2);
93     return (len != 0);
94   }
95   */
GetItemID(int pos)96   UINT GetItemID(int pos) { return ::GetMenuItemID(_menu, pos);   }
GetItemState(UINT id,UINT flags)97   UINT GetItemState(UINT id, UINT flags) { return ::GetMenuState(_menu, id, flags);   }
98   #endif
99 
GetItemInfo(UINT itemIndex,bool byPosition,LPMENUITEMINFO itemInfo)100   bool GetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFO itemInfo)
101     { return BOOLToBool(::GetMenuItemInfo(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
SetItemInfo(UINT itemIndex,bool byPosition,LPMENUITEMINFO itemInfo)102   bool SetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFO itemInfo)
103     { return BOOLToBool(::SetMenuItemInfo(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
104 
AppendItem(UINT flags,UINT_PTR newItemID,LPCTSTR newItem)105   bool AppendItem(UINT flags, UINT_PTR newItemID, LPCTSTR newItem)
106     { return BOOLToBool(::AppendMenu(_menu, flags, newItemID, newItem)); }
107 
Insert(UINT position,UINT flags,UINT_PTR idNewItem,LPCTSTR newItem)108   bool Insert(UINT position, UINT flags, UINT_PTR idNewItem, LPCTSTR newItem)
109     { return BOOLToBool(::InsertMenu(_menu, position, flags, idNewItem, newItem)); }
110 
111   #ifndef UNDER_CE
InsertItem(UINT itemIndex,bool byPosition,LPCMENUITEMINFO itemInfo)112   bool InsertItem(UINT itemIndex, bool byPosition, LPCMENUITEMINFO itemInfo)
113     { return BOOLToBool(::InsertMenuItem(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
114   #endif
115 
RemoveItem(UINT item,UINT flags)116   bool RemoveItem(UINT item, UINT flags) { return BOOLToBool(::RemoveMenu(_menu, item, flags)); }
RemoveAllItemsFrom(UINT index)117   void RemoveAllItemsFrom(UINT index) { while (RemoveItem(index, MF_BYPOSITION)); }
RemoveAllItems()118   void RemoveAllItems() { RemoveAllItemsFrom(0); }
119 
120   #ifndef _UNICODE
GetItemInfo(UINT itemIndex,bool byPosition,LPMENUITEMINFOW itemInfo)121   bool GetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo)
122     { return BOOLToBool(::GetMenuItemInfoW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
InsertItem(UINT itemIndex,bool byPosition,LPMENUITEMINFOW itemInfo)123   bool InsertItem(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo)
124     { return BOOLToBool(::InsertMenuItemW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
SetItemInfo(UINT itemIndex,bool byPosition,LPMENUITEMINFOW itemInfo)125   bool SetItemInfo(UINT itemIndex, bool byPosition, LPMENUITEMINFOW itemInfo)
126     { return BOOLToBool(::SetMenuItemInfoW(_menu, itemIndex, BoolToBOOL(byPosition), itemInfo)); }
127   bool AppendItem(UINT flags, UINT_PTR newItemID, LPCWSTR newItem);
128   #endif
129 
130   bool GetItem(UINT itemIndex, bool byPosition, CMenuItem &item);
131   bool SetItem(UINT itemIndex, bool byPosition, const CMenuItem &item);
132   bool InsertItem(UINT itemIndex, bool byPosition, const CMenuItem &item);
133 
Track(UINT flags,int x,int y,HWND hWnd)134   int Track(UINT flags, int x, int y, HWND hWnd) { return ::TrackPopupMenuEx(_menu, flags, x, y, hWnd, NULL); }
135 
CheckRadioItem(UINT idFirst,UINT idLast,UINT idCheck,UINT flags)136   bool CheckRadioItem(UINT idFirst, UINT idLast, UINT idCheck, UINT flags)
137     { return BOOLToBool(::CheckMenuRadioItem(_menu, idFirst, idLast, idCheck, flags)); }
138 
CheckItem(UINT id,UINT uCheck)139   DWORD CheckItem(UINT id, UINT uCheck) { return ::CheckMenuItem(_menu, id, uCheck); }
CheckItemByID(UINT id,bool check)140   DWORD CheckItemByID(UINT id, bool check) { return CheckItem(id, MF_BYCOMMAND | (check ? MF_CHECKED : MF_UNCHECKED)); }
141 
EnableItem(UINT uIDEnableItem,UINT uEnable)142   BOOL EnableItem(UINT uIDEnableItem, UINT uEnable) { return EnableMenuItem(_menu, uIDEnableItem, uEnable); }
143 };
144 
145 class CMenuDestroyer
146 {
147   CMenu *_menu;
148 public:
CMenuDestroyer(CMenu & menu)149   CMenuDestroyer(CMenu &menu): _menu(&menu) {}
CMenuDestroyer()150   CMenuDestroyer(): _menu(0) {}
~CMenuDestroyer()151   ~CMenuDestroyer() { if (_menu) _menu->Destroy(); }
Attach(CMenu & menu)152   void Attach(CMenu &menu) { _menu = &menu; }
Disable()153   void Disable() { _menu = 0; }
154 };
155 
156 }
157 
158 #endif
159