OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [tools/] [src/] [tools/] [configtool/] [standalone/] [win32/] [BCMenu.cpp] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 unneback
//####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
 
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
//*************************************************************************

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.