?? peepermenu.cpp
字號:
///////////////////////////////////////////////////////////////////////////////
// 遠程控制軟件-偷窺者 菜單類 //
// 日期:2001/10/02 //
// 作者:劉東發 //
// Email:dongfa@yeah.net //
// http://dongfa.yeah.net //
// OICQ:5584173 阿東 //
// 作者聲明: //
// 此部分代碼全是作者所寫,可以隨便傳播,但要保持文件的完整性,有問題 //
// 或者意見請來信,謝謝! //
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "PeeperMenu.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define MEMU_SYSCOLOR GetSysColor(COLOR_MENU)
#define TOP_COLOR RGB(128, 128, 128)
#define BOTTOM_COLOR RGB(255, 255, 255)
CPeeperMenu::CPeeperMenu()
{
m_nMenuHeight = 24;
m_nMenuWidth = 48;
m_nSepHeight = 12;
m_nSpace = 4;
m_ilImageList.DeleteImageList();
m_uIDArray.RemoveAll();
m_uBackBmpID = 0;
m_szMenuBk = CSize(0, 0);
m_szMenuIcon = CSize(0, 0);
}
CPeeperMenu::~CPeeperMenu()
{
ClearMemory();
}
void CPeeperMenu::ClearMemory()
{
POSITION pos = m_obMenuList.GetHeadPosition();
while(pos)
{
LPPEEPERMENU lpMenu = (LPPEEPERMENU)m_obMenuList.GetNext(pos);
if(lpMenu)
{
delete lpMenu;
lpMenu = NULL;
}
}
m_obMenuList.RemoveAll();
m_ilImageList.DeleteImageList();
m_uIDArray.RemoveAll();
}
BOOL CPeeperMenu::ChangeStyle(HMENU hMenu, BOOL bTop)
{
CMenu *pMenu = CMenu::FromHandle(hMenu);
if(pMenu != NULL)
{
for(UINT i = 0; i < pMenu->GetMenuItemCount(); i ++)
{
LPPEEPERMENU lpMenu = new PEEPERMENU;
lpMenu->nMenuID = pMenu->GetMenuItemID(i);
if(lpMenu->nMenuID < 0 && bTop)
{
lpMenu->nMenuID = -2;
}
pMenu->GetMenuString(i, lpMenu->strText, MF_BYPOSITION);
pMenu->ModifyMenu(i, MF_BYPOSITION | MF_OWNERDRAW,
lpMenu->nMenuID, LPCTSTR(lpMenu));
CMenu *pSubMenu = pMenu->GetSubMenu(i);
if(pSubMenu && lpMenu->nMenuID != -2 && !bTop)
{
lpMenu->nMenuID = -1;
}
m_obMenuList.AddTail((CObject *)lpMenu);
if(pSubMenu)
{
ChangeStyle(pSubMenu->GetSafeHmenu());
}
}
}
return TRUE;
}
BOOL CPeeperMenu::LoadMenu(UINT uMenuID, UINT uToolBarID, CSize sz)
{
BOOL bRet = CMenu::LoadMenu(uMenuID);
ChangeStyle(GetSafeHmenu(), TRUE);
return bRet;
}
BOOL CPeeperMenu::AttachMenu(HMENU hMenu, UINT uToolBarID, CSize sz)
{
ClearMemory();
Attach(hMenu);
ChangeStyle(GetSafeHmenu(), TRUE);
m_szMenuIcon = sz;
int nRet = GetImageFromToolBar(uToolBarID, sz, &m_ilImageList, &m_uIDArray);
return TRUE;
}
BOOL CPeeperMenu::DetachMenu()
{
ClearMemory();
Detach();
return TRUE;
}
void CPeeperMenu::AppendMenu(UINT uID, CString strText)
{
}
void CPeeperMenu::SetBkImage(UINT uID)
{
m_uBackBmpID = uID;
CBitmap bmp;
bmp.LoadBitmap(m_uBackBmpID);
if(bmp.GetSafeHandle() != NULL)
{
BITMAP bm;
bmp.GetBitmap(&bm);
m_szMenuBk.cx = bm.bmWidth;
m_szMenuBk.cy = bm.bmHeight;
}
else
{
m_szMenuBk = CSize(0, 0);
}
}
int CPeeperMenu::GetIndexByID(UINT uID)
{
for(int i = 0; i < m_uIDArray.GetSize(); i ++)
{
if(uID == m_uIDArray[i])
{
ASSERT(i < m_ilImageList.GetImageCount());
return i;
}
}
return -1;
}
int CPeeperMenu::AddToolBar(UINT uToolBarID, CSize sz)
{
CImageList ilImage;
CUIntArray uIDArray;
int nRet = GetImageFromToolBar(uToolBarID, sz, &ilImage, &uIDArray);
if(nRet > 0)
{
for(int i = 0; i < ilImage.GetImageCount(); i ++)
{
HICON hIcon = ilImage.ExtractIcon(i);
if(hIcon != NULL)
{
m_ilImageList.Add(hIcon);
m_uIDArray.Add(uIDArray[i]);
}
}
}
return nRet;
}
int CPeeperMenu::GetImageFromToolBar(UINT uToolBarID, CSize sz, CImageList *pImageList,
CUIntArray *uIDArray)
{
if(uToolBarID <= 0 || pImageList == NULL || uIDArray == NULL)
return -1;
CToolBar wndToolBar;
if(!wndToolBar.Create(AfxGetMainWnd()) || !wndToolBar.LoadToolBar(uToolBarID))
{
return -1;
}
int nCount = wndToolBar.GetCount();
if(nCount <= 0)
{
return -1;
}
pImageList->Create(uToolBarID, sz.cx, sz.cy, MEMU_SYSCOLOR);
int nImageCount = pImageList->GetImageCount();
for(int i = 0; i < nCount; i ++)
{
UINT uID = wndToolBar.GetItemID(i);
if(uID != ID_SEPARATOR)
{
uIDArray->Add(uID);
}
}
int nSize = uIDArray->GetSize();
ASSERT(nSize == nImageCount);
return nSize;
}
int CPeeperMenu::DrawBmp(CDC *pDC, UINT uID, CRect rect, BOOL bStretch)
{
HRSRC hSrc = FindResource(NULL, MAKEINTRESOURCE(uID), RT_BITMAP);
if(hSrc)
{
CBitmap bmp;
bmp.LoadBitmap(uID);
if(bmp.GetSafeHandle() != NULL)
{
BITMAP bm;
bmp.GetBitmap(&bm);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap *pOldBmp = memDC.SelectObject(&bmp);
if(bStretch)
{
pDC->SetStretchBltMode(COLORONCOLOR);
pDC->StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&memDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
}
else
{
pDC->BitBlt(rect.left, rect.top, bm.bmWidth, bm.bmHeight,
&memDC, 0, 0, SRCCOPY);
}
memDC.SelectObject(&pOldBmp);
memDC.DeleteDC();
}
}
return 0;
}
void CPeeperMenu::DrawGradRect(CDC *pDC, CRect rect, COLORREF cr1,
COLORREF cr2, BOOL bHor)
{
int r1 = GetRValue(cr1);
int g1 = GetGValue(cr1);
int b1 = GetBValue(cr1);
int r2 = GetRValue(cr2);
int g2 = GetGValue(cr2);
int b2 = GetBValue(cr2);
if(bHor)
{
float dr = ((float)(r2 - r1))/(float)(rect.Width());
float dg = ((float)(g2 - g1))/(float)(rect.Width());
float db = ((float)(b2 - b1))/(float)(rect.Width());
for(int i = rect.left; i < rect.right; i ++)
{
int r = r1 + (int)(dr*((float)(i - rect.left)));
int g = g1 + (int)(dg*((float)(i - rect.left)));
int b = b1 + (int)(db*((float)(i - rect.left)));
CPen pen(PS_SOLID, 1, RGB(r, g, b));
CPen *old = pDC->SelectObject(&pen);
pDC->MoveTo(i, rect.top);
pDC->LineTo(i, rect.bottom);
pDC->SelectObject(old);
}
}
else
{
float dr = ((float)(r2 - r1))/(float)(rect.Height());
float dg = ((float)(g2 - g1))/(float)(rect.Height());
float db = ((float)(b2 - b1))/(float)(rect.Height());
for(int i = rect.top; i < rect.bottom; i ++)
{
int r = r1 + (int)(dr*((float)(i - rect.top)));
int g = g1 + (int)(dg*((float)(i - rect.top)));
int b = b1 + (int)(db*((float)(i - rect.top)));
CPen pen(PS_SOLID, 1, RGB(r, g, b));
CPen *old = pDC->SelectObject(&pen);
pDC->MoveTo(rect.left, i);
pDC->LineTo(rect.right, i);
pDC->SelectObject(old);
}
}
}
void CPeeperMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
LPPEEPERMENU lpMenu = (LPPEEPERMENU)(lpDIS->itemData);
if(!AfxIsValidAddress(lpMenu, sizeof(PEEPERMENU)))
return ;
CDC *pDC = CDC::FromHandle(lpDIS->hDC);
const CRect rect = lpDIS->rcItem;
BOOL bIsSelected = FALSE;
BOOL bIsChecked = FALSE;
BOOL bIsGrayed = FALSE;
BOOL bHasImage = FALSE;
//取得菜單狀態
bIsSelected = (lpDIS->itemState & ODS_SELECTED);
bIsChecked = (lpDIS->itemState & ODS_CHECKED);
bIsGrayed = (lpDIS->itemState & ODS_GRAYED);
CRect rc = rect;
pDC->SetBkMode(TRANSPARENT);
pDC->SelectStockObject(NULL_BRUSH);
if(lpMenu->nMenuID == 0)// 分隔條
{
CRect rc = rect;
rc.top = rect.Height()/2 + rect.top;
rc.bottom = rc.top + 2;
rc.left += (m_szMenuBk.cx + m_nSpace);
pDC->Draw3dRect(rc, TOP_COLOR, BOTTOM_COLOR);
}
else // 顯示文字或者圖標
{
//先畫圖標
int nIndex = GetIndexByID(lpMenu->nMenuID);
if(nIndex >= 0) // 如果有圖片標
{
bHasImage = TRUE; //設置有圖像標志
rc = rect;
rc.left += (m_szMenuBk.cx + m_nSpace);
int n = (rect.Height() - m_szMenuIcon.cy)/2;
rc.top += (n + 1);
m_ilImageList.Draw(pDC, nIndex, CPoint(rc.left, rc.top), ILD_TRANSPARENT);
CRect rc1 = CRect(rc.left, rc.top, rc.left + m_szMenuIcon.cx,
rc.top + m_szMenuIcon.cy);
rc = rc1;
rc.InflateRect(m_nSpace/2, m_nSpace/2);
if(bIsChecked) //如果有圖像并且是Check狀態
{
pDC->Draw3dRect(rc, TOP_COLOR, BOTTOM_COLOR);
}
else // 沒有Check但是有圖像
{
rc.InflateRect(1, 1);
if(bIsSelected)
{
pDC->Draw3dRect(rc, BOTTOM_COLOR, TOP_COLOR);
}
else
{
pDC->Draw3dRect(rc, MEMU_SYSCOLOR, MEMU_SYSCOLOR);
}
}
}
else // 如果沒有使用缺省的
{
bHasImage = FALSE; //設置無圖像標志
if(bIsChecked)
{
bHasImage = TRUE; //設置有圖像標志
rc = rect;
rc.left += (m_szMenuBk.cx + m_nSpace);
int n = (rect.Height() - m_szMenuIcon.cy)/2;
rc.top += (n + 1);
CRect rc1 = CRect(rc.left, rc.top, rc.left + m_szMenuIcon.cx,
rc.top + m_szMenuIcon.cy);
pDC->SetTextColor(RGB(0, 64, 255));
pDC->DrawText(_T("√"), &rc1, DT_EXPANDTABS | DT_VCENTER |
DT_SINGLELINE | DT_CENTER);
rc = rc1;
rc.left += 1;
rc.top += 1;
pDC->DrawText(_T("√"), &rc, DT_EXPANDTABS | DT_VCENTER |
DT_SINGLELINE | DT_CENTER);
rc1.InflateRect(m_nSpace/2, m_nSpace/2);
pDC->Draw3dRect(rc1, TOP_COLOR, BOTTOM_COLOR);
}
}
//顯示菜單文字
if(bIsGrayed) // 是禁止菜單
{
rc = rect;
rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*2);
rc.DeflateRect(0, m_nSpace/2, 0, m_nSpace/2 - 1);
if(bIsSelected) // 如果是禁止菜單,并且是被選擇
{
CRect rc1 = rc;
if(!bHasImage)
{
rc1.left -= (m_szMenuIcon.cx + m_nSpace);
}
DrawGradRect(pDC, rc1, RGB(64, 0, 255), RGB(192, 192, 192));
if(lpMenu->strText.GetLength() > 0)
{
rc = rect;
rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*3);
pDC->SetTextColor(TOP_COLOR);
pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
}
}
else // 如果是禁止菜單但沒有被選擇
{
CRect rc1 = rc;
if(!bHasImage)
{
rc1.left -= (m_szMenuIcon.cx + m_nSpace);
}
pDC->FillSolidRect(rc1, MEMU_SYSCOLOR);
if(lpMenu->strText.GetLength() > 0)
{
rc = rect;
rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*3);
pDC->SetTextColor(BOTTOM_COLOR);
pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
pDC->SetTextColor(TOP_COLOR);
rc.left -= 1;
rc.top -= 1;
pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS | DT_VCENTER | DT_SINGLELINE);
}
}
}
else // 不是禁止菜單
{
if(lpMenu->nMenuID == -2) // 頂層菜單
{
rc = rect;
rc.left += m_nSpace*2;
if(bIsSelected) // 是選擇狀態
{
pDC->Draw3dRect(rc, TOP_COLOR, BOTTOM_COLOR);
pDC->SetTextColor(RGB(0, 0, 128));
}
else // 不是選擇狀態
{
pDC->Draw3dRect(rc, MEMU_SYSCOLOR, MEMU_SYSCOLOR);
pDC->SetTextColor(RGB(64, 0, 128));
}
rc.left += m_nSpace;
if(lpMenu->strText.GetLength() > 0)
{
pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS |
DT_VCENTER | DT_SINGLELINE);
}
}
else // 不是頂層菜單,是彈出菜單或者一個菜單項目
{
rc = rect;
rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*2);
rc.DeflateRect(0, m_nSpace/2, 0, m_nSpace/2 - 1);
if(bIsSelected)
{
CRect rc1 = rc;
if(!bHasImage)
{
rc1.left -= (m_szMenuIcon.cx + m_nSpace);
}
DrawGradRect(pDC, rc1, RGB(64, 0, 255), RGB(192, 192, 192));
pDC->SetTextColor(BOTTOM_COLOR);
}
else
{
CRect rc1 = rc;
if(!bHasImage)
{
rc1.left -= (m_szMenuIcon.cx + m_nSpace);
}
pDC->FillSolidRect(rc1, MEMU_SYSCOLOR);
pDC->SetTextColor(RGB(64, 0, 128));
}
if(lpMenu->strText.GetLength() > 0)
{
rc = rect;
rc.left += (m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*3);
pDC->DrawText(lpMenu->strText, &rc, DT_EXPANDTABS |
DT_VCENTER | DT_SINGLELINE);
}
}
}
}
if((lpDIS->itemAction & ODA_DRAWENTIRE) && lpMenu->nMenuID != -2)
{
// DrawBmp(pDC, m_uBackBmpID, CRect(1, 1, -1, -1), FALSE);
DrawGradRect(pDC, CRect(0, 0, m_szMenuBk.cx, rect.bottom),
RGB(0, 0, 0), RGB(0, 0, 255), FALSE);
}
}
void CPeeperMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{
LPPEEPERMENU lpMenu = (LPPEEPERMENU)(lpMIS->itemData);
if(lpMenu->nMenuID == 0)
{
lpMIS->itemHeight = m_nSepHeight;
lpMIS->itemWidth = 100;
}
else
{
lpMIS->itemWidth = m_nMenuWidth; // default
CString strText = lpMenu->strText;
int nLen = strText.GetLength();
if(nLen > 0)
{
CFont fontMenu;
LOGFONT lf;
ZeroMemory(&lf, sizeof(LOGFONT));
NONCLIENTMETRICS nm;
nm.cbSize = sizeof(NONCLIENTMETRICS);
VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
nm.cbSize, &nm, 0));
lf = nm.lfMenuFont;
fontMenu.CreateFontIndirect(&lf);
SIZE sz;
CDC *pDC = AfxGetMainWnd()->GetDC();
CFont *old = pDC->SelectObject(&fontMenu);
::GetTextExtentPoint32(pDC->GetSafeHdc(), strText, strText.GetLength(), &sz);
if(lpMenu->nMenuID == -2)
{
lpMIS->itemWidth = sz.cx + m_nSpace;
}
else
{
lpMIS->itemWidth = sz.cx + m_szMenuBk.cx + m_szMenuIcon.cx + m_nSpace*4;
}
pDC->SelectObject(&old);
AfxGetMainWnd()->ReleaseDC(pDC);
fontMenu.DeleteObject();
}
lpMIS->itemHeight = m_nMenuHeight;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -