⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcmenu.cpp

📁 TabBars的开源源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//*************************************************************************
// BCMenu.cpp : implementation file
// Version : 2.4
// Date : Feb 11, 1999
// Author : Brent Corkum
// 
// Portions of code supplied by:
// Ben Ashley,Girish Bharadwaj,Jean-Edouard Lachand-Robert,
// Robert Edward Caldecott,Kenny Goers,Leonardo Zide,
// Stefan Kuhr
//
// Bug Fixes:
// Stefan Kuhr,Martin Vladic,Kim Yoo Chul
//
// You are free to use/modify this code but leave this header intact.
//

//this line was inserted and notified to you
//I remove some function or porpert which this addin do not use
//it cound not be replaced by original file

#include "stdafx.h"        // Standard windows header file
#include "BCMenu.h"        // BCMenu class declaration
#include <afxpriv.h>       //SK: makes A2W and other spiffy AFX macros work

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define GAP 1
#ifndef OBM_CHECK
#define OBM_CHECK 32760 // from winuser.h
#endif

#if _MFC_VER <0x400
#error This code does not work on Versions of MFC prior to 4.0
#endif

static CPINFO CPInfo;

enum Win32Type{
Win32s,
Windoze95,
WinNT3,
WinNT4orHigher
};


static Win32Type IsShellType()
{
  Win32Type  ShellType;
  DWORD winVer;
  OSVERSIONINFO *osvi;

  winVer=GetVersion();
  if(winVer<0x80000000){/*NT */
    ShellType=WinNT3;
    osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
    if (osvi!=NULL){
      memset(osvi,0,sizeof(OSVERSIONINFO));
      osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
      GetVersionEx(osvi);
      if (osvi->dwMajorVersion>=4L)
        ShellType=WinNT4orHigher;//yup, it is NT 4 or higher!
      free(osvi);
    }
  }
  else if  (LOBYTE(LOWORD(winVer))<4)
    ShellType=Win32s;/*Win32s*/
  else
    ShellType=Windoze95;/*Windoze95*/
  return ShellType;
}

static Win32Type g_Shell=IsShellType();

void BCMenuData::SetAnsiString(LPCSTR szAnsiString)
{
ASSERT(szAnsiString);
USES_CONVERSION;
SetWideString(A2W(szAnsiString));  //SK:  see MFC Tech Note 059
}

CString BCMenuData::GetString(void)//returns the menu text in ANSI or UNICODE
//depending on the MFC-Version we are using
{
CString strText;
if (m_szMenuText)
    {
#ifdef UNICODE
    strText = m_szMenuText;
#else
USES_CONVERSION;
    strText=W2A(m_szMenuText);     //SK:  see MFC Tech Note 059
#endif    
    }
return strText;
}


/*
 
===============================================================================
  BCMenu::BCMenu()
  TCMeny::~BCMenu()
  -----------------

  Constructor and Destructor.
 
===============================================================================
*/

BCMenu::BCMenu()
{
  disable_old_style=FALSE;
  m_bDynIcons = FALSE;
  m_iconX = 16;            // Icon sizes default to 16 x 16
  m_iconY = 15;            // ...
  m_selectcheck = -1;
  m_unselectcheck = -1;
  checkmaps=NULL;
  checkmapsshare=FALSE;
  // set the color used for the transparent background in all bitmaps
  m_bitmapBackground=RGB(192,192,192); //gray
  m_bitmapBackgroundFlag=FALSE;
  GetCPInfo(CP_ACP,&CPInfo);
}


BCMenu::~BCMenu()
{
  DestroyMenu();
}

BOOL BCMenu::IsNewShell ()
{
return (Windoze95==g_Shell || WinNT4orHigher==g_Shell);
}


BCMenuData::~BCMenuData()
{
  if(bitmap)
    delete(bitmap);

  delete[] m_szMenuText; //Need not check for NULL because ANSI X3J16 allows "delete NULL"
}


