forked from WinMerge/winmerge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBCMenu.h
341 lines (317 loc) · 13.2 KB
/
BCMenu.h
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
//*************************************************************************
// BCMenu.h : header file
// Version : 3.036
// Date : June 2005
// Author : Brent Corkum
// Email : corkum@rocscience.com
// Latest Version : http://www.rocscience.com/~corkum/BCMenu.html
//
// Bug Fixes and portions of code supplied by:
//
// 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,David Kinder,Marc Loiry
//
// 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.
//*************************************************************************
#pragma once
#include <afxtempl.h>
// BCMenuData class. Fill this class structure to define a single menu item:
class BCMenuData
{
wchar_t *m_szMenuText;
public:
BCMenuData () {menuIconNormal=-1;xoffset=-1;bitmap=nullptr;pContext=nullptr;
nFlags=0;nID=0;syncflag=0;m_szMenuText=nullptr;global_offset=-1;};
void SetAnsiString(LPCSTR szAnsiString)
{
USES_CONVERSION;
SetWideString(A2W(szAnsiString)); //SK: see MFC Tech Note 059
}
void SetWideString(const wchar_t *szWideString);
const wchar_t *GetWideString(void) {return m_szMenuText;};
~BCMenuData ();
CString GetString(void);//returns the menu text in ANSI or UNICODE
INT_PTR xoffset,global_offset;
int menuIconNormal;
UINT nFlags,syncflag;
UINT_PTR nID;
CImageList *bitmap;
void *pContext; // used to attach user data
};
struct CMenuItemInfo : public MENUITEMINFO
{
CMenuItemInfo()
{
memset(this, 0, sizeof(MENUITEMINFO));
cbSize = sizeof(MENUITEMINFO);
}
};
// how seperators are handled when removing a menu (Tongzhe Cui)
typedef enum {BCMENU_NONE, BCMENU_HEAD, BCMENU_TAIL, BCMENU_BOTH} BC_Seperator;
// defines for unicode support
#ifndef UNICODE
#define AppendMenu AppendMenuA
#define InsertMenu InsertMenuA
#define InsertODMenu InsertODMenuA
#define AppendODMenu AppendODMenuA
#define AppendODPopupMenu AppendODPopupMenuA
#define ModifyODMenu ModifyODMenuA
#define SetImageForPopupFromToolbar SetImageForPopupFromToolbarA
#else
#define AppendMenu AppendMenuW
#define InsertMenu InsertMenuW
#define InsertODMenu InsertODMenuW
#define AppendODMenu AppendODMenuW
#define ModifyODMenu ModifyODMenuW
#define AppendODPopupMenu AppendODPopupMenuW
#define SetImageForPopupFromToolbar SetImageForPopupFromToolbarW
#endif
class BCMenu : public CMenu
{
DECLARE_DYNAMIC( BCMenu )
public:
BCMenu();
virtual ~BCMenu();
// Functions for loading and applying bitmaps to menus (see example application)
virtual BOOL LoadMenu(LPCTSTR lpszResourceName);
virtual BOOL LoadMenu(int nResource);
bool LoadToolbar(UINT nToolBar);
bool LoadToolbars(const UINT *arID,int n);
bool LoadFromToolBar(UINT nID,UINT nToolBar,int& xoffset);
bool AddBitmapToImageList(CImageList *list,UINT nResourceID,bool bDisabled=false);
static HBITMAP LoadSysColorBitmap(int nResourceId);
// functions for appending a menu option, use the AppendMenu call (see above define)
bool AppendMenuA(UINT nFlags,UINT_PTR nIDNewItem=0,const char *lpszNewItem=nullptr,int nIconNormal=-1)
{
USES_CONVERSION;
return AppendMenuW(nFlags, nIDNewItem, A2W(lpszNewItem), nIconNormal);
}
bool AppendMenuA(UINT nFlags,UINT_PTR nIDNewItem,const char *lpszNewItem,CImageList *il,int xoffset)
{
USES_CONVERSION;
return AppendMenuW(nFlags,nIDNewItem,A2W(lpszNewItem),il,xoffset);
}
bool AppendMenuA(UINT nFlags,UINT_PTR nIDNewItem,const char *lpszNewItem,CBitmap *bmp)
{
USES_CONVERSION;
return AppendMenuW(nFlags,nIDNewItem,A2W(lpszNewItem),bmp);
}
bool AppendMenuW(UINT nFlags,UINT_PTR nIDNewItem=0,const wchar_t *lpszNewItem=nullptr,int nIconNormal=-1);
bool AppendMenuW(UINT nFlags,UINT_PTR nIDNewItem,const wchar_t *lpszNewItem,CImageList *il,int xoffset);
bool AppendMenuW(UINT nFlags,UINT_PTR nIDNewItem,const wchar_t *lpszNewItem,CBitmap *bmp);
bool AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT_PTR nID,
int nIconNormal)
{
USES_CONVERSION;
return AppendODMenuW(A2W(lpstrText),nFlags,nID,nIconNormal);//SK: See MFC Tech Note 059
}
bool AppendODMenuW(const wchar_t *lpstrText,UINT nFlags = MF_OWNERDRAW,UINT_PTR nID = 0,int nIconNormal = -1);
bool AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT_PTR nID,
CImageList *il,int xoffset)
{
USES_CONVERSION;
return AppendODMenuW(A2W(lpstrText),nFlags,nID,il,xoffset);
}
bool AppendODMenuW(const wchar_t *lpstrText,UINT nFlags,UINT_PTR nID,CImageList *il,int xoffset);
bool AppendMenu (BCMenu* pMenuToAdd, bool add_separator = true, int num_items_to_remove_at_end = 0);
// for appending a popup menu (see example application)
BCMenu* AppendODPopupMenuA(LPCSTR lpstrText)
{
USES_CONVERSION;
return AppendODPopupMenuW(A2W(lpstrText));
}
BCMenu* AppendODPopupMenuW(const wchar_t *lpstrText);
// functions for inserting a menu option, use the InsertMenu call (see above define)
bool InsertMenuA(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem,const char *lpszNewItem,CImageList *il,int xoffset)
{
USES_CONVERSION;
return InsertMenuW(nPosition,nFlags,nIDNewItem,A2W(lpszNewItem),il,xoffset);
}
bool InsertMenuA(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem,const char *lpszNewItem,CBitmap *bmp)
{
USES_CONVERSION;
return InsertMenuW(nPosition,nFlags,nIDNewItem,A2W(lpszNewItem),bmp);
}
bool InsertMenuA(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem,const char *lpszNewItem,int nIconNormal)
{
USES_CONVERSION;
return InsertMenuW(nPosition,nFlags,nIDNewItem,A2W(lpszNewItem),nIconNormal);
}
bool InsertMenuW(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem=0,wchar_t *lpszNewItem=nullptr,int nIconNormal=-1);
bool InsertMenuW(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem,wchar_t *lpszNewItem,CImageList *il,int xoffset);
bool InsertMenuW(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem,wchar_t *lpszNewItem,CBitmap *bmp);
bool InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT_PTR nID,
int nIconNormal)
{
USES_CONVERSION;
return InsertODMenuW(nPosition,A2W(lpstrText),nFlags,nID,nIconNormal);
}
bool InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags = MF_OWNERDRAW,UINT_PTR nID = 0,int nIconNormal = -1);
bool InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT_PTR nID,
CImageList *il,int xoffset)
{
USES_CONVERSION;
return InsertODMenuW(nPosition,A2W(lpstrText),nFlags,nID,il,xoffset);
}
bool InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT_PTR nID,CImageList *il,int xoffset);
// functions for modifying a menu option, use the ModifyODMenu call (see above define)
bool ModifyODMenuA(const char * lpstrText,UINT_PTR nID,int nIconNormal)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,nIconNormal);//SK: see MFC Tech Note 059
}
bool ModifyODMenuA(const char * lpstrText,UINT_PTR nID,CImageList *il,int xoffset)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,il,xoffset);
}
bool ModifyODMenuA(const char *lpstrText,UINT_PTR nID,CBitmap *bmp)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),nID,bmp);
}
bool ModifyODMenuA(const char *lpstrText,const char *OptionText,
int nIconNormal)
{
USES_CONVERSION;
return ModifyODMenuW(A2W(lpstrText),A2W(OptionText),nIconNormal);//SK: see MFC Tech Note 059
}
bool ModifyODMenuW(wchar_t *lpstrText,UINT_PTR nID=0,int nIconNormal=-1);
bool ModifyODMenuW(wchar_t *lpstrText,UINT_PTR nID,CImageList *il,int xoffset);
bool ModifyODMenuW(wchar_t *lpstrText,UINT_PTR nID,CBitmap *bmp);
bool ModifyODMenuW(wchar_t *lpstrText,wchar_t *OptionText,int nIconNormal);
bool SetImageForPopupFromToolbarA (const char *strPopUpText, UINT toolbarID, UINT command_id_to_extract_icon_from)
{
USES_CONVERSION;
return SetImageForPopupFromToolbarW(A2W(strPopUpText),toolbarID,command_id_to_extract_icon_from);
}
bool SetImageForPopupFromToolbarW (wchar_t *strPopUpText, UINT toolbarID, UINT command_id_to_extract_icon_from);
// for deleting and removing menu options
bool RemoveMenu(UINT uiId,UINT nFlags);
bool DeleteMenu(UINT uiId,UINT nFlags);
// 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 RemoveMenu(char* pText, BC_Seperator sPos)
{
USES_CONVERSION;
return RemoveMenu(A2W(pText), sPos);
}
int RemoveMenu(wchar_t* pText, BC_Seperator sPos=BCMENU_NONE);
int DeleteMenu(char* pText, BC_Seperator sPos)
{
USES_CONVERSION;
return DeleteMenu(A2W(pText), sPos);
}
int DeleteMenu(wchar_t* pText, BC_Seperator sPos=BCMENU_NONE);
// Destoying
virtual BOOL DestroyMenu();
// 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
BCMenu* GetSubBCMenu(char* pText)
{
USES_CONVERSION;
return GetSubBCMenu(A2W(pText));
}
BCMenu* GetSubBCMenu(wchar_t* lpszSubMenuName);
CMenu* GetSubMenu (LPCTSTR lpszSubMenuName);
CMenu* GetSubMenu (int nPos);
int GetMenuPosition(char* pText)
{
USES_CONVERSION;
return GetMenuPosition(A2W(pText));
}
int GetMenuPosition(wchar_t* pText);
// Drawing:
virtual void DrawItem( LPDRAWITEMSTRUCT); // Draw an item
virtual void MeasureItem( LPMEASUREITEMSTRUCT ); // Measure an item
// Static functions used for handling menu's in the mainframe
static void UpdateMenu(CMenu *pmenu);
static bool IsMenu(CMenu *submenu);
static bool IsMenu(HMENU submenu);
static LRESULT FindKeyboardShortcut(UINT nChar,UINT nFlags,CMenu *pMenu);
// Customizing:
// Set icon size
static void SetIconSize (int, int);
// set the color in the bitmaps that is the background transparent color
void SetBitmapBackground(COLORREF color);
void UnSetBitmapBackground(void);
// obsolete functions for setting how menu images are dithered for disabled menu options
static inline COLORREF LightenColor(COLORREF col,double factor);
public:
// Miscellaneous Protected Member functions
protected:
BCMenuData *FindMenuItem(UINT_PTR nID);
BCMenu *FindMenuOption(int nId,UINT& nLoc);
BCMenu *FindAnotherMenuOption(int nId,UINT& nLoc,CArray<BCMenu*,BCMenu*>&bcsubs,
CArray<UINT,UINT&>&bclocs);
BCMenuData *FindMenuOption(wchar_t *lpstrText);
void DrawCheckMark(CDC* pDC,int x,int y,COLORREF color,bool narrowflag=false);
void DrawRadioDot(CDC *pDC,int x,int y,COLORREF color);
BCMenuData *NewODMenu(UINT pos,UINT nFlags,UINT_PTR nID,CString string);
void SynchronizeMenu(void);
void InitializeMenuList(int value);
void DeleteMenuList(void);
BCMenuData *FindMenuList(UINT_PTR nID);
void DrawItem_Win9xNT2000 (LPDRAWITEMSTRUCT lpDIS);
bool Draw3DCheckmark(CDC *dc, const CRect& rc,bool bSelected,HBITMAP hbmCheck);
void DrawItem_Theme (LPDRAWITEMSTRUCT lpDIS);
void DitherBlt2(CDC *drawdc, int nXDest, int nYDest, int nWidth,
int nHeight, CBitmap &bmp, int nXSrc, int nYSrc,COLORREF bgcolor);
void DitherBlt3(CDC *drawdc, int nXDest, int nYDest, int nWidth,
int nHeight, CBitmap &bmp,COLORREF bgcolor);
bool GetBitmapFromImageList(CDC* pDC,CImageList *imglist,int nIndex,CBitmap &bmp);
bool ImageListDuplicate(CImageList *il,int xoffset,CImageList *newlist);
static WORD NumBitmapColors(LPBITMAPINFOHEADER lpBitmap);
void RemoveTopLevelOwnerDraw(void);
int GetMenuStart(void);
void GetTransparentBitmap(CBitmap &bmp);
void GetDisabledBitmap(CBitmap &bmp,COLORREF background=0);
INT_PTR AddToGlobalImageList(CImageList *il,int xoffset,int nID);
INT_PTR AddToGlobalImageList(int nIconNormal,int nID);
int GlobalImageListOffset(int nID);
// Member Variables
protected:
CTypedPtrArray<CPtrArray, BCMenuData*> m_MenuList; // Stores list of menu items
// When loading an owner-drawn menu using a Resource, BCMenu must keep track of
// the popup menu's that it creates. Warning, this list *MUST* be destroyed
// last item first :)
CTypedPtrArray<CPtrArray, HMENU> m_SubMenus; // Stores list of sub-menus
// Stores a list of all BCMenu's ever created
static CTypedPtrArray<CPtrArray, HMENU> m_AllSubMenus;
// Global ImageList
static CImageList m_AllImages;
static CArray<int,int&> m_AllImagesID;
// icon size
static int m_iconX;
static int m_iconY;
COLORREF m_bitmapBackground;
bool m_bitmapBackgroundFlag;
static bool hicolor_bitmaps;
bool m_loadmenu;
static MARGINS m_marginCheck;
static MARGINS m_marginSeparator;
static SIZE m_sizeCheck;
static SIZE m_sizeSeparator;
static int m_textBorder;
static int m_checkBgWidth;
static int m_gutterWidth;
static int m_arrowWidth;
static HTHEME m_hTheme;
};