comparison host/tools/configtool/standalone/win32/BCMenu.cpp @ 76:435cced73e2f ecos-v1_3_1-release

eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
author jlarmour
date Tue, 28 Mar 2000 14:10:45 +0000
parents
children 74dbf4c3f2e1
comparison
equal deleted inserted replaced
75:41bf073c0c32 76:435cced73e2f
1 //####COPYRIGHTBEGIN####
2 //
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
8 // This program is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the Free
10 // Software Foundation; either version 2 of the License, or (at your option)
11 // any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 // more details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc.,
20 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 //
22 // ----------------------------------------------------------------------------
23 //
24 //####COPYRIGHTEND####
25
26 //#####DESCRIPTIONBEGIN####
27 //
28 //*************************************************************************
29 // BCMenu.cpp : implementation file
30 // Version : 2.63
31 // Date : December 2, 1999
32 // Author : Brent Corkum
33 // Email : corkum@rocscience.com
34 // Latest Version : http://www.rocscience.com/~corkum/BCMenu.html
35 //
36 // Bug Fixes and portions of code supplied by:
37 //
38 // Ben Ashley,Girish Bharadwaj,Jean-Edouard Lachand-Robert,
39 // Robert Edward Caldecott,Kenny Goers,Leonardo Zide,
40 // Stefan Kuhr,Reiner Jung,Martin Vladic,Kim Yoo Chul,
41 // Oz Solomonovich
42 //
43 // You are free to use/modify this code but leave this header intact.
44 // This class is public domain so you are free to use it any of
45 // your applications (Freeware,Shareware,Commercial). All I ask is
46 // that you let me know so that if you have a real winner I can
47 // brag to my buddies that some of my code is in your app. I also
48 // wouldn't mind if you sent me a copy of your application since I
49 // like to play with new stuff.
50 //*************************************************************************
51 //####DESCRIPTIONEND####
52 //==========================================================================
53
54 #include "stdafx.h" // Standard windows header file
55 #include "BCMenu.h" // BCMenu class declaration
56 #include <afxpriv.h> //SK: makes A2W and other spiffy AFX macros work
57
58 #ifdef _DEBUG
59 #define new DEBUG_NEW
60 #undef THIS_FILE
61 static char THIS_FILE[] = __FILE__;
62 #endif
63
64 #define GAP 1
65 #ifndef OBM_CHECK
66 #define OBM_CHECK 32760 // from winuser.h
67 #endif
68
69 #if _MFC_VER <0x400
70 #error This code does not work on Versions of MFC prior to 4.0
71 #endif
72
73 static CPINFO CPInfo;
74
75 enum Win32Type{
76 Win32s,
77 Windoze95,
78 WinNT3,
79 WinNT4orHigher
80 };
81
82
83 Win32Type IsShellType()
84 {
85 Win32Type ShellType;
86 DWORD winVer;
87 OSVERSIONINFO *osvi;
88
89 winVer=GetVersion();
90 if(winVer<0x80000000){/*NT */
91 ShellType=WinNT3;
92 osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
93 if (osvi!=NULL){
94 memset(osvi,0,sizeof(OSVERSIONINFO));
95 osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
96 GetVersionEx(osvi);
97 if (osvi->dwMajorVersion>=4L)
98 ShellType=WinNT4orHigher;//yup, it is NT 4 or higher!
99 free(osvi);
100 }
101 }
102 else if (LOBYTE(LOWORD(winVer))<4)
103 ShellType=Win32s;/*Win32s*/
104 else
105 ShellType=Windoze95;/*Windoze95*/
106 return ShellType;
107 }
108
109 static Win32Type g_Shell=IsShellType();
110
111 void BCMenuData::SetAnsiString(LPCSTR szAnsiString)
112 {
113 USES_CONVERSION;
114 SetWideString(A2W(szAnsiString)); //SK: see MFC Tech Note 059
115 }
116
117 CString BCMenuData::GetString(void)//returns the menu text in ANSI or UNICODE
118 //depending on the MFC-Version we are using
119 {
120 CString strText;
121 if (m_szMenuText)
122 {
123 #ifdef UNICODE
124 strText = m_szMenuText;
125 #else
126 USES_CONVERSION;
127 strText=W2A(m_szMenuText); //SK: see MFC Tech Note 059
128 #endif
129 }
130 return strText;
131 }
132
133 CTypedPtrArray<CPtrArray, HMENU> BCMenu::m_AllSubMenus; // Stores list of all sub-menus
134
135 /*
136
137 ===============================================================================
138 BCMenu::BCMenu()
139 TCMeny::~BCMenu()
140 -----------------
141
142 Constructor and Destructor.
143
144 ===============================================================================
145 */
146
147 BCMenu::BCMenu()
148 {
149 m_bDynIcons = FALSE; // O.S. - no dynamic icons by default
150 disable_old_style=FALSE;
151 m_iconX = 16; // Icon sizes default to 16 x 16
152 m_iconY = 15; // ...
153 m_selectcheck = -1;
154 m_unselectcheck = -1;
155 checkmaps=NULL;
156 checkmapsshare=FALSE;
157 // set the color used for the transparent background in all bitmaps
158 m_bitmapBackground=RGB(192,192,192); //gray
159 m_bitmapBackgroundFlag=FALSE;
160 GetCPInfo(CP_ACP,&CPInfo);
161 }
162
163
164 BCMenu::~BCMenu()
165 {
166 DestroyMenu();
167 }
168
169 BOOL BCMenu::IsNewShell ()
170 {
171 return (Windoze95==g_Shell || WinNT4orHigher==g_Shell);
172 }
173
174
175 BCMenuData::~BCMenuData()
176 {
177 if(bitmap)
178 delete(bitmap);
179
180 delete[] m_szMenuText; //Need not check for NULL because ANSI X3J16 allows "delete NULL"
181 }
182
183
184 void BCMenuData::SetWideString(const wchar_t *szWideString)
185 {
186 delete[] m_szMenuText;//Need not check for NULL because ANSI X3J16 allows "delete NULL"
187
188 if (szWideString)
189 {
190 m_szMenuText = new wchar_t[sizeof(wchar_t)*(wcslen(szWideString)+1)];
191 if (m_szMenuText)
192 wcscpy(m_szMenuText,szWideString);
193 }
194 else
195 m_szMenuText=NULL;//set to NULL so we need not bother about dangling non-NULL Ptrs
196 }
197
198 BOOL BCMenu::IsMenu(CMenu *submenu)
199 {
200 int m;
201 int numSubMenus = m_AllSubMenus.GetUpperBound();
202 for(m=0;m<=numSubMenus;++m){
203 if(submenu->m_hMenu==m_AllSubMenus[m])return(TRUE);
204 }
205 return(FALSE);
206 }
207
208 BOOL BCMenu::IsMenu(HMENU submenu)
209 {
210 int m;
211 int numSubMenus = m_AllSubMenus.GetUpperBound();
212 for(m=0;m<=numSubMenus;++m){
213 if(submenu==m_AllSubMenus[m])return(TRUE);
214 }
215 return(FALSE);
216 }
217
218 BOOL BCMenu::DestroyMenu()
219 {
220 // Destroy Sub menus:
221 int m,n;
222 int numAllSubMenus = m_AllSubMenus.GetUpperBound();
223 for(n = numAllSubMenus; n>= 0; n--){
224 if(m_AllSubMenus[n]==this->m_hMenu)m_AllSubMenus.RemoveAt(n);
225 }
226 int numSubMenus = m_SubMenus.GetUpperBound();
227 for(m = numSubMenus; m >= 0; m--){
228 numAllSubMenus = m_AllSubMenus.GetUpperBound();
229 for(n = numAllSubMenus; n>= 0; n--){
230 if(m_AllSubMenus[n]==m_SubMenus[m])m_AllSubMenus.RemoveAt(n);
231 }
232 delete((BCMenu *)FromHandle(m_SubMenus[m]));
233 }
234 m_SubMenus.RemoveAll();
235 // Destroy menu data
236 int numItems = m_MenuList.GetUpperBound();
237 for(m = 0; m <= numItems; m++)delete(m_MenuList[m]);
238 m_MenuList.RemoveAll();
239 if(checkmaps&&!checkmapsshare){
240 delete checkmaps;
241 checkmaps=NULL;
242 }
243 // Call base-class implementation last:
244 return(CMenu::DestroyMenu());
245 };
246
247
248 ///////////////////////////////////////////////////////////////////////////
249 //
250 // BCMenu message handlers
251
252
253 /*
254 ==========================================================================
255 void BCMenu::DrawItem(LPDRAWITEMSTRUCT)
256 ---------------------------------------
257
258 Called by the framework when a particular item needs to be drawn. We
259 overide this to draw the menu item in a custom-fashion, including icons
260 and the 3D rectangle bar.
261 ==========================================================================
262 */
263
264
265 void BCMenu::DrawItem (LPDRAWITEMSTRUCT lpDIS)
266 {
267 ASSERT(lpDIS != NULL);
268 CDC* pDC = CDC::FromHandle(lpDIS->hDC);
269 CRect rect;
270 UINT state = (((BCMenuData*)(lpDIS->itemData))->nFlags);
271 if(state & MF_SEPARATOR){
272 rect.CopyRect(&lpDIS->rcItem);
273 rect.top+=rect.Height()>>1;
274 pDC->DrawEdge(&rect,EDGE_ETCHED,BF_TOP);
275 }
276 else{
277 CRect rect2;
278 BOOL standardflag=FALSE,selectedflag=FALSE,disableflag=FALSE;
279 BOOL checkflag=FALSE;
280 COLORREF crText = GetSysColor(COLOR_MENUTEXT);
281 COLORREF m_clrBack=GetSysColor(COLOR_MENU);
282 CBrush m_brBackground,m_brSelect;
283 CPen m_penBack;
284 int x0,y0,dy;
285 int nIconNormal=-1,xoffset=-1;
286 CImageList *bitmap=NULL;
287 CFont m_fontMenu;
288 LOGFONT m_lf;
289
290 // set some colors and the font
291 m_penBack.CreatePen (PS_SOLID,0,GetSysColor(COLOR_MENU));
292 m_brBackground.CreateSolidBrush(GetSysColor(COLOR_MENU));
293 m_brSelect.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
294 ZeroMemory ((PVOID) &m_lf,sizeof (LOGFONT));
295 NONCLIENTMETRICS nm;
296 nm.cbSize = sizeof (NONCLIENTMETRICS);
297 VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
298 m_lf = nm.lfMenuFont;
299 m_fontMenu.CreateFontIndirect (&m_lf);
300
301 // draw the colored rectangle portion
302
303 rect.CopyRect(&lpDIS->rcItem);
304 rect2=rect;
305
306 // draw the up/down/focused/disabled state
307
308 UINT state = lpDIS->itemState;
309 CString strText;
310 LOGFONT lf;
311 lf = m_lf;
312
313 CFont dispFont;
314 CFont *pFont=NULL;
315
316 if(lpDIS->itemData != NULL){
317 nIconNormal = (((BCMenuData*)(lpDIS->itemData))->menuIconNormal);
318 xoffset = (((BCMenuData*)(lpDIS->itemData))->xoffset);
319 bitmap = (((BCMenuData*)(lpDIS->itemData))->bitmap);
320 strText = ((BCMenuData*) (lpDIS->itemData))->GetString();
321
322 if(state&ODS_CHECKED && nIconNormal<0){
323 if(state&ODS_SELECTED && m_selectcheck>0)checkflag=TRUE;
324 else if(m_unselectcheck>0) checkflag=TRUE;
325 }
326 else if(nIconNormal != -1){
327 standardflag=TRUE;
328 if(state&ODS_SELECTED && !(state&ODS_GRAYED))selectedflag=TRUE;
329 else if(state&ODS_GRAYED) disableflag=TRUE;
330 }
331 }
332 else{
333 strText.Empty();
334 }
335
336 if(state&ODS_SELECTED){ // draw the down edges
337
338 CPen *pOldPen = pDC->SelectObject (&m_penBack);
339
340 // You need only Text highlight and thats what you get
341
342 if(checkflag||standardflag||selectedflag||disableflag||state&ODS_CHECKED)
343 rect2.SetRect(rect.left+m_iconX+4+GAP,rect.top,rect.right,rect.bottom);
344 pDC->FillRect (rect2,&m_brSelect);
345
346 pDC->SelectObject (pOldPen);
347 if((HFONT)dispFont != NULL)dispFont.DeleteObject ();
348 dispFont.CreateFontIndirect (&lf);
349 crText = GetSysColor(COLOR_HIGHLIGHTTEXT);
350 }
351 else {
352 CPen *pOldPen = pDC->SelectObject (&m_penBack);
353 pDC->FillRect (rect,&m_brBackground);
354 pDC->SelectObject (pOldPen);
355
356 // draw the up edges
357
358 pDC->Draw3dRect (rect,m_clrBack,m_clrBack);
359 if ((HFONT)dispFont != NULL) dispFont.DeleteObject ();
360 dispFont.CreateFontIndirect (&lf); //Normal
361 }
362
363 // draw the text if there is any
364 //We have to paint the text only if the image is nonexistant
365
366 dy = (rect.Height()-4-m_iconY)/2;
367 dy = dy<0 ? 0 : dy;
368
369 if(checkflag||standardflag||selectedflag||disableflag){
370 rect2.SetRect(rect.left+1,rect.top+1+dy,rect.left+m_iconX+3,
371 rect.top+m_iconY+3+dy);
372 pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
373 if(checkflag && checkmaps){
374 pDC->FillRect (rect2,&m_brBackground);
375 rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
376 rect.top+m_iconY+4+dy);
377
378 pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
379 CPoint ptImage(rect.left+2,rect.top+2+dy);
380
381 if(state&ODS_SELECTED)checkmaps->Draw(pDC,1,ptImage,ILD_TRANSPARENT);
382 else checkmaps->Draw(pDC,0,ptImage,ILD_TRANSPARENT);
383 }
384 else if(disableflag){
385 if(!selectedflag){
386 CBitmap bitmapstandard;
387 GetBitmapFromImageList(pDC,bitmap,xoffset,bitmapstandard);
388 rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
389 rect.top+m_iconY+4+dy);
390 pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
391 if(disable_old_style)
392 DitherBlt(lpDIS->hDC,rect.left+2,rect.top+2+dy,m_iconX,m_iconY,
393 (HBITMAP)(bitmapstandard),0,0);
394 else
395 DitherBlt2(pDC,rect.left+2,rect.top+2+dy,m_iconX,m_iconY,
396 bitmapstandard,0,0);
397 bitmapstandard.DeleteObject();
398 }
399 }
400 else if(selectedflag){
401 pDC->FillRect (rect2,&m_brBackground);
402 rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
403 rect.top+m_iconY+4+dy);
404 if (IsNewShell()){
405 if(state&ODS_CHECKED)
406 pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),
407 GetSysColor(COLOR_3DHILIGHT));
408 else
409 pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DHILIGHT),
410 GetSysColor(COLOR_3DSHADOW));
411 }
412 CPoint ptImage(rect.left+2,rect.top+2+dy);
413 if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
414 }
415 else{
416 if(state&ODS_CHECKED){
417 CBrush brush;
418 COLORREF col =GetSysColor(COLOR_3DLIGHT);
419 brush.CreateSolidBrush(col);
420 pDC->FillRect(rect2,&brush);
421 brush.DeleteObject();
422 rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
423 rect.top+m_iconY+4+dy);
424 if (IsNewShell())
425 pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),
426 GetSysColor(COLOR_3DHILIGHT));
427 }
428 else{
429 pDC->FillRect (rect2,&m_brBackground);
430 rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
431 rect.top+m_iconY+4+dy);
432 pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
433 }
434 CPoint ptImage(rect.left+2,rect.top+2+dy);
435 if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
436 }
437 }
438 if(nIconNormal<0 && state&ODS_CHECKED && !checkflag){
439 rect2.SetRect(rect.left+1,rect.top+2+dy,rect.left+m_iconX+1,
440 rect.top+m_iconY+2+dy);
441 CMenuItemInfo info;
442 info.fMask = MIIM_CHECKMARKS;
443 ::GetMenuItemInfo((HMENU)lpDIS->hwndItem,lpDIS->itemID,
444 MF_BYCOMMAND, &info);
445 if(state&ODS_CHECKED || info.hbmpUnchecked) {
446 Draw3DCheckmark(pDC, rect2, state&ODS_SELECTED,
447 state&ODS_CHECKED ? info.hbmpChecked :
448 info.hbmpUnchecked);
449 }
450 }
451
452 //This is needed always so that we can have the space for check marks
453
454 x0=rect.left;y0=rect.top;
455 rect.left = rect.left + m_iconX + 8 + GAP;
456
457 if(!strText.IsEmpty()){
458
459 CRect rectt(rect.left,rect.top-1,rect.right,rect.bottom-1);
460
461 // Find tabs
462
463 CString leftStr,rightStr;
464 leftStr.Empty();rightStr.Empty();
465 int tablocr=strText.ReverseFind(_T('\t'));
466 if(tablocr!=-1){
467 rightStr=strText.Mid(tablocr+1);
468 leftStr=strText.Left(strText.Find(_T('\t')));
469 rectt.right-=m_iconX;
470 }
471 else leftStr=strText;
472
473 int iOldMode = pDC->GetBkMode();
474 pDC->SetBkMode( TRANSPARENT);
475
476 // Draw the text in the correct colour:
477
478 UINT nFormat = DT_LEFT|DT_SINGLELINE|DT_VCENTER;
479 UINT nFormatr = DT_RIGHT|DT_SINGLELINE|DT_VCENTER;
480 if(!(lpDIS->itemState & ODS_GRAYED)){
481 pDC->SetTextColor(crText);
482 pDC->DrawText (leftStr,rectt,nFormat);
483 if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
484 }
485 else{
486
487 // Draw the disabled text
488 if(!(state & ODS_SELECTED)){
489 RECT offset = *rectt;
490 offset.left+=1;
491 offset.right+=1;
492 offset.top+=1;
493 offset.bottom+=1;
494 pDC->SetTextColor(GetSysColor(COLOR_BTNHILIGHT));
495 pDC->DrawText(leftStr,&offset, nFormat);
496 if(tablocr!=-1) pDC->DrawText (rightStr,&offset,nFormatr);
497 pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
498 pDC->DrawText(leftStr,rectt, nFormat);
499 if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
500 }
501 else{
502 // And the standard Grey text:
503 pDC->SetTextColor(m_clrBack);
504 pDC->DrawText(leftStr,rectt, nFormat);
505 if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
506 }
507 }
508 pFont = pDC->SelectObject (&dispFont);
509 pDC->SetBkMode( iOldMode );
510 pDC->SelectObject (pFont); //set it to the old font
511 }
512
513 m_penBack.DeleteObject();
514 m_brBackground.DeleteObject();
515 m_fontMenu.DeleteObject();
516 m_brSelect.DeleteObject();
517 dispFont.DeleteObject ();
518 }
519 }
520
521 BOOL BCMenu::GetBitmapFromImageList(CDC* pDC,CImageList *imglist,int nIndex,CBitmap &bmp)
522 {
523 HICON hIcon = imglist->ExtractIcon(nIndex);
524 CDC dc;
525 dc.CreateCompatibleDC(pDC);
526 bmp.CreateCompatibleBitmap(pDC,m_iconX,m_iconY);
527 CBitmap* pOldBmp = dc.SelectObject(&bmp);
528 CBrush brush ;
529 brush.CreateSolidBrush(GetSysColor(COLOR_MENU));
530 ::DrawIconEx(
531 dc.GetSafeHdc(),
532 0,
533 0,
534 hIcon,
535 m_iconX,
536 m_iconY,
537 0,
538 (HBRUSH)brush,
539 DI_NORMAL
540 );
541 dc.SelectObject( pOldBmp );
542 dc.DeleteDC();
543 // the icon is not longer needed
544 DestroyIcon(hIcon);
545 return(TRUE);
546 }
547
548 /*
549 ==========================================================================
550 void BCMenu::MeasureItem(LPMEASUREITEMSTRUCT)
551 ---------------------------------------------
552
553 Called by the framework when it wants to know what the width and height
554 of our item will be. To accomplish this we provide the width of the
555 icon plus the width of the menu text, and then the height of the icon.
556
557 ==========================================================================
558 */
559
560 void BCMenu::MeasureItem( LPMEASUREITEMSTRUCT lpMIS )
561 {
562 UINT state = (((BCMenuData*)(lpMIS->itemData))->nFlags);
563 if(state & MF_SEPARATOR){
564 lpMIS->itemWidth = 0;
565 lpMIS->itemHeight = GetSystemMetrics(SM_CYMENU)>>1;
566 }
567 else{
568 CFont m_fontMenu;
569 LOGFONT m_lf;
570 ZeroMemory ((PVOID) &m_lf,sizeof (LOGFONT));
571 NONCLIENTMETRICS nm;
572 nm.cbSize = sizeof (NONCLIENTMETRICS);
573 VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
574 nm.cbSize,&nm,0));
575 m_lf = nm.lfMenuFont;
576 m_fontMenu.CreateFontIndirect (&m_lf);
577
578 // Obtain the width of the text:
579 CWnd *pWnd = AfxGetMainWnd(); // Get main window
580 CDC *pDC = pWnd->GetDC(); // Get device context
581 CFont* pFont=NULL; // Select menu font in...
582
583 if (IsNewShell())
584 pFont = pDC->SelectObject (&m_fontMenu);// Select menu font in...
585
586 //Get pointer to text SK
587 const wchar_t *lpstrText = ((BCMenuData*)(lpMIS->itemData))->GetWideString();//SK: we use const to prevent misuse
588
589
590 SIZE size;
591
592 if (Win32s!=g_Shell)
593 VERIFY(::GetTextExtentPoint32W(pDC->m_hDC,lpstrText,
594 wcslen(lpstrText),&size)); //SK should also work on 95
595 #ifndef UNICODE //can't be UNICODE for Win32s
596 else{//it's Win32suckx
597 RECT rect;
598 rect.left=rect.top=0;
599 size.cy=DrawText(pDC->m_hDC,(LPCTSTR)lpstrText,
600 wcslen(lpstrText),&rect,
601 DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_CALCRECT);
602 //+3 makes at least three pixels space to the menu border
603 size.cx=rect.right-rect.left+3;
604 size.cx += 3*(size.cx/wcslen(lpstrText));
605 }
606 #endif
607
608 CSize t = CSize(size);
609 if(IsNewShell())
610 pDC->SelectObject (pFont); // Select old font in
611 AfxGetMainWnd()->ReleaseDC(pDC); // Release the DC
612
613 // Set width and height:
614
615 lpMIS->itemWidth = m_iconX + t.cx + m_iconX + GAP;
616 int temp = GetSystemMetrics(SM_CYMENU);
617 lpMIS->itemHeight = temp>m_iconY+4 ? temp : m_iconY+4;
618 m_fontMenu.DeleteObject();
619 }
620 }
621
622 void BCMenu::SetIconSize (int width, int height)
623 {
624 m_iconX = width;
625 m_iconY = height;
626 }
627
628 BOOL BCMenu::AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT nID,
629 int nIconNormal)
630 {
631 USES_CONVERSION;
632 return AppendODMenuW(A2W(lpstrText),nFlags,nID,nIconNormal);//SK: See MFC Tech Note 059
633 }
634
635
636 BOOL BCMenu::AppendODMenuW(wchar_t *lpstrText,UINT nFlags,UINT nID,
637 int nIconNormal)
638 {
639 // Add the MF_OWNERDRAW flag if not specified:
640 if(!nID){
641 if(nFlags&MF_BYPOSITION)nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
642 else nFlags=MF_SEPARATOR|MF_OWNERDRAW;
643 }
644 else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
645
646 if(nFlags & MF_POPUP){
647 m_AllSubMenus.Add((HMENU)nID);
648 m_SubMenus.Add((HMENU)nID);
649 }
650
651 BCMenuData *mdata = new BCMenuData;
652 m_MenuList.Add(mdata);
653 mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
654
655 mdata->menuIconNormal = nIconNormal;
656 mdata->xoffset=-1;
657 if(nIconNormal>=0){
658 mdata->xoffset=0;
659 LoadFromToolBar(nID,nIconNormal,mdata->xoffset);
660 if(mdata->bitmap)mdata->bitmap->DeleteImageList();
661 else mdata->bitmap=new(CImageList);
662 mdata->bitmap->Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
663 if(!AddBitmapToImageList(mdata->bitmap,nIconNormal)){
664 mdata->bitmap->DeleteImageList();
665 delete mdata->bitmap;
666 mdata->bitmap=NULL;
667 mdata->menuIconNormal = nIconNormal = -1;
668 mdata->xoffset = -1;
669 }
670 }
671 mdata->nFlags = nFlags;
672 mdata->nID = nID;
673 return(CMenu::AppendMenu(nFlags, nID, (LPCTSTR)mdata));
674 }
675
676 BOOL BCMenu::AppendODMenuA(LPCSTR lpstrText,UINT nFlags,UINT nID,
677 CImageList *il,int xoffset)
678 {
679 USES_CONVERSION;
680 return AppendODMenuW(A2W(lpstrText),nFlags,nID,il,xoffset);
681 }
682
683 BOOL BCMenu::AppendODMenuW(wchar_t *lpstrText,UINT nFlags,UINT nID,
684 CImageList *il,int xoffset)
685 {
686 // Add the MF_OWNERDRAW flag if not specified:
687 if(!nID){
688 if(nFlags&MF_BYPOSITION)nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
689 else nFlags=MF_SEPARATOR|MF_OWNERDRAW;
690 }
691 else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
692
693 if(nFlags & MF_POPUP){
694 m_AllSubMenus.Add((HMENU)nID);
695 m_SubMenus.Add((HMENU)nID);
696 }
697
698 BCMenuData *mdata = new BCMenuData;
699 m_MenuList.Add(mdata);
700 mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
701
702 if(il){
703 mdata->menuIconNormal = 0;
704 mdata->xoffset=0;
705 if(mdata->bitmap)mdata->bitmap->DeleteImageList();
706 else mdata->bitmap=new(CImageList);
707 ImageListDuplicate(il,xoffset,mdata->bitmap);
708 }
709 else{
710 mdata->menuIconNormal = -1;
711 mdata->xoffset = -1;
712 }
713 mdata->nFlags = nFlags;
714 mdata->nID = nID;
715 return(CMenu::AppendMenu(nFlags, nID, (LPCTSTR)mdata));
716 }
717
718 BOOL BCMenu::InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT nID,
719 int nIconNormal)
720 {
721 USES_CONVERSION;
722 return InsertODMenuW(nPosition,A2W(lpstrText),nFlags,nID,nIconNormal);
723 }
724
725
726 BOOL BCMenu::InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT nID,
727 int nIconNormal)
728 {
729 if(!(nFlags & MF_BYPOSITION)){
730 int iPosition =0;
731 BCMenu* pMenu = FindMenuOption(nPosition,iPosition);
732 if(pMenu){
733 return(pMenu->InsertODMenuW(iPosition,lpstrText,nFlags|MF_BYPOSITION,nID,nIconNormal));
734 }
735 else return(FALSE);
736 }
737
738 if(!nID)nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
739 else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
740
741 if(nFlags & MF_POPUP){
742 m_AllSubMenus.Add((HMENU)nID);
743 m_SubMenus.InsertAt(nPosition,(HMENU)nID);
744 }
745
746 BCMenuData *mdata = new BCMenuData;
747 m_MenuList.InsertAt(nPosition,mdata);
748 mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
749
750 mdata->menuIconNormal = nIconNormal;
751 mdata->xoffset=-1;
752 if(nIconNormal>=0){
753 mdata->xoffset=0;
754 LoadFromToolBar(nID,nIconNormal,mdata->xoffset);
755 if(mdata->bitmap)mdata->bitmap->DeleteImageList();
756 else mdata->bitmap=new(CImageList);
757 mdata->bitmap->Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
758 if(!AddBitmapToImageList(mdata->bitmap,nIconNormal)){
759 mdata->bitmap->DeleteImageList();
760 delete mdata->bitmap;
761 mdata->bitmap=NULL;
762 mdata->menuIconNormal = nIconNormal = -1;
763 mdata->xoffset = -1;
764 }
765 }
766 mdata->nFlags = nFlags;
767 mdata->nID = nID;
768 return(CMenu::InsertMenu(nPosition,nFlags,nID,(LPCTSTR)mdata));
769 }
770
771 BOOL BCMenu::InsertODMenuA(UINT nPosition,LPCSTR lpstrText,UINT nFlags,UINT nID,
772 CImageList *il,int xoffset)
773 {
774 USES_CONVERSION;
775 return InsertODMenuW(nPosition,A2W(lpstrText),nFlags,nID,il,xoffset);
776 }
777
778 BOOL BCMenu::InsertODMenuW(UINT nPosition,wchar_t *lpstrText,UINT nFlags,UINT nID,
779 CImageList *il,int xoffset)
780 {
781 if(!(nFlags & MF_BYPOSITION)){
782 int iPosition =0;
783 BCMenu* pMenu = FindMenuOption(nPosition,iPosition);
784 if(pMenu){
785 return(pMenu->InsertODMenuW(iPosition,lpstrText,nFlags|MF_BYPOSITION,nID,il,xoffset));
786 }
787 else return(FALSE);
788 }
789
790 if(!nID)nFlags=MF_SEPARATOR|MF_OWNERDRAW|MF_BYPOSITION;
791 else if(!(nFlags & MF_OWNERDRAW))nFlags |= MF_OWNERDRAW;
792
793 if(nFlags & MF_POPUP){
794 m_AllSubMenus.Add((HMENU)nID);
795 m_SubMenus.InsertAt(nPosition,(HMENU)nID);
796 }
797
798 BCMenuData *mdata = new BCMenuData;
799 m_MenuList.InsertAt(nPosition,mdata);
800 mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
801
802 if(il){
803 mdata->menuIconNormal = 0;
804 mdata->xoffset=0;
805 if(mdata->bitmap)mdata->bitmap->DeleteImageList();
806 else mdata->bitmap=new(CImageList);
807 ImageListDuplicate(il,xoffset,mdata->bitmap);
808 }
809 else{
810 mdata->menuIconNormal = -1;
811 mdata->xoffset = -1;
812 }
813 mdata->nFlags = nFlags;
814 mdata->nID = nID;
815 return(CMenu::InsertMenu(nPosition,nFlags,nID,(LPCTSTR)mdata));
816 }
817
818 BOOL BCMenu::ModifyODMenuA(const char * lpstrText,UINT nID,int nIconNormal)
819 {
820 USES_CONVERSION;
821 return ModifyODMenuW(A2W(lpstrText),nID,nIconNormal);//SK: see MFC Tech Note 059
822 }
823
824 BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,UINT nID,int nIconNormal)
825 {
826 int nLoc;
827 BCMenuData *mdata;
828
829 // Find the old BCMenuData structure:
830 BCMenu *psubmenu = FindMenuOption(nID,nLoc);
831 if(psubmenu && nLoc>=0)mdata = psubmenu->m_MenuList[nLoc];
832 else{
833 // Create a new BCMenuData structure:
834 mdata = new BCMenuData;
835 m_MenuList.Add(mdata);
836 }
837
838 ASSERT(mdata);
839 if(lpstrText)
840 mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
841 mdata->menuIconNormal = nIconNormal;
842 mdata->xoffset=-1;
843 if(nIconNormal>=0){
844 mdata->xoffset=0;
845 LoadFromToolBar(nID,nIconNormal,mdata->xoffset);
846 if(mdata->bitmap)mdata->bitmap->DeleteImageList();
847 else mdata->bitmap=new CImageList;
848 mdata->bitmap->Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
849 if(!AddBitmapToImageList(mdata->bitmap,nIconNormal)){
850 mdata->bitmap->DeleteImageList();
851 delete mdata->bitmap;
852 mdata->bitmap=NULL;
853 mdata->menuIconNormal = nIconNormal = -1;
854 mdata->xoffset = -1;
855 }
856 }
857 mdata->nFlags = MF_BYCOMMAND | MF_OWNERDRAW;
858 mdata->nID = nID;
859 return (CMenu::ModifyMenu(nID,mdata->nFlags,nID,(LPCTSTR)mdata));
860 }
861
862 BOOL BCMenu::ModifyODMenuA(const char * lpstrText,UINT nID,CImageList *il,int xoffset)
863 {
864 USES_CONVERSION;
865 return ModifyODMenuW(A2W(lpstrText),nID,il,xoffset);
866 }
867
868 BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,UINT nID,CImageList *il,int xoffset)
869 {
870 int nLoc;
871 BCMenuData *mdata;
872
873 // Find the old BCMenuData structure:
874 BCMenu *psubmenu = FindMenuOption(nID,nLoc);
875 if(psubmenu && nLoc>=0)mdata = psubmenu->m_MenuList[nLoc];
876 else{
877 // Create a new BCMenuData structure:
878 mdata = new BCMenuData;
879 m_MenuList.Add(mdata);
880 }
881
882 ASSERT(mdata);
883 if(lpstrText)
884 mdata->SetWideString(lpstrText); //SK: modified for dynamic allocation
885 if(il){
886 mdata->menuIconNormal = 0;
887 mdata->xoffset=0;
888 if(mdata->bitmap)mdata->bitmap->DeleteImageList();
889 else mdata->bitmap=new(CImageList);
890 ImageListDuplicate(il,xoffset,mdata->bitmap);
891 }
892 else{
893 mdata->menuIconNormal = -1;
894 mdata->xoffset = -1;
895 }
896 mdata->nFlags = MF_BYCOMMAND | MF_OWNERDRAW;
897 mdata->nID = nID;
898 return (CMenu::ModifyMenu(nID,mdata->nFlags,nID,(LPCTSTR)mdata));
899 }
900
901 BOOL BCMenu::ModifyODMenuA(const char * lpstrText,UINT nID,CBitmap *bmp)
902 {
903 USES_CONVERSION;
904 return ModifyODMenuW(A2W(lpstrText),nID,bmp);
905 }
906
907 BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,UINT nID,CBitmap *bmp)
908 {
909 if(bmp){
910 CImageList temp;
911 temp.Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
912 if(m_bitmapBackgroundFlag)temp.Add(bmp,m_bitmapBackground);
913 else temp.Add(bmp,GetSysColor(COLOR_3DFACE));
914 return ModifyODMenuW(lpstrText,nID,&temp,0);
915 }
916 return ModifyODMenuW(lpstrText,nID,NULL,0);
917 }
918
919
920 BOOL BCMenu::ModifyODMenuA(const char *lpstrText,const char *OptionText,
921 int nIconNormal)
922 {
923 USES_CONVERSION;
924 return ModifyODMenuW(A2W(lpstrText),A2W(OptionText),nIconNormal);//SK: see MFC Tech Note 059
925 }
926
927 BOOL BCMenu::ModifyODMenuW(wchar_t *lpstrText,wchar_t *OptionText,
928 int nIconNormal)
929 {
930 BCMenuData *mdata;
931
932 // Find the old BCMenuData structure:
933 CString junk=OptionText;
934 mdata=FindMenuOption(OptionText);
935 if(mdata){
936 if(lpstrText)
937 mdata->SetWideString(lpstrText);//SK: modified for dynamic allocation
938 mdata->menuIconNormal = nIconNormal;
939 mdata->xoffset=-1;
940 if(nIconNormal>=0){
941 mdata->xoffset=0;
942 if(mdata->bitmap)mdata->bitmap->DeleteImageList();
943 else mdata->bitmap=new(CImageList);
944 mdata->bitmap->Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
945 if(!AddBitmapToImageList(mdata->bitmap,nIconNormal)){
946 mdata->bitmap->DeleteImageList();
947 delete mdata->bitmap;
948 mdata->bitmap=NULL;
949 mdata->menuIconNormal = nIconNormal = -1;
950 mdata->xoffset = -1;
951 }
952 }
953 return(TRUE);
954 }
955 return(FALSE);
956 }
957
958 BCMenuData *BCMenu::NewODMenu(UINT pos,UINT nFlags,UINT nID,CString string)
959 {
960 BCMenuData *mdata;
961
962 mdata = new BCMenuData;
963 mdata->menuIconNormal = -1;
964 mdata->xoffset=-1;
965 #ifdef UNICODE
966 mdata->SetWideString((LPCTSTR)string);//SK: modified for dynamic allocation
967 #else
968 mdata->SetAnsiString(string);
969 #endif
970 mdata->nFlags = nFlags;
971 mdata->nID = nID;
972
973 if(nFlags & MF_POPUP)m_AllSubMenus.Add((HMENU)nID);
974
975 if (nFlags&MF_OWNERDRAW){
976 ASSERT(!(nFlags&MF_STRING));
977 ModifyMenu(pos,nFlags,nID,(LPCTSTR)mdata);
978 }
979 else if (nFlags&MF_STRING){
980 ASSERT(!(nFlags&MF_OWNERDRAW));
981 ModifyMenu(pos,nFlags,nID,mdata->GetString());
982 }
983 else{
984 ASSERT(nFlags&MF_SEPARATOR);
985 ModifyMenu(pos,nFlags,nID);
986 }
987
988 return(mdata);
989 };
990
991 BOOL BCMenu::LoadToolbars(const UINT *arID,int n)
992 {
993 ASSERT(arID);
994 BOOL returnflag=TRUE;
995 for(int i=0;i<n;++i){
996 if(!LoadToolbar(arID[i]))returnflag=FALSE;
997 }
998 return(returnflag);
999 }
1000
1001 BOOL BCMenu::LoadToolbar(UINT nToolBar)
1002 {
1003 UINT nID;
1004 BOOL returnflag=FALSE;
1005 CToolBar bar;
1006
1007 bar.Create(AfxGetMainWnd());
1008 if(bar.LoadToolBar(nToolBar)){
1009 for(int i=0;i<bar.GetCount();++i){
1010 nID = bar.GetItemID(i);
1011 if(nID && GetMenuState(nID, MF_BYCOMMAND)
1012 !=0xFFFFFFFF){
1013 ModifyODMenu(NULL,nID,nToolBar);
1014 }
1015 }
1016 returnflag=TRUE;
1017 }
1018 return(returnflag);
1019 }
1020
1021 BOOL BCMenu::LoadFromToolBar(UINT nID,UINT nToolBar,int& xoffset)
1022 {
1023 int xset,offset;
1024 UINT nStyle;
1025 BOOL returnflag=FALSE;
1026 CToolBar bar;
1027
1028 bar.Create(AfxGetMainWnd());
1029 if(bar.LoadToolBar(nToolBar)){
1030 offset=bar.CommandToIndex(nID);
1031 if(offset>=0){
1032 bar.GetButtonInfo(offset,nID,nStyle,xset);
1033 if(xset>0)xoffset=xset;
1034 returnflag=TRUE;
1035 }
1036 }
1037 return(returnflag);
1038 }
1039
1040 // O.S.
1041 BCMenuData *BCMenu::FindMenuItem(UINT nID)
1042 {
1043 BCMenuData *pData = NULL;
1044 int i;
1045
1046 for(i = 0; i <= m_MenuList.GetUpperBound(); i++){
1047 if (m_MenuList[i]->nID == nID){
1048 pData = m_MenuList[i];
1049 break;
1050 }
1051 }
1052 if (!pData){
1053 int loc;
1054 BCMenu *pMenu = FindMenuOption(nID, loc);
1055 ASSERT(pMenu != this);
1056 if (loc >= 0){
1057 return pMenu->FindMenuItem(nID);
1058 }
1059 }
1060 return pData;
1061 }
1062
1063 BCMenu *BCMenu::FindMenuOption(int nId,int& nLoc)
1064 {
1065 int i;
1066 BCMenu *psubmenu,*pgoodmenu;
1067
1068 for(i=0;i<(int)(GetMenuItemCount());++i){
1069 #ifdef _CPPRTTI
1070 psubmenu=dynamic_cast<BCMenu *>(GetSubMenu(i));
1071 #else
1072 psubmenu=(BCMenu *)GetSubMenu(i);
1073 #endif
1074 if(psubmenu){
1075 pgoodmenu=psubmenu->FindMenuOption(nId,nLoc);
1076 if(pgoodmenu)return(pgoodmenu);
1077 }
1078 else if(nId==(int)GetMenuItemID(i)){
1079 nLoc=i;
1080 return(this);
1081 }
1082 }
1083 nLoc = -1;
1084 return(NULL);
1085 }
1086
1087 BCMenuData *BCMenu::FindMenuOption(wchar_t *lpstrText)
1088 {
1089 int i,j;
1090 BCMenu *psubmenu;
1091 BCMenuData *pmenulist;
1092
1093 for(i=0;i<(int)(GetMenuItemCount());++i){
1094 #ifdef _CPPRTTI
1095 psubmenu=dynamic_cast<BCMenu *>(GetSubMenu(i));
1096 #else
1097 psubmenu=(BCMenu *)GetSubMenu(i);
1098 #endif
1099 if(psubmenu){
1100 pmenulist=psubmenu->FindMenuOption(lpstrText);
1101 if(pmenulist)return(pmenulist);
1102 }
1103 else{
1104 const wchar_t *szWide;//SK: we use const to prevent misuse of this Ptr
1105 for(j=0;j<=m_MenuList.GetUpperBound();++j){
1106 szWide = m_MenuList[j]->GetWideString ();
1107 if(szWide && !wcscmp(lpstrText,szWide))//SK: modified for dynamic allocation
1108 return(m_MenuList[j]);
1109 }
1110 }
1111 }
1112 return(NULL);
1113 }
1114
1115
1116 BOOL BCMenu::LoadMenu(int nResource)
1117 {
1118 return(BCMenu::LoadMenu(MAKEINTRESOURCE(nResource)));
1119 };
1120
1121 BOOL BCMenu::LoadMenu(LPCTSTR lpszResourceName)
1122 {
1123 TRACE(_T(
1124 "IMPORTANT:Use BCMenu::DestroyMenu to destroy Loaded Menu's\n"));
1125 ASSERT_VALID(this);
1126 ASSERT(lpszResourceName != NULL);
1127
1128 // Find the Menu Resource:
1129 HINSTANCE m_hInst = AfxFindResourceHandle(lpszResourceName,RT_MENU);
1130 HRSRC hRsrc = ::FindResource(m_hInst,lpszResourceName,RT_MENU);
1131 if(hRsrc == NULL)return FALSE;
1132
1133 // Load the Menu Resource:
1134
1135 HGLOBAL hGlobal = LoadResource(m_hInst, hRsrc);
1136 if(hGlobal == NULL)return FALSE;
1137
1138 // Attempt to create us as a menu...
1139
1140 if(!CMenu::CreateMenu())return FALSE;
1141
1142 // Get Item template Header, and calculate offset of MENUITEMTEMPLATES
1143
1144 MENUITEMTEMPLATEHEADER *pTpHdr=
1145 (MENUITEMTEMPLATEHEADER*)LockResource(hGlobal);
1146 BYTE* pTp=(BYTE*)pTpHdr +
1147 (sizeof(MENUITEMTEMPLATEHEADER) + pTpHdr->offset);
1148
1149
1150 // Variables needed during processing of Menu Item Templates:
1151
1152 int j=0;
1153 WORD dwFlags = 0; // Flags of the Menu Item
1154 WORD dwID = 0; // ID of the Menu Item
1155 UINT uFlags; // Actual Flags.
1156 wchar_t *szCaption=NULL;
1157 int nLen = 0; // Length of caption
1158 CTypedPtrArray<CPtrArray, BCMenu*> m_Stack; // Popup menu stack
1159 CArray<BOOL,BOOL> m_StackEnd; // Popup menu stack
1160 m_Stack.Add(this); // Add it to this...
1161 m_StackEnd.Add(FALSE);
1162
1163 do{
1164 // Obtain Flags and (if necessary), the ID...
1165 memcpy(&dwFlags, pTp, sizeof(WORD));pTp+=sizeof(WORD);// Obtain Flags
1166 if(!(dwFlags & MF_POPUP)){
1167 memcpy(&dwID, pTp, sizeof(WORD)); // Obtain ID
1168 pTp+=sizeof(WORD);
1169 }
1170 else dwID = 0;
1171
1172 uFlags = (UINT)dwFlags; // Remove MF_END from the flags that will
1173 if(uFlags & MF_END) // be passed to the Append(OD)Menu functions.
1174 uFlags -= MF_END;
1175
1176 // Obtain Caption (and length)
1177
1178 nLen = 0;
1179 szCaption=new wchar_t[wcslen((wchar_t *)pTp)+1];
1180 wcscpy(szCaption,(wchar_t *)pTp);
1181 pTp=&pTp[(wcslen((wchar_t *)pTp)+1)*sizeof(wchar_t)];//modified SK
1182
1183 // Handle popup menus first....
1184
1185 //WideCharToMultiByte
1186 if(dwFlags & MF_POPUP){
1187 if(dwFlags & MF_END)m_StackEnd.SetAt(m_Stack.GetUpperBound(),TRUE);
1188 BCMenu* pSubMenu = new BCMenu;
1189 pSubMenu->m_unselectcheck=m_unselectcheck;
1190 pSubMenu->m_selectcheck=m_selectcheck;
1191 pSubMenu->checkmaps=checkmaps;
1192 pSubMenu->checkmapsshare=TRUE;
1193 pSubMenu->CreatePopupMenu();
1194
1195 // Append it to the top of the stack:
1196
1197 m_Stack[m_Stack.GetUpperBound()]->AppendODMenuW(szCaption,uFlags,
1198 (UINT)pSubMenu->m_hMenu, -1);
1199 m_Stack.Add(pSubMenu);
1200 m_StackEnd.Add(FALSE);
1201 }
1202 else {
1203 m_Stack[m_Stack.GetUpperBound()]->AppendODMenuW(szCaption, uFlags,
1204 dwID, -1);
1205 if(dwFlags & MF_END)m_StackEnd.SetAt(m_Stack.GetUpperBound(),TRUE);
1206 j = m_Stack.GetUpperBound();
1207 while(j>=0 && m_StackEnd.GetAt(j)){
1208 m_Stack[m_Stack.GetUpperBound()]->InsertSpaces();
1209 m_Stack.RemoveAt(j);
1210 m_StackEnd.RemoveAt(j);
1211 --j;
1212 }
1213 }
1214
1215 delete[] szCaption;
1216 }while(m_Stack.GetUpperBound() != -1);
1217
1218 for(int i=0;i<(int)GetMenuItemCount();++i){
1219 CString str=m_MenuList[i]->GetString();
1220
1221 if(GetSubMenu(i)){
1222 m_MenuList[i]->nFlags=MF_POPUP|MF_BYPOSITION;
1223 ModifyMenu(i,MF_POPUP|MF_BYPOSITION,
1224 (UINT)GetSubMenu(i)->m_hMenu,str);
1225 }
1226 else{
1227 m_MenuList[i]->nFlags=MF_STRING|MF_BYPOSITION;
1228 ModifyMenu(i,MF_STRING|MF_BYPOSITION,m_MenuList[i]->nID,str);
1229 }
1230 }
1231
1232 return(TRUE);
1233 }
1234
1235 void BCMenu::InsertSpaces(void)
1236 {
1237 int i,j,numitems,maxlength;
1238 CString string,newstring;
1239 CSize t;
1240 CFont m_fontMenu;
1241 LOGFONT m_lf;
1242
1243 ZeroMemory ((PVOID) &m_lf,sizeof (LOGFONT));
1244 NONCLIENTMETRICS nm;
1245 nm.cbSize = sizeof (NONCLIENTMETRICS);
1246 VERIFY (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0));
1247 m_lf = nm.lfMenuFont;
1248 m_fontMenu.CreateFontIndirect (&m_lf);
1249
1250 CWnd *pWnd = AfxGetMainWnd();
1251 CDC *pDC = pWnd->GetDC();
1252 CFont* pFont = pDC->SelectObject (&m_fontMenu);
1253
1254 numitems=GetMenuItemCount();
1255 maxlength = -1;
1256 for(i=0;i<numitems;++i){
1257 string=m_MenuList[i]->GetString();
1258 j=string.Find((char)9);
1259 newstring.Empty();
1260 if(j!=-1)newstring=string.Left(j);
1261 else newstring=string;
1262 newstring+=_T(" ");//SK: modified for Unicode correctness.
1263 LPCTSTR lpstrText = (LPCTSTR)newstring;
1264 t=pDC->GetTextExtent(lpstrText,_tcslen(lpstrText));
1265 if(t.cx>maxlength)maxlength = t.cx;
1266 }
1267 for(i=0;i<numitems;++i){
1268 string=m_MenuList[i]->GetString();
1269 j=string.Find((char)9);
1270 if(j!=-1){
1271 newstring.Empty();
1272 newstring=string.Left(j);
1273 LPCTSTR lpstrText = (LPCTSTR)(newstring);
1274 t=pDC->GetTextExtent(lpstrText,_tcslen(lpstrText));
1275 while(t.cx<maxlength){
1276 newstring+=_T(' ');//SK: modified for Unicode correctness
1277 LPCTSTR lpstrText = (LPCTSTR)(newstring);
1278 t=pDC->GetTextExtent(lpstrText,_tcslen(lpstrText));
1279 }
1280 newstring+=string.Mid(j);
1281 #ifdef UNICODE
1282 m_MenuList[i]->SetWideString(newstring);//SK: modified for dynamic allocation
1283 #else
1284 m_MenuList[i]->SetAnsiString(newstring);
1285 #endif
1286 }
1287 }
1288 pDC->SelectObject (pFont); // Select old font in
1289 AfxGetMainWnd()->ReleaseDC(pDC); // Release the DC
1290 m_fontMenu.DeleteObject();
1291 }
1292
1293 void BCMenu::LoadCheckmarkBitmap(int unselect, int select)
1294 {
1295 if(unselect>0 && select>0){
1296 m_selectcheck=select;
1297 m_unselectcheck=unselect;
1298 if(checkmaps)checkmaps->DeleteImageList();
1299 else checkmaps=new(CImageList);
1300 checkmaps->Create(m_iconX,m_iconY,ILC_MASK,2,1);
1301 BOOL flag1=AddBitmapToImageList(checkmaps,unselect);
1302 BOOL flag2=AddBitmapToImageList(checkmaps,select);
1303 if(!flag1||!flag2){
1304 checkmaps->DeleteImageList();
1305 delete checkmaps;
1306 checkmaps=NULL;
1307 }
1308 }
1309 }
1310
1311 //--------------------------------------------------------------------------
1312 //[18.06.99 rj]
1313 BOOL BCMenu::GetMenuText(UINT id, CString& string, UINT nFlags/*= MF_BYPOSITION*/)
1314 {
1315 BOOL returnflag=FALSE;
1316
1317 if(MF_BYPOSITION&nFlags){
1318 UINT numMenuItems = m_MenuList.GetUpperBound();
1319 if(id<=numMenuItems){
1320 string=m_MenuList[id]->GetString();
1321 returnflag=TRUE;
1322 }
1323 }
1324 else{
1325 int uiLoc;
1326 BCMenu* pMenu = FindMenuOption(id,uiLoc);
1327 if(NULL!=pMenu) returnflag = pMenu->GetMenuText(uiLoc,string);
1328 }
1329 return(returnflag);
1330 }
1331
1332
1333 void BCMenu::DrawRadioDot(CDC *pDC,int x,int y,COLORREF color)
1334 {
1335 CRect rcDot(x,y,x+6,y+6);
1336 CBrush brush;
1337 CPen pen;
1338 brush.CreateSolidBrush(color);
1339 pen.CreatePen(PS_SOLID,0,color);
1340 CBrush *pOldBrush=pDC->SelectObject(&brush);
1341 CPen *pOldPen=pDC->SelectObject(&pen);
1342 pDC->Ellipse(&rcDot);
1343 pDC->SelectObject(pOldBrush);
1344 pDC->SelectObject(pOldPen);
1345 pen.DeleteObject();
1346 brush.DeleteObject();
1347 }
1348
1349 void BCMenu::DrawCheckMark(CDC* pDC,int x,int y,COLORREF color)
1350 {
1351 pDC->SetPixel(x,y+2,color);
1352 pDC->SetPixel(x,y+3,color);
1353 pDC->SetPixel(x,y+4,color);
1354
1355 pDC->SetPixel(x+1,y+3,color);
1356 pDC->SetPixel(x+1,y+4,color);
1357 pDC->SetPixel(x+1,y+5,color);
1358
1359 pDC->SetPixel(x+2,y+4,color);
1360 pDC->SetPixel(x+2,y+5,color);
1361 pDC->SetPixel(x+2,y+6,color);
1362
1363 pDC->SetPixel(x+3,y+3,color);
1364 pDC->SetPixel(x+3,y+4,color);
1365 pDC->SetPixel(x+3,y+5,color);
1366
1367 pDC->SetPixel(x+4,y+2,color);
1368 pDC->SetPixel(x+4,y+3,color);
1369 pDC->SetPixel(x+4,y+4,color);
1370
1371 pDC->SetPixel(x+5,y+1,color);
1372 pDC->SetPixel(x+5,y+2,color);
1373 pDC->SetPixel(x+5,y+3,color);
1374
1375 pDC->SetPixel(x+6,y,color);
1376 pDC->SetPixel(x+6,y+1,color);
1377 pDC->SetPixel(x+6,y+2,color);
1378 }
1379
1380 BCMenuData *BCMenu::FindMenuList(UINT nID)
1381 {
1382 for(int i=0;i<=m_MenuList.GetUpperBound();++i){
1383 if(m_MenuList[i]->nID==nID && !m_MenuList[i]->syncflag){
1384 m_MenuList[i]->syncflag=1;
1385 return(m_MenuList[i]);
1386 }
1387 }
1388 return(NULL);
1389 }
1390
1391 void BCMenu::InitializeMenuList(int value)
1392 {
1393 for(int i=0;i<=m_MenuList.GetUpperBound();++i)
1394 m_MenuList[i]->syncflag=value;
1395 }
1396
1397 void BCMenu::DeleteMenuList(void)
1398 {
1399 for(int i=0;i<=m_MenuList.GetUpperBound();++i){
1400 if(!m_MenuList[i]->syncflag){
1401 delete m_MenuList[i];
1402 }
1403 }
1404 }
1405
1406 void BCMenu::SynchronizeMenu(void)
1407 {
1408 CTypedPtrArray<CPtrArray, BCMenuData*> temp;
1409 BCMenuData *mdata;
1410 CString string;
1411 UINT submenu,nID=0,state,j;
1412
1413 InitializeMenuList(0);
1414 for(j=0;j<GetMenuItemCount();++j){
1415 mdata=NULL;
1416 state=GetMenuState(j,MF_BYPOSITION);
1417 if(state&MF_POPUP){
1418 submenu=(UINT)GetSubMenu(j)->m_hMenu;
1419 mdata=FindMenuList(submenu);
1420 GetMenuString(j,string,MF_BYPOSITION);
1421 if(!mdata)mdata=NewODMenu(j,
1422 (state&0xFF)|MF_BYPOSITION|MF_POPUP|MF_OWNERDRAW,submenu,string);
1423 else if(string.GetLength()>0)
1424 #ifdef UNICODE
1425 mdata->SetWideString(string); //SK: modified for dynamic allocation
1426 #else
1427 mdata->SetAnsiString(string);
1428 #endif
1429 }
1430 else if(state&MF_SEPARATOR){
1431 mdata=FindMenuList(0);
1432 if(!mdata)mdata=NewODMenu(j,
1433 state|MF_BYPOSITION|MF_SEPARATOR|MF_OWNERDRAW,0,_T(""));//SK: modified for Unicode correctness
1434 else ModifyMenu(j,mdata->nFlags,nID,(LPCTSTR)mdata);
1435 }
1436 else{
1437 nID=GetMenuItemID(j);
1438 mdata=FindMenuList(nID);
1439 GetMenuString(j,string,MF_BYPOSITION);
1440 if(!mdata)mdata=NewODMenu(j,state|MF_BYPOSITION|MF_OWNERDRAW,
1441 nID,string);
1442 else{
1443 mdata->nFlags=state|MF_BYPOSITION|MF_OWNERDRAW;
1444 if(string.GetLength()>0)
1445 #ifdef UNICODE
1446 mdata->SetWideString(string);//SK: modified for dynamic allocation
1447 #else
1448 mdata->SetAnsiString(string);
1449 #endif
1450
1451 ModifyMenu(j,mdata->nFlags,nID,(LPCTSTR)mdata);
1452 }
1453 }
1454 if(mdata)temp.Add(mdata);
1455 }
1456 DeleteMenuList();
1457 m_MenuList.RemoveAll();
1458 m_MenuList.Append(temp);
1459 temp.RemoveAll();
1460 }
1461
1462 void BCMenu::UpdateMenu(CMenu *pmenu)
1463 {
1464 #ifdef _CPPRTTI
1465 BCMenu *psubmenu = dynamic_cast<BCMenu *>(pmenu);
1466 #else
1467 BCMenu *psubmenu = (BCMenu *)pmenu;
1468 #endif
1469 if(psubmenu)psubmenu->SynchronizeMenu();
1470 }
1471
1472 LRESULT BCMenu::FindKeyboardShortcut(UINT nChar, UINT nFlags,
1473 CMenu *pMenu)
1474 {
1475 #ifdef _CPPRTTI
1476 BCMenu *pBCMenu = dynamic_cast<BCMenu *>(pMenu);
1477 #else
1478 BCMenu *pBCMenu = (BCMenu *)pMenu;
1479 #endif
1480 if(pBCMenu && nFlags&MF_POPUP){
1481 CString key(_T('&'),2);//SK: modified for Unicode correctness
1482 key.SetAt(1,(TCHAR)nChar);
1483 key.MakeLower();
1484 CString menutext;
1485 int menusize = (int)pBCMenu->GetMenuItemCount();
1486 if(menusize!=(pBCMenu->m_MenuList.GetUpperBound()+1))
1487 pBCMenu->SynchronizeMenu();
1488 for(int i=0;i<menusize;++i){
1489 if(pBCMenu->GetMenuText(i,menutext)){
1490 menutext.MakeLower();
1491 if(menutext.Find(key)>=0)return(MAKELRESULT(i,2));
1492 }
1493 }
1494 }
1495 return(0);
1496 }
1497
1498 void BCMenu::DitherBlt (HDC hdcDest, int nXDest, int nYDest, int nWidth,
1499 int nHeight, HBITMAP hbm, int nXSrc, int nYSrc)
1500 {
1501 ASSERT(hdcDest && hbm);
1502 ASSERT(nWidth > 0 && nHeight > 0);
1503
1504 // Create a generic DC for all BitBlts
1505 HDC hDC = CreateCompatibleDC(hdcDest);
1506 ASSERT(hDC);
1507
1508 if (hDC)
1509 {
1510 // Create a DC for the monochrome DIB section
1511 HDC bwDC = CreateCompatibleDC(hDC);
1512 ASSERT(bwDC);
1513
1514 if (bwDC)
1515 {
1516 // Create the monochrome DIB section with a black and white palette
1517 struct {
1518 BITMAPINFOHEADER bmiHeader;
1519 RGBQUAD bmiColors[2];
1520 } RGBBWBITMAPINFO = {
1521
1522 { // a BITMAPINFOHEADER
1523 sizeof(BITMAPINFOHEADER), // biSize
1524 nWidth, // biWidth;
1525 nHeight, // biHeight;
1526 1, // biPlanes;
1527 1, // biBitCount
1528 BI_RGB, // biCompression;
1529 0, // biSizeImage;
1530 0, // biXPelsPerMeter;
1531 0, // biYPelsPerMeter;
1532 0, // biClrUsed;
1533 0 // biClrImportant;
1534 },
1535 {
1536 { 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 }
1537 }
1538 };
1539 VOID *pbitsBW;
1540 HBITMAP hbmBW = CreateDIBSection(bwDC,
1541 (LPBITMAPINFO)&RGBBWBITMAPINFO, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
1542 ASSERT(hbmBW);
1543
1544 if (hbmBW)
1545 {
1546 // Attach the monochrome DIB section and the bitmap to the DCs
1547 HBITMAP olddib = (HBITMAP)SelectObject(bwDC, hbmBW);
1548 HBITMAP hdcolddib = (HBITMAP)SelectObject(hDC, hbm);
1549
1550 // BitBlt the bitmap into the monochrome DIB section
1551 BitBlt(bwDC, 0, 0, nWidth, nHeight, hDC, nXSrc, nYSrc, SRCCOPY);
1552
1553 // Paint the destination rectangle in gray
1554 FillRect(hdcDest, CRect(nXDest, nYDest, nXDest + nWidth, nYDest +
1555 nHeight), GetSysColorBrush((IsNewShell())?COLOR_3DFACE:COLOR_MENU));
1556 //SK: looks better on the old shell
1557 // BitBlt the black bits in the monochrome bitmap into COLOR_3DHILIGHT
1558 // bits in the destination DC
1559 // The magic ROP comes from the Charles Petzold's book
1560 HBRUSH hb = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
1561 HBRUSH oldBrush = (HBRUSH)SelectObject(hdcDest, hb);
1562 BitBlt(hdcDest,nXDest+1,nYDest+1,nWidth,nHeight,bwDC,0,0,0xB8074A);
1563
1564 // BitBlt the black bits in the monochrome bitmap into COLOR_3DSHADOW
1565 // bits in the destination DC
1566 hb = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
1567 DeleteObject(SelectObject(hdcDest, hb));
1568 BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight,bwDC,0,0,0xB8074A);
1569 DeleteObject(SelectObject(hdcDest, oldBrush));
1570 VERIFY(DeleteObject(SelectObject(bwDC, olddib)));
1571 SelectObject(hDC, hdcolddib);
1572 }
1573
1574 VERIFY(DeleteDC(bwDC));
1575 }
1576
1577 VERIFY(DeleteDC(hDC));
1578 }
1579 }
1580
1581 BOOL BCMenu::AddBitmapToImageList(CImageList *bmplist,UINT nResourceID)
1582 {
1583 // O.S.
1584 if (m_bDynIcons){
1585 bmplist->Add((HICON)nResourceID);
1586 return TRUE;
1587 }
1588
1589 BOOL bReturn=TRUE;
1590
1591 HBITMAP hbmp=LoadSysColorBitmap(nResourceID);
1592 if(hbmp){
1593 CBitmap bmp;
1594 bmp.Attach(hbmp);
1595 if(m_bitmapBackgroundFlag) bmplist->Add(&bmp,m_bitmapBackground);
1596 else bmplist->Add(&bmp,GetSysColor(COLOR_3DFACE));
1597 bmp.Detach();
1598 DeleteObject(hbmp);
1599 bReturn=TRUE;
1600 }
1601 else bReturn = FALSE;
1602 return(bReturn);
1603 }
1604
1605 void BCMenu::SetBitmapBackground(COLORREF color)
1606 {
1607 m_bitmapBackground=color;
1608 m_bitmapBackgroundFlag=TRUE;
1609 }
1610
1611 void BCMenu::UnSetBitmapBackground(void)
1612 {
1613 m_bitmapBackgroundFlag=FALSE;
1614 }
1615
1616 // Given a toolbar, append all the options from it to this menu
1617 // Passed a ptr to the toolbar object and the toolbar ID
1618 // Author : Robert Edward Caldecott
1619 void BCMenu::AddFromToolBar(CToolBar* pToolBar, int nResourceID)
1620 {
1621 for (int i = 0; i < pToolBar->GetCount(); i++) {
1622 UINT nID = pToolBar->GetItemID(i);
1623 // See if this toolbar option
1624 // appears as a command on this
1625 // menu or is a separator
1626 if (nID == 0 || GetMenuState(nID, MF_BYCOMMAND) == 0xFFFFFFFF)
1627 continue; // Item doesn't exist
1628 UINT nStyle;
1629 int nImage;
1630 // Get the toolbar button info
1631 pToolBar->GetButtonInfo(i, nID, nStyle, nImage);
1632 // OK, we have the command ID of the toolbar
1633 // option, and the tollbar bitmap offset
1634 int nLoc;
1635 BCMenuData* pData;
1636 BCMenu *pSubMenu = FindMenuOption(nID, nLoc);
1637 if (pSubMenu && nLoc >= 0)pData = pSubMenu->m_MenuList[nLoc];
1638 else {
1639 // Create a new BCMenuData structure
1640 pData = new BCMenuData;
1641 m_MenuList.Add(pData);
1642 }
1643 // Set some default structure members
1644 pData->menuIconNormal = nResourceID;
1645 pData->nID = nID;
1646 pData->nFlags = MF_BYCOMMAND | MF_OWNERDRAW;
1647 pData->xoffset = nImage;
1648 if (pData->bitmap)pData->bitmap->DeleteImageList();
1649 else pData->bitmap = new CImageList;
1650 pData->bitmap->Create(m_iconX, m_iconY,ILC_COLORDDB|ILC_MASK, 1, 1);
1651
1652 if(!AddBitmapToImageList(pData->bitmap, nResourceID)){
1653 pData->bitmap->DeleteImageList();
1654 delete pData->bitmap;
1655 pData->bitmap=NULL;
1656 pData->menuIconNormal = -1;
1657 pData->xoffset = -1;
1658 }
1659
1660 // Modify our menu
1661 ModifyMenu(nID,pData->nFlags,nID,(LPCTSTR)pData);
1662 }
1663 }
1664
1665 BOOL BCMenu::Draw3DCheckmark(CDC *dc, const CRect& rc,
1666 BOOL bSelected, HBITMAP hbmCheck)
1667 {
1668 CRect rcDest = rc;
1669 CBrush brush;
1670 COLORREF col=GetSysColor((bSelected||!IsNewShell())?COLOR_MENU:COLOR_3DLIGHT);//SK: Looks better on the old shell
1671 brush.CreateSolidBrush(col);
1672 dc->FillRect(rcDest,&brush);
1673 brush.DeleteObject();
1674 if (IsNewShell()) //SK: looks better on the old shell
1675 dc->DrawEdge(&rcDest, BDR_SUNKENOUTER, BF_RECT);
1676 if (!hbmCheck)DrawCheckMark(dc,rc.left+4,rc.top+4,GetSysColor(COLOR_MENUTEXT));
1677 else DrawRadioDot(dc,rc.left+5,rc.top+4,GetSysColor(COLOR_MENUTEXT));
1678 return TRUE;
1679 }
1680
1681 void BCMenu::DitherBlt2(CDC *drawdc, int nXDest, int nYDest, int nWidth,
1682 int nHeight, CBitmap &bmp, int nXSrc, int nYSrc)
1683 {
1684 // create a monochrome memory DC
1685 CDC ddc;
1686 ddc.CreateCompatibleDC(0);
1687 CBitmap bwbmp;
1688 bwbmp.CreateCompatibleBitmap(&ddc, nWidth, nHeight);
1689 CBitmap * pddcOldBmp = ddc.SelectObject(&bwbmp);
1690
1691 CDC dc;
1692 dc.CreateCompatibleDC(0);
1693 CBitmap * pdcOldBmp = dc.SelectObject(&bmp);
1694
1695 // build a mask
1696 ddc.PatBlt(0, 0, nWidth, nHeight, WHITENESS);
1697 dc.SetBkColor(GetSysColor(COLOR_BTNFACE));
1698 ddc.BitBlt(0, 0, nWidth, nHeight, &dc, nXSrc,nYSrc, SRCCOPY);
1699 dc.SetBkColor(GetSysColor(COLOR_BTNHILIGHT));
1700 ddc.BitBlt(0, 0, nWidth, nHeight, &dc, nXSrc,nYSrc, SRCPAINT);
1701
1702 // Copy the image from the toolbar into the memory DC
1703 // and draw it (grayed) back into the toolbar.
1704 dc.FillSolidRect(0,0, nWidth, nHeight, GetSysColor((IsNewShell())?COLOR_3DFACE:COLOR_MENU));
1705 //SK: Looks better on the old shell
1706 dc.SetBkColor(RGB(0, 0, 0));
1707 dc.SetTextColor(RGB(255, 255, 255));
1708 CBrush brShadow, brHilight;
1709 brHilight.CreateSolidBrush(GetSysColor(COLOR_BTNHILIGHT));
1710 brShadow.CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
1711 CBrush * pOldBrush = dc.SelectObject(&brHilight);
1712 dc.BitBlt(0,0, nWidth, nHeight, &ddc, 0, 0, 0x00E20746L);
1713 drawdc->BitBlt(nXDest+1,nYDest+1,nWidth, nHeight, &dc,0,0,SRCCOPY);
1714 dc.BitBlt(1,1, nWidth, nHeight, &ddc, 0, 0, 0x00E20746L);
1715 dc.SelectObject(&brShadow);
1716 dc.BitBlt(0,0, nWidth, nHeight, &ddc, 0, 0, 0x00E20746L);
1717 drawdc->BitBlt(nXDest,nYDest,nWidth, nHeight, &dc,0,0,SRCCOPY);
1718 // reset DCs
1719 ddc.SelectObject(pddcOldBmp);
1720 ddc.DeleteDC();
1721 dc.SelectObject(pOldBrush);
1722 dc.SelectObject(pdcOldBmp);
1723 dc.DeleteDC();
1724
1725 brShadow.DeleteObject();
1726 brHilight.DeleteObject();
1727 bwbmp.DeleteObject();
1728 }
1729
1730 void BCMenu::SetDisableOldStyle(void)
1731 {
1732 disable_old_style=TRUE;
1733 }
1734
1735 void BCMenu::UnSetDisableOldStyle(void)
1736 {
1737 disable_old_style=FALSE;
1738 }
1739
1740 BOOL BCMenu::GetDisableOldStyle(void)
1741 {
1742 return(disable_old_style);
1743 }
1744
1745
1746 HBITMAP BCMenu::LoadSysColorBitmap(int nResourceId)
1747 {
1748 HINSTANCE hInst =
1749 AfxFindResourceHandle(MAKEINTRESOURCE(nResourceId),RT_BITMAP);
1750 HRSRC hRsrc =
1751 ::FindResource(hInst,MAKEINTRESOURCE(nResourceId),RT_BITMAP);
1752 if (hRsrc == NULL)
1753 return NULL;
1754 return AfxLoadSysColorBitmap(hInst, hRsrc, FALSE);
1755 }
1756
1757 BOOL BCMenu::RemoveMenu(UINT uiId,UINT nFlags)
1758 {
1759 if(MF_BYPOSITION&nFlags){
1760 UINT uint = GetMenuState(uiId,MF_BYPOSITION);
1761 if(uint&MF_SEPARATOR && !(uint&MF_POPUP)){
1762 delete m_MenuList.GetAt(uiId);
1763 m_MenuList.RemoveAt(uiId);
1764 }
1765 else{
1766 BCMenu* pSubMenu = (BCMenu*) GetSubMenu(uiId);
1767 if(NULL==pSubMenu){
1768 UINT uiCommandId = GetMenuItemID(uiId);
1769 for(int i=0;i<m_MenuList.GetSize(); i++){
1770 if(m_MenuList[i]->nID==uiCommandId){
1771 delete m_MenuList.GetAt(i);
1772 m_MenuList.RemoveAt(i);
1773 break;
1774 }
1775 }
1776 }
1777 else{
1778 int numSubMenus = m_SubMenus.GetUpperBound();
1779 for(int m = numSubMenus; m >= 0; m--){
1780 if(m_SubMenus[m]==pSubMenu->m_hMenu){
1781 int numAllSubMenus = m_AllSubMenus.GetUpperBound();
1782 for(int n = numAllSubMenus; n>= 0; n--){
1783 if(m_AllSubMenus[n]==m_SubMenus[m])m_AllSubMenus.RemoveAt(n);
1784 }
1785 m_SubMenus.RemoveAt(m);
1786 }
1787 }
1788 int num = pSubMenu->GetMenuItemCount();
1789 for(int i=num-1;i>=0;--i)pSubMenu->RemoveMenu(i,MF_BYPOSITION);
1790 for(i=m_MenuList.GetUpperBound();i>=0;i--){
1791 if(m_MenuList[i]->nID==(UINT)pSubMenu->m_hMenu){
1792 delete m_MenuList.GetAt(i);
1793 m_MenuList.RemoveAt(i);
1794 break;
1795 }
1796 }
1797 delete pSubMenu;
1798 }
1799 }
1800 }
1801 else{
1802 int iPosition =0;
1803 BCMenu* pMenu = FindMenuOption(uiId,iPosition);
1804 if(pMenu)pMenu->RemoveMenu(iPosition,MF_BYPOSITION);
1805 }
1806 return CMenu::RemoveMenu(uiId,nFlags);
1807 }
1808
1809 BOOL BCMenu::DeleteMenu(UINT uiId,UINT nFlags)
1810 {
1811 if(MF_BYPOSITION&nFlags){
1812 UINT uint = GetMenuState(uiId,MF_BYPOSITION);
1813 if(uint&MF_SEPARATOR && !(uint&MF_POPUP)){
1814 delete m_MenuList.GetAt(uiId);
1815 m_MenuList.RemoveAt(uiId);
1816 }
1817 else{
1818 BCMenu* pSubMenu = (BCMenu*) GetSubMenu(uiId);
1819 if(NULL==pSubMenu){
1820 UINT uiCommandId = GetMenuItemID(uiId);
1821 for(int i=0;i<m_MenuList.GetSize(); i++){
1822 if(m_MenuList[i]->nID==uiCommandId){
1823 delete m_MenuList.GetAt(i);
1824 m_MenuList.RemoveAt(i);
1825 break;
1826 }
1827 }
1828 }
1829 else{
1830 int numSubMenus = m_SubMenus.GetUpperBound();
1831 for(int m = numSubMenus; m >= 0; m--){
1832 if(m_SubMenus[m]==pSubMenu->m_hMenu){
1833 int numAllSubMenus = m_AllSubMenus.GetUpperBound();
1834 for(int n = numAllSubMenus; n>= 0; n--){
1835 if(m_AllSubMenus[n]==m_SubMenus[m])m_AllSubMenus.RemoveAt(n);
1836 }
1837 m_SubMenus.RemoveAt(m);
1838 }
1839 }
1840 int num = pSubMenu->GetMenuItemCount();
1841 for(int i=num-1;i>=0;--i)pSubMenu->DeleteMenu(i,MF_BYPOSITION);
1842 for(i=m_MenuList.GetUpperBound();i>=0;i--){
1843 if(m_MenuList[i]->nID==(UINT)pSubMenu->m_hMenu){
1844 delete m_MenuList.GetAt(i);
1845 m_MenuList.RemoveAt(i);
1846 break;
1847 }
1848 }
1849 delete pSubMenu;
1850 }
1851 }
1852 }
1853 else{
1854 int iPosition =0;
1855 BCMenu* pMenu = FindMenuOption(uiId,iPosition);
1856 if(pMenu)pMenu->DeleteMenu(iPosition,MF_BYPOSITION);
1857 }
1858 return CMenu::DeleteMenu(uiId,nFlags);
1859 }
1860
1861
1862 BOOL BCMenu::AppendMenuA(UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,int nIconNormal)
1863 {
1864 USES_CONVERSION;
1865 return AppendMenuW(nFlags,nIDNewItem,A2W(lpszNewItem),nIconNormal);
1866 }
1867
1868 BOOL BCMenu::AppendMenuW(UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,int nIconNormal)
1869 {
1870 return AppendODMenuW(lpszNewItem,nFlags,nIDNewItem,nIconNormal);
1871 }
1872
1873 BOOL BCMenu::AppendMenuA(UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CImageList *il,int xoffset)
1874 {
1875 USES_CONVERSION;
1876 return AppendMenuW(nFlags,nIDNewItem,A2W(lpszNewItem),il,xoffset);
1877 }
1878
1879 BOOL BCMenu::AppendMenuW(UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CImageList *il,int xoffset)
1880 {
1881 return AppendODMenuW(lpszNewItem,nFlags,nIDNewItem,il,xoffset);
1882 }
1883
1884 BOOL BCMenu::AppendMenuA(UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CBitmap *bmp)
1885 {
1886 USES_CONVERSION;
1887 return AppendMenuW(nFlags,nIDNewItem,A2W(lpszNewItem),bmp);
1888 }
1889
1890 BOOL BCMenu::AppendMenuW(UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CBitmap *bmp)
1891 {
1892 if(bmp){
1893 CImageList temp;
1894 temp.Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
1895 if(m_bitmapBackgroundFlag)temp.Add(bmp,m_bitmapBackground);
1896 else temp.Add(bmp,GetSysColor(COLOR_3DFACE));
1897 return AppendODMenuW(lpszNewItem,nFlags,nIDNewItem,&temp,0);
1898 }
1899 return AppendODMenuW(lpszNewItem,nFlags,nIDNewItem,NULL,0);
1900 }
1901
1902 BOOL BCMenu::InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,int nIconNormal)
1903 {
1904 USES_CONVERSION;
1905 return InsertMenuW(nPosition,nFlags,nIDNewItem,A2W(lpszNewItem),nIconNormal);
1906 }
1907
1908 BOOL BCMenu::InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,int nIconNormal)
1909 {
1910 return InsertODMenuW(nPosition,lpszNewItem,nFlags,nIDNewItem,nIconNormal);
1911 }
1912
1913 BOOL BCMenu::InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CImageList *il,int xoffset)
1914 {
1915 USES_CONVERSION;
1916 return InsertMenuW(nPosition,nFlags,nIDNewItem,A2W(lpszNewItem),il,xoffset);
1917 }
1918
1919 BOOL BCMenu::InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CImageList *il,int xoffset)
1920 {
1921 return InsertODMenuW(nPosition,lpszNewItem,nFlags,nIDNewItem,il,xoffset);
1922 }
1923
1924 BOOL BCMenu::InsertMenuA(UINT nPosition,UINT nFlags,UINT nIDNewItem,const char *lpszNewItem,CBitmap *bmp)
1925 {
1926 USES_CONVERSION;
1927 return InsertMenuW(nPosition,nFlags,nIDNewItem,A2W(lpszNewItem),bmp);
1928 }
1929
1930 BOOL BCMenu::InsertMenuW(UINT nPosition,UINT nFlags,UINT nIDNewItem,wchar_t *lpszNewItem,CBitmap *bmp)
1931 {
1932 if(bmp){
1933 CImageList temp;
1934 temp.Create(m_iconX,m_iconY,ILC_COLORDDB|ILC_MASK,1,1);
1935 if(m_bitmapBackgroundFlag)temp.Add(bmp,m_bitmapBackground);
1936 else temp.Add(bmp,GetSysColor(COLOR_3DFACE));
1937 return InsertODMenuW(nPosition,lpszNewItem,nFlags,nIDNewItem,&temp,0);
1938 }
1939 return InsertODMenuW(nPosition,lpszNewItem,nFlags,nIDNewItem,NULL,0);
1940 }
1941
1942 //--------------------------------------------------------------------------
1943 //[21.06.99 rj]
1944 BCMenu* BCMenu::AppendODPopupMenuW(wchar_t *lpstrText)
1945 {
1946 BCMenu* pSubMenu = new BCMenu;
1947 pSubMenu->m_unselectcheck=m_unselectcheck;
1948 pSubMenu->m_selectcheck=m_selectcheck;
1949 pSubMenu->checkmaps=checkmaps;
1950 pSubMenu->checkmapsshare=TRUE;
1951 pSubMenu->CreatePopupMenu();
1952 AppendODMenuW(lpstrText,MF_POPUP,(UINT)pSubMenu->m_hMenu, -1);
1953 return pSubMenu;
1954 }
1955
1956 //--------------------------------------------------------------------------
1957 //[21.06.99 rj]
1958 BCMenu* BCMenu::AppendODPopupMenuA(LPCSTR lpstrText)
1959 {
1960 USES_CONVERSION;
1961 return AppendODPopupMenuW(A2W(lpstrText));
1962 }
1963
1964 BOOL BCMenu::ImageListDuplicate(CImageList *il,int xoffset,CImageList *newlist)
1965 {
1966 if (il == NULL||newlist==NULL||xoffset<0) return FALSE;
1967 HICON hIcon = il->ExtractIcon(xoffset);
1968 int cx, cy;
1969 ImageList_GetIconSize(il->m_hImageList, &cx, &cy);
1970 newlist->Create(cx,cy,ILC_COLOR32|ILC_MASK,1,1);
1971 newlist->Add(hIcon);
1972 ::DestroyIcon(hIcon);
1973 return TRUE;
1974 }
1975
1976 //*************************************************************************