void BCMenuData::SetWideString(const wchar_t *szWideString)
{
delete[] m_szMenuText;//Need not check for NULL because ANSI X3J16 allows "delete NULL"

if (szWideString)
    {
    m_szMenuText = new wchar_t[sizeof(wchar_t)*(wcslen(szWideString)+1)];
    if (m_szMenuText)
        wcscpy(m_szMenuText,szWideString);
    }
else
    m_szMenuText=NULL;//set to NULL so we need not bother about dangling non-NULL Ptrs
}

BOOL BCMenu::IsMenu(CMenu *submenu)
{
  int m;

  int numSubMenus = m_SubMenus.GetUpperBound();
  for(m=0;m<=numSubMenus;++m){
    if(submenu==m_SubMenus[m])return(TRUE);
  }
  return(FALSE);
}

BOOL BCMenu::DestroyMenu()
{
  // Destroy Sub menus:
  int m;
  int numSubMenus = m_SubMenus.GetUpperBound();
  for(m = numSubMenus; m >= 0; m--)delete(m_SubMenus[m]);
  m_SubMenus.RemoveAll();
  // Destroy menu data
  int numItems = m_MenuList.GetUpperBound();
  for(m = 0; m <= numItems; m++)delete(m_MenuList[m]);
  m_MenuList.RemoveAll();
  if(checkmaps&&!checkmapsshare){
    delete checkmaps;
    checkmaps=NULL;
  }
  // Call base-class implementation last:
  return(CMenu::DestroyMenu());
};


///////////////////////////////////////////////////////////////////////////
//
// BCMenu message handlers


/*
==========================================================================
void BCMenu::DrawItem(LPDRAWITEMSTRUCT)
---------------------------------------

Called by the framework when a particular item needs to be drawn.  We
overide this to draw the menu item in a custom-fashion, including icons
and the 3D rectangle bar.
==========================================================================
*/


