-
Notifications
You must be signed in to change notification settings - Fork 0
/
BCMenu.h
329 lines (291 loc) · 27.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
//////////////////////////////////////////////////
//类名:BCMenu
//功能:具有XP风格的图标菜单
//修改人:徐景周(Johnny Xu, xujingzhou2016@gmail.com)
//组织:未来工作室(Future Studio)
//日期:2001.12.1
//////////////////////////////////////////////////
#ifndef BCMenu_H
#define BCMenu_H
#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=NULL;pContext=NULL;
nFlags=0;nID=0;syncflag=0;m_szMenuText=NULL;};
void SetAnsiString(LPCSTR szAnsiString);
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 xoffset;
int menuIconNormal;
UINT nFlags,nID,syncflag;
CImageList *bitmap;
void *pContext; // used to attach user data
};
//struct CMenuItemInfo : public MENUITEMINFO {
struct CMenuItemInfo : public
//MENUITEMINFO
#ifndef UNICODE //SK: this fixes warning C4097: typedef-name 'MENUITEMINFO' used as synonym for class-name 'tagMENUITEMINFOA'
tagMENUITEMINFOA
#else
tagMENUITEMINFOW
#endif
{
CMenuItemInfo()
{
memset(this, 0, sizeof(MENUITEMINFO));
cbSize = sizeof(MENUITEMINFO);
}
};
// how the menu's are drawn, either original or XP style
typedef enum {BCMENU_DRAWMODE_ORIGINAL,BCMENU_DRAWMODE_XP} BC_MenuDrawMode;
// 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
#else
#define AppendMenu AppendMenuW
#define InsertMenu InsertMenuW
#define InsertODMenu InsertODMenuW
#define AppendODMenu AppendODMenuW
#define ModifyODMenu ModifyODMenuW
#define AppendODPopupMenu AppendODPopupMenuW
#endif
class BCMenu : public CMenu
{
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);
void AddFromToolBar(CToolBar* pToolBar, int nResourceID);
BOOL LoadFromToolBar(UINT nID,UINT nToolBar,int& xoffset);
BOOL AddBitmapToImageList(CImageList *list,UINT nResourceID);
static HBITMAP LoadSysColorBitmap(int nResourceId);
void LoadCheckmarkBitmap(int unselect,int select); // custom check mark bitmaps
// functions for appending a menu option, use the AppendMenu call (see above define)
BOOL AppendMenuA(UINT nFlags,UINT nIDNewItem=0,const char *lpszNewItem=NULL,int nIconNormal=-1);
BOOL AppendMenuA(UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CImageList *il,int xoffset);
BOOL AppendMenuA(UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CBitmap *bmp);
BOOL AppendMenuW(UINT nFlags,UINT nIDNewItem=0,wchar_t *lpszNewItem=NULL,int nIconNormal=-1);
BOOL AppendMenuW(UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CImageList *il,int xoffset);
BOOL AppendMenuW(UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CBitmap *bmp);
BOOL AppendODMenuA(LPCSTR lpstrText,UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
BOOL AppendODMenuW(wchar_t *lpstrText,UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
BOOL AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT nID,CImageList *il,int xoffset);
BOOL AppendODMenuW(wchar_t *lpstrText,UINT nFlags,UINT nID,CImageList *il,int xoffset);
// for appending a popup menu (see example application)
BCMenu* AppendODPopupMenuA(LPCSTR lpstrText);
BCMenu* AppendODPopupMenuW(wchar_t *lpstrText);
// functions for inserting a menu option, use the InsertMenu call (see above define)
BOOL InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem=0,const char *lpszNewItem=NULL,int nIconNormal=-1);
BOOL InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CImageList *il,int xoffset);
BOOL InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CBitmap *bmp);
BOOL InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem=0,wchar_t *lpszNewItem=NULL,int nIconNormal=-1);
BOOL InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CImageList *il,int xoffset);
BOOL InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CBitmap *bmp);
BOOL InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
BOOL InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags = MF_OWNERDRAW,UINT nID = 0,int nIconNormal = -1);
BOOL InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT nID,CImageList *il,int xoffset);
BOOL InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT nID,CImageList *il,int xoffset);
// functions for modifying a menu option, use the ModifyODMenu call (see above define)
BOOL ModifyODMenuA(const char *lpstrText,UINT nID=0,int nIconNormal=-1);
BOOL ModifyODMenuA(const char *lpstrText,UINT nID,CImageList *il,int xoffset);
BOOL ModifyODMenuA(const char *lpstrText,UINT nID,CBitmap *bmp);
BOOL ModifyODMenuA(const char *lpstrText,const char *OptionText,int nIconNormal);
BOOL ModifyODMenuW(wchar_t *lpstrText,UINT nID=0,int nIconNormal=-1);
BOOL ModifyODMenuW(wchar_t *lpstrText,UINT nID,CImageList *il,int xoffset);
BOOL ModifyODMenuW(wchar_t *lpstrText,UINT nID,CBitmap *bmp);
BOOL ModifyODMenuW(wchar_t *lpstrText,wchar_t *OptionText,int nIconNormal);
// use this method for adding a solid/hatched colored square beside a menu option
// courtesy of Warren Stevens
BOOL ModifyODMenuA(const char *lpstrText,UINT nID,COLORREF fill,COLORREF border,int hatchstyle=-1);
BOOL ModifyODMenuW(wchar_t *lpstrText,UINT nID,COLORREF fill,COLORREF border,int hatchstyle=-1);
// 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=BCMENU_NONE);
int RemoveMenu(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
CMenu* GetSubMenu (LPCTSTR lpszSubMenuName);
CMenu* GetSubMenu (int nPos);
int GetMenuPosition(char* 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);
// Function to set how menu is drawn, either original or XP style
static void SetMenuDrawMode(UINT mode){
BCMenu::original_drawmode=mode;
BCMenu::xp_drawmode=mode;
};
// Function to set how disabled items are drawn (mode=FALSE means they are not drawn selected)
static void SetSelectDisableMode(BOOL mode){
BCMenu::original_select_disabled=mode;
BCMenu::xp_select_disabled=mode;
};
static int BCMenu::GetMenuDrawMode(void);
// Customizing:
// Set icon size
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
BOOL GetDisableOldStyle(void);
void SetDisableOldStyle(void);
void UnSetDisableOldStyle(void);
// Miscellaneous Protected Member functions
protected:
static BOOL IsNewShell(void);
BCMenuData *BCMenu::FindMenuItem(UINT nID);
BCMenu *FindMenuOption(int nId,int& nLoc);
BCMenu *FindAnotherMenuOption(int nId,int& nLoc,CArray<BCMenu*,BCMenu*>&bcsubs,
CArray<int,int&>&bclocs);
BCMenuData *FindMenuOption(wchar_t *lpstrText);
void InsertSpaces(void);
void DrawCheckMark(CDC *pDC,int x,int y,COLORREF color);
void DrawRadioDot(CDC *pDC,int x,int y,COLORREF color);
BCMenuData *NewODMenu(UINT pos,UINT nFlags,UINT nID,CString string);
void SynchronizeMenu(void);
void BCMenu::InitializeMenuList(int value);
void BCMenu::DeleteMenuList(void);
BCMenuData *BCMenu::FindMenuList(UINT nID);
void DrawItem_Win9xNT2000 (LPDRAWITEMSTRUCT lpDIS);
void DrawItem_WinXP (LPDRAWITEMSTRUCT lpDIS);
BOOL Draw3DCheckmark(CDC *dc, const CRect& rc,BOOL bSelected,HBITMAP hbmCheck);
BOOL DrawXPCheckmark(CDC *dc, const CRect& rc, HBITMAP hbmCheck,COLORREF &colorout);
void DitherBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth,
int nHeight, HBITMAP hbm, int nXSrc, int nYSrc,COLORREF bgcolor);
void DitherBlt2(CDC *drawdc, int nXDest, int nYDest, int nWidth,
int nHeight, CBitmap &bmp, int nXSrc, int nYSrc,COLORREF bgcolor);
BOOL GetBitmapFromImageList(CDC* pDC,CImageList *imglist,int nIndex,CBitmap &bmp);
BOOL ImageListDuplicate(CImageList *il,int xoffset,CImageList *newlist);
static COLORREF LightenColor(COLORREF col,double factor);
static WORD NumBitmapColors(LPBITMAPINFOHEADER lpBitmap);
void ColorBitmap(CDC* pDC, CBitmap& bmp,CSize size,COLORREF fill,COLORREF border,int hatchstyle=-1);
// 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;
int m_iconX,m_iconY;
COLORREF m_bitmapBackground;
BOOL m_bitmapBackgroundFlag;
BOOL disable_old_style;
static UINT original_drawmode,xp_drawmode;
static BOOL xp_select_disabled,original_select_disabled;
CImageList *checkmaps;
BOOL checkmapsshare;
int m_selectcheck;
int m_unselectcheck;
BOOL m_bDynIcons;
};
#define BCMENU_USE_MEMDC
#ifdef BCMENU_USE_MEMDC
//////////////////////////////////////////////////
// BCMenuMemDC - memory DC
//
// Author: Keith Rule
// Email: keithr@europa.com
// Copyright 1996-1997, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// History - 10/3/97 Fixed scrolling bug.
// Added print support.
// 25 feb 98 - fixed minor assertion bug
//
// This class implements a memory Device Context
class BCMenuMemDC : public CDC
{
public:
// constructor sets up the memory DC
BCMenuMemDC(CDC* pDC,LPCRECT lpSrcRect) : CDC()
{
ASSERT(pDC != NULL);
m_rect.CopyRect(lpSrcRect);
m_pDC = pDC;
m_pOldBitmap = NULL;
m_bMemDC = !pDC->IsPrinting();
if (m_bMemDC) // Create a Memory DC
{
CreateCompatibleDC(pDC);
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
m_pOldBitmap = SelectObject(&m_bitmap);
SetWindowOrg(m_rect.left, m_rect.top);
}
else // Make a copy of the relevent parts of the current DC for printing
{
m_bPrinting = pDC->m_bPrinting;
m_hDC = pDC->m_hDC;
m_hAttribDC = pDC->m_hAttribDC;
}
}
// Destructor copies the contents of the mem DC to the original DC
~BCMenuMemDC()
{
if (m_bMemDC)
{
// Copy the offscreen bitmap onto the screen.
m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
this, m_rect.left, m_rect.top, SRCCOPY);
//Swap back the original bitmap.
SelectObject(m_pOldBitmap);
} else {
// All we need to do is replace the DC with an illegal value,
// this keeps us from accidently deleting the handles associated with
// the CDC that was passed to the constructor.
m_hDC = m_hAttribDC = NULL;
}
}
// Allow usage as a pointer
BCMenuMemDC* operator->() {return this;}
// Allow usage as a pointer
operator BCMenuMemDC*() {return this;}
private:
CBitmap m_bitmap; // Offscreen bitmap
CBitmap* m_pOldBitmap; // bitmap originally found in BCMenuMemDC
CDC* m_pDC; // Saves CDC passed in constructor
CRect m_rect; // Rectangle of drawing area.
BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.
};
#endif
#endif
//*************************************************************************