OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [tools/] [configtool/] [standalone/] [win32/] [BCMenu.cpp] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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