void BCMenu::DrawItem (LPDRAWITEMSTRUCT lpDIS)
{
  ASSERT(lpDIS != NULL);
  CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  CRect rect;

  UINT state = (((BCMenuData*)(lpDIS->itemData))->nFlags);
  if(state & MF_SEPARATOR){
    rect.CopyRect(&lpDIS->rcItem);
    rect.top+=rect.Height()>>1;
    pDC->DrawEdge(&rect,EDGE_ETCHED,BF_TOP);
  }
  else{
    CRect rect2;
    BOOL standardflag=FALSE,selectedflag=FALSE,disableflag=FALSE;
    BOOL checkflag=FALSE;
    CBitmap bitmapstandard;
    COLORREF crText = GetSysColor(COLOR_MENUTEXT);
    COLORREF m_clrBack=GetSysColor(COLOR_MENU);
    CBrush m_brBackground,m_brSelect;
    CPen m_penBack;
    int x0,y0,dy;
    int nIconNormal=-1,xoffset=-1;
    CImageList *bitmap=NULL;
    CFont m_fontMenu;
    LOGFONT m_lf;

    // set some colors and the font
    m_penBack.CreatePen (PS_SOLID,0,GetSysColor(COLOR_MENU));
    m_brBackground.CreateSolidBrush(GetSysColor(COLOR_MENU));
    m_brSelect.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
    ZeroMemory ((PVOID) &m_lf,sizeof (LOGFONT));
    NONCLIENTMETRICS nm;
    nm.cbSize = sizeof (NONCLIENTMETRICS);
    VERIFY (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,nm.cbSize,&nm,0)); 
    m_lf =  nm.lfMenuFont;
    m_fontMenu.CreateFontIndirect (&m_lf);

    // draw the colored rectangle portion
  
    rect.CopyRect(&lpDIS->rcItem);
    rect2=rect;
 
    // draw the up/down/focused/disabled state

    UINT state = lpDIS->itemState;
    CString strText;
    LOGFONT lf;
    lf = m_lf;

    CFont dispFont;
    CFont *pFont=NULL;
      
    if(lpDIS->itemData != NULL){
      nIconNormal = (((BCMenuData*)(lpDIS->itemData))->menuIconNormal);
      xoffset = (((BCMenuData*)(lpDIS->itemData))->xoffset);
      bitmap = (((BCMenuData*)(lpDIS->itemData))->bitmap);
      strText = ((BCMenuData*) (lpDIS->itemData))->GetString();
    
      if(state&ODS_CHECKED && nIconNormal<0){
        if(state&ODS_SELECTED && m_selectcheck>0)checkflag=TRUE;
        else if(m_unselectcheck>0) checkflag=TRUE;
      }
      else if(nIconNormal != -1){
        standardflag=TRUE;
        if(state&ODS_SELECTED && !(state&ODS_GRAYED))selectedflag=TRUE;
        else if(state&ODS_GRAYED) disableflag=TRUE;
      }
    }
    else{
      strText.Empty();
    }

    if(state&ODS_SELECTED){ // draw the down edges

      CPen *pOldPen = pDC->SelectObject (&m_penBack);

      // You need only Text highlight and thats what you get
     
      if(checkflag||standardflag||selectedflag||disableflag||state&ODS_CHECKED)
        rect2.SetRect(rect.left+m_iconX+4+GAP,rect.top,rect.right,rect.bottom);
      pDC->FillRect (rect2,&m_brSelect);

      pDC->SelectObject (pOldPen);
      if((HFONT)dispFont != NULL)dispFont.DeleteObject ();
      dispFont.CreateFontIndirect (&lf);
      crText = GetSysColor(COLOR_HIGHLIGHTTEXT);
    }
    else {
      CPen *pOldPen = pDC->SelectObject (&m_penBack);
      pDC->FillRect (rect,&m_brBackground);
      pDC->SelectObject (pOldPen);

      // draw the up edges

      pDC->Draw3dRect (rect,m_clrBack,m_clrBack);
      if ((HFONT)dispFont != NULL) dispFont.DeleteObject ();
      dispFont.CreateFontIndirect (&lf); //Normal
    }

    // draw the text if there is any
    //We have to paint the text only if the image is nonexistant

    dy = (rect.Height()-4-m_iconY)/2;
    dy = dy<0 ? 0 : dy;

    if(checkflag||standardflag||selectedflag||disableflag){
      rect2.SetRect(rect.left+1,rect.top+1+dy,rect.left+m_iconX+3,
                    rect.top+m_iconY+3+dy);
      pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
      if(checkflag && checkmaps){
        pDC->FillRect (rect2,&m_brBackground);
        rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
                      rect.top+m_iconY+4+dy);
        
		pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
        CPoint ptImage(rect.left+2,rect.top+2+dy);
       
        if(state&ODS_SELECTED)checkmaps->Draw(pDC,1,ptImage,ILD_TRANSPARENT);
        else checkmaps->Draw(pDC,0,ptImage,ILD_TRANSPARENT);
      }
      else if(disableflag){
        if(!selectedflag){
          HBITMAP hbmp=LoadSysColorBitmap(nIconNormal);
          if(hbmp){
            bitmapstandard.Attach(hbmp);
            rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
                          rect.top+m_iconY+4+dy);
            pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
            if(disable_old_style)
              DitherBlt(lpDIS->hDC,rect.left+2,rect.top+2+dy,m_iconX,m_iconY,
                       (HBITMAP)(bitmapstandard),xoffset*m_iconX,0);
            else
              DitherBlt2(pDC,rect.left+2,rect.top+2+dy,m_iconX,m_iconY,
                         bitmapstandard,xoffset*m_iconX,0);
            bitmapstandard.DeleteObject();
          }
        }
      }
      else if(selectedflag){
        pDC->FillRect (rect2,&m_brBackground);
        rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
                      rect.top+m_iconY+4+dy);
        if (IsNewShell()){
          if(state&ODS_CHECKED)
            pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),
                            GetSysColor(COLOR_3DHILIGHT));
          else
            pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DHILIGHT),
                            GetSysColor(COLOR_3DSHADOW));
        }
        CPoint ptImage(rect.left+2,rect.top+2+dy);
        if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
      }
      else{
        if(state&ODS_CHECKED){
          CBrush brush;
          COLORREF col =GetSysColor(COLOR_3DLIGHT);
          brush.CreateSolidBrush(col);
          pDC->FillRect(rect2,&brush);
          brush.DeleteObject();
          rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
                        rect.top+m_iconY+4+dy);
          if (IsNewShell())
            pDC->Draw3dRect(rect2,GetSysColor(COLOR_3DSHADOW),
                            GetSysColor(COLOR_3DHILIGHT));
        }
        else{
          pDC->FillRect (rect2,&m_brBackground);
          rect2.SetRect(rect.left,rect.top+dy,rect.left+m_iconX+4,
                        rect.top+m_iconY+4+dy);
          pDC->Draw3dRect (rect2,m_clrBack,m_clrBack);
        }
        CPoint ptImage(rect.left+2,rect.top+2+dy);
        if(bitmap)bitmap->Draw(pDC,xoffset,ptImage,ILD_TRANSPARENT);
      }
    }
    if(nIconNormal<0 && state&ODS_CHECKED && !checkflag){
      rect2.SetRect(rect.left+1,rect.top+2+dy,rect.left+m_iconX+1,
                    rect.top+m_iconY+2+dy);
      CMenuItemInfo info;
      info.fMask = MIIM_CHECKMARKS;
      ::GetMenuItemInfo((HMENU)lpDIS->hwndItem,lpDIS->itemID,
                      MF_BYCOMMAND, &info);
      if(state&ODS_CHECKED || info.hbmpUnchecked) {
        Draw3DCheckmark(pDC, rect2, state&ODS_SELECTED,
                        state&ODS_CHECKED ? info.hbmpChecked :
                        info.hbmpUnchecked);
      }
    }

    //This is needed always so that we can have the space for check marks

    x0=rect.left;y0=rect.top;
    rect.left = rect.left + m_iconX + 8 + GAP; 

    if(!strText.IsEmpty()){

      CRect rectt(rect.left,rect.top-1,rect.right,rect.bottom-1);

      //   Find tabs

      CString leftStr,rightStr;
      leftStr.Empty();rightStr.Empty();
      int tablocr=strText.ReverseFind(_T('\t'));
      if(tablocr!=-1){
        rightStr=strText.Mid(tablocr+1);
        leftStr=strText.Left(strText.Find(_T('\t')));
        rectt.right-=m_iconX;
      }
      else leftStr=strText;

      int iOldMode = pDC->GetBkMode();
      pDC->SetBkMode( TRANSPARENT);

      // Draw the text in the correct colour:

      UINT nFormat  = DT_LEFT|DT_SINGLELINE|DT_VCENTER;
      UINT nFormatr = DT_RIGHT|DT_SINGLELINE|DT_VCENTER;
      if(!(lpDIS->itemState & ODS_GRAYED)){
        pDC->SetTextColor(crText);
        pDC->DrawText (leftStr,rectt,nFormat);
        if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
      }
      else{

        // Draw the disabled text
        if(!(state & ODS_SELECTED)){
          RECT offset = *rectt;
          offset.left+=1;
          offset.right+=1;
          offset.top+=1;
          offset.bottom+=1;
          pDC->SetTextColor(GetSysColor(COLOR_BTNHILIGHT));
          pDC->DrawText(leftStr,&offset, nFormat);
          if(tablocr!=-1) pDC->DrawText (rightStr,&offset,nFormatr);
          pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
          pDC->DrawText(leftStr,rectt, nFormat);
          if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
        }
        else{
        // And the standard Grey text:
          pDC->SetTextColor(m_clrBack);
          pDC->DrawText(leftStr,rectt, nFormat);
          if(tablocr!=-1) pDC->DrawText (rightStr,rectt,nFormatr);
        }
      }
      pFont = pDC->SelectObject (&dispFont);
      pDC->SetBkMode( iOldMode );
      pDC->SelectObject (pFont); //set it to the old font
    }

    m_penBack.DeleteObject();
    m_brBackground.DeleteObject();
    m_fontMenu.DeleteObject();
    m_brSelect.DeleteObject();
    dispFont.DeleteObject ();
  }
}


/*
==========================================================================
void BCMenu::MeasureItem(LPMEASUREITEMSTRUCT)
---------------------------------------------

Called by the framework when it wants to know what the width and height
of our item will be.  To accomplish this we provide the width of the
icon plus the width of the menu text, and then the height of the icon.
 
==========================================================================
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -