📄 menuspawn.cpp
字号:
// MenuSpawn.cpp: implementation of the CMenuSpawn class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ToolbarMenuDemoMDI.h"
#include "MenuSpawn.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMenuSpawn::CMenuSpawn()
{
Init();
}
CMenuSpawn::CMenuSpawn(const bool _IsPopup)
{
Init();
bIsPopup = _IsPopup;
}
CMenuSpawn::~CMenuSpawn()
{
if (iSpawnItem > 0)
{
for (int t = 0; t < iSpawnItem; t++)
if (pSpawnItem[t]) delete pSpawnItem[t];
GlobalFree((HGLOBAL) pSpawnItem);
}
if (iImageItem > 0)
{
GlobalFree((HGLOBAL) pImageItem);
}
if (hMenuFont) ::DeleteObject((HGDIOBJ)hMenuFont);
// if (hGuiFont) ::DeleteObject((HGDIOBJ)hGuiFont);
}
void CMenuSpawn::TransparentBlt(CDC * pDestDc, int x, int y, int w, int h, CBitmap * pBmp, int sx, int sy, COLORREF crTransparent)
{
CDC memDC, maskDC, tempDC;
maskDC.CreateCompatibleDC(pDestDc);
CBitmap maskBitmap;
//add these to store return of SelectObject() calls
CBitmap* pOldMemBmp = NULL;
CBitmap* pOldMaskBmp = NULL;
memDC.CreateCompatibleDC(pDestDc);
tempDC.CreateCompatibleDC(pDestDc);
CBitmap bmpImage;
bmpImage.CreateCompatibleBitmap( pDestDc, w, h);
pOldMemBmp = memDC.SelectObject( &bmpImage );
CBitmap * oldBmp = tempDC.SelectObject(pBmp);
memDC.BitBlt( 0,0,w, h, &tempDC, sx, sy, SRCCOPY );
// Create monochrome bitmap for the mask
maskBitmap.CreateBitmap(w, h, 1, 1, NULL);
pOldMaskBmp = maskDC.SelectObject( &maskBitmap );
memDC.SetBkColor(crTransparent);
// Create the mask from the memory DC
maskDC.BitBlt(0, 0, w, h, &memDC, 0, 0, SRCCOPY);
memDC.SetBkColor(RGB(0,0,0));
memDC.SetTextColor(RGB(255,255,255));
memDC.BitBlt(0, 0, w, h, &maskDC, 0, 0, SRCAND);
// Set the foreground to black. See comment above.
pDestDc->SetBkColor(RGB(255,255,255));
pDestDc->SetTextColor(RGB(0,0,0));
pDestDc->BitBlt(x, y, w, h, &maskDC, 0, 0, SRCAND);
// Combine the foreground with the background
pDestDc->BitBlt(x, y, w, h, &memDC, 0, 0, SRCPAINT);
tempDC.SelectObject(oldBmp);
if (pOldMaskBmp) maskDC.SelectObject( pOldMaskBmp );
if (pOldMemBmp) memDC.SelectObject( pOldMemBmp );
}
void CMenuSpawn::Init()
{
crMenuText = GetSysColor(COLOR_MENUTEXT);
crMenuTextSel = GetSysColor(COLOR_HIGHLIGHTTEXT);
cr3dFace = GetSysColor(COLOR_3DFACE);
crMenu = GetSysColor(COLOR_MENU);
crHighlight = GetSysColor(COLOR_HIGHLIGHT);
cr3dHilight = GetSysColor(COLOR_3DHILIGHT);
cr3dShadow = GetSysColor(COLOR_3DSHADOW);
crGrayText = GetSysColor(COLOR_GRAYTEXT);
m_clrBtnFace = GetSysColor(COLOR_BTNFACE);
m_clrBtnHilight = GetSysColor(COLOR_BTNHILIGHT);
m_clrBtnShadow = GetSysColor(COLOR_BTNSHADOW);
iSpawnItem = 0;
pSpawnItem = NULL;
iImageItem = 0;
pImageItem = NULL;
szImage = CSize(20,20);
hMenuFont = NULL;
COLORMAP cMap[3] = {
{ RGB(128,128,128), cr3dShadow },
{ RGB(192,192,192), cr3dFace },
{ RGB(255,255,255), cr3dHilight }
};
CBitmap bmp;
bmp.LoadMappedBitmap(IDB_MENUCHK, 0, cMap, 3);
ilOther.Create(19, 19, ILC_COLOR4|ILC_MASK, 1, 0);
ilOther.Add(&bmp, cr3dFace);
bmp.DeleteObject();
NONCLIENTMETRICS ncm;
memset(&ncm, 0, sizeof(ncm));
ncm.cbSize = sizeof(ncm);
::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (PVOID) &ncm, 0);
hGuiFont = ::CreateFontIndirect(&ncm.lfMenuFont);
bIsPopup = false;
bBackBitmap = false;
}
bool CMenuSpawn::AddToolBarResource(unsigned int resId)
{
HRSRC hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resId), RT_TOOLBAR);
if (hRsrc == NULL) return false;
HGLOBAL hGlb = ::LoadResource(AfxGetResourceHandle(), hRsrc);
if (hGlb == NULL) return false;
ToolBarData* pTBData = (ToolBarData*) ::LockResource(hGlb);
if (pTBData == NULL) return false;
ASSERT(pTBData->wVersion == 1);
CBitmap bmp;
bmp.LoadBitmap(resId);
int nBmpItems = ilList.Add(&bmp, RGB(192,192,192));
bmp.DeleteObject();
WORD* pItem = (WORD*)(pTBData+1);
for(int i=0; i<pTBData->wItemCount; i++, pItem++)
{
if(*pItem != ID_SEPARATOR)
AddImageItem(nBmpItems++, (WORD) *pItem);
}
// ** it seem that Windows doesn't free these resource (from Heitor Tome)
::UnlockResource(hGlb);
::FreeResource(hGlb);
// **
return true;
}
bool CMenuSpawn::LoadToolBarResource(unsigned int resId)
{
HRSRC hRsrc = ::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resId), RT_TOOLBAR);
if (hRsrc == NULL) return false;
HGLOBAL hGlb = ::LoadResource(AfxGetResourceHandle(), hRsrc);
if (hGlb == NULL) return false;
ToolBarData* pTBData = (ToolBarData*) ::LockResource(hGlb);
if (pTBData == NULL) return false;
ASSERT(pTBData->wVersion == 1);
szImage.cx = (int) pTBData->wWidth;
szImage.cy = (int) pTBData->wHeight;
if (ilList.Create(szImage.cx, szImage.cy, ILC_COLOR4|ILC_MASK, pTBData->wItemCount, 0) == false)
return false;
ilList.SetBkColor(cr3dFace);
CBitmap bmp;
bmp.LoadBitmap(resId);
ilList.Add(&bmp, RGB(192,192,192));
bmp.DeleteObject();
WORD* pItem = (WORD*)(pTBData+1);
int nBmpItems = 0;
for(int i=0; i<pTBData->wItemCount; i++, pItem++)
{
if(*pItem != ID_SEPARATOR)
AddImageItem(nBmpItems++, (WORD) *pItem);
}
// ** it seem that Windows doesn't free these resource (from Heitor Tome)
::UnlockResource(hGlb);
::FreeResource(hGlb);
// **
return true;
}
void CMenuSpawn::AddImageItem(const int idx, WORD cmd)
{
if (iImageItem == 0)
pImageItem = (ImageItem *) GlobalAlloc(GPTR, sizeof(ImageItem));
else
pImageItem = (ImageItem *) GlobalReAlloc((HGLOBAL) pImageItem, sizeof(ImageItem) * (iImageItem + 1), GMEM_MOVEABLE|GMEM_ZEROINIT);
ASSERT(pImageItem);
pImageItem[iImageItem].iCmd = (int) cmd;
pImageItem[iImageItem].iImageIdx = idx;
iImageItem ++;
}
void CMenuSpawn::RemapMenu(CMenu * pMenu)
{
static int iRecurse = 0;
iRecurse ++;
ASSERT(pMenu);
int nItem = pMenu->GetMenuItemCount();
while ((--nItem)>=0)
{
UINT itemId = pMenu->GetMenuItemID(nItem);
if (itemId == (UINT) -1)
{
CMenu *pops = pMenu->GetSubMenu(nItem);
if (pops) RemapMenu(pops);
if (bIsPopup || iRecurse > 0)
{
CString cs;
pMenu->GetMenuString(nItem, cs, MF_BYPOSITION);
if (cs != "")
{
SpawnItem * sp = AddSpawnItem(cs, (!bIsPopup && iRecurse == 1) ? -4 : -2);
pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW, (UINT) -1, (LPCTSTR)sp);
}
}
}
else
{
if (itemId != 0)
{
UINT oldState = pMenu->GetMenuState(nItem,MF_BYPOSITION);
if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
{
ASSERT(oldState != (UINT)-1);
CString cs;
pMenu->GetMenuString(nItem, cs, MF_BYPOSITION);
SpawnItem * sp = AddSpawnItem(cs, itemId);
pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
}
}
else
{
UINT oldState = pMenu->GetMenuState(nItem,MF_BYPOSITION);
if (!(oldState&MF_OWNERDRAW) && !(oldState&MF_BITMAP))
{
ASSERT(oldState != (UINT)-1);
SpawnItem * sp = AddSpawnItem("--", -3);
pMenu->ModifyMenu(nItem,MF_BYPOSITION|MF_OWNERDRAW|oldState, (LPARAM)itemId, (LPCTSTR)sp);
}
}
}
}
iRecurse --;
}
CMenuSpawn::SpawnItem * CMenuSpawn::AddSpawnItem(const char * txt, const int cmd)
{
if (iSpawnItem == 0)
pSpawnItem = (SpawnItem **) GlobalAlloc(GPTR, sizeof(SpawnItem));
else
pSpawnItem = (SpawnItem **) GlobalReAlloc((HGLOBAL) pSpawnItem, sizeof(SpawnItem) * (iSpawnItem + 1), GMEM_MOVEABLE|GMEM_ZEROINIT);
ASSERT(pSpawnItem);
SpawnItem * p = new SpawnItem;
ASSERT(p);
pSpawnItem[iSpawnItem] = p;
lstrcpy(p->cText, txt);
p->iCmd = cmd;
if (cmd >= 0) p->iImageIdx = FindImageItem(cmd);
else p->iImageIdx = cmd;
iSpawnItem ++;
return p;
}
int CMenuSpawn::FindImageItem(const int cmd)
{
for (int t = 0; t < iImageItem; t++)
if (pImageItem[t].iCmd == cmd) return pImageItem[t].iImageIdx;
return -1;
}
bool CMenuSpawn::DrawItem(LPDRAWITEMSTRUCT lp)
{
bool res = false;
if (lp->CtlType == ODT_MENU)
{
UINT id = lp->itemID;
UINT state = lp->itemState;
bool bEnab = !(state & ODS_DISABLED);
bool bSelect = (state & ODS_SELECTED) ? true : false;
bool bChecked = (state & ODS_CHECKED) ? true : false;
SpawnItem * pItem = (SpawnItem *) lp->itemData;
if (pItem)
{
CDC * pDC = CDC::FromHandle(lp->hDC);
CFont * pft = CFont::FromHandle((HFONT) hMenuFont ? hMenuFont : hGuiFont);
CFont * of = pDC->SelectObject(pft);
CRect rc(lp->rcItem);
CRect rcImage(rc), rcText(rc);
rcImage.right = rcImage.left + rc.Height();
rcImage.bottom = rc.bottom;
if (bBackBitmap)
{
CDC tempDC;
tempDC.CreateCompatibleDC(pDC);
tempDC.FillSolidRect(rc, crMenu);
CBitmap * ob = tempDC.SelectObject(&bmpBack);
pDC->FillSolidRect(rc, crMenu);
pDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &tempDC, rc.left, rc.top, SRCCOPY );
}
if (pItem->iCmd == -3) // is a separator
{
CPen pnDk(PS_SOLID,1,cr3dShadow);
CPen pnLt(PS_SOLID,1,cr3dHilight);
CPen * opn = pDC->SelectObject(&pnDk);
pDC->MoveTo(rc.left + 2, rc.top + 2);
pDC->LineTo(rc.right - 2, rc.top + 2);
pDC->SelectObject(&pnLt);
pDC->MoveTo(rc.left + 2, rc.top + 3);
pDC->LineTo(rc.right - 2, rc.top + 3);
pDC->SelectObject(opn);
}
else if (pItem->iCmd == -4) // is a title item
{
CString cs(pItem->cText), cs1;
CRect rcBdr(rcText);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -