/**********************************************************************
// 类Office XP、OICQ外观的菜单类
// -- 抽取自 临风程序界面类库ringdows.lib
//
//作者:临风 整理:YZ
//
//版本:0.1
//
//声明: 本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到
// 你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在
// 修改的同时给作者一份同样的副本。
// 本类库不得用于任何商业用途,如确实需要,请与作者联系。
//
//e-mail:ringphone@sina.com
//
//原文件名:rcm.cpp
//
//说明:ringmenu 类定义文件
//
**********************************************************************/
//#define OEMRESOURCE // 此定义应加到stdafx.h中的首部
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include "rcm.h"
RingMenu::RingMenu(HINSTANCE hInst)
{
m_hMenu = NULL;
m_hCurrMenu = NULL;
m_hInst = hInst;
}
RingMenu::RingMenu(HINSTANCE hInst, LPCTSTR lpMenuname)
{
m_hMenu = NULL;
m_hCurrMenu = NULL;
m_hInst = hInst;
Load(lpMenuname);
}
RingMenu::~RingMenu()
{
m_hCurrMenu = NULL;
if(m_hMenu != NULL)
DestroyMenu(m_hMenu);
}
BOOL RingMenu::Load(LPCTSTR lpMenuname)
{
if(m_hMenu != NULL)
return FALSE;
else
{
m_hMenu = LoadMenu(m_hInst,lpMenuname);
if(m_hMenu)
{
m_hCurrMenu = m_hMenu;
return TRUE;
}
}
return FALSE;
}
BOOL RingMenu::LoadPopup(LPCTSTR lpMenuname,UINT nIndex)
{
if(!m_hMenu)
m_hMenu = LoadMenu(m_hInst,lpMenuname);
m_hCurrMenu = GetSubMenu(m_hMenu,nIndex);
return (BOOL)m_hCurrMenu;
}
BOOL RingMenu::Attach(HMENU hMenu)
{
m_hMenu = hMenu;
return TRUE;
}
HMENU RingMenu::Detach()
{
HMENU hTemp= m_hMenu;
m_hMenu = NULL;
return hTemp;
}
BOOL RingMenu::Create()
{
if(m_hMenu != NULL)
return FALSE;
else
{
m_hMenu = CreateMenu();
if(m_hMenu)
{
m_hCurrMenu = m_hMenu;
return TRUE;
}
}
return FALSE;
}
BOOL RingMenu::CreatePopup()
{
if(m_hMenu != NULL)
return FALSE;
else
{
m_hMenu = CreatePopupMenu();
if(m_hMenu)
{
m_hCurrMenu = m_hMenu;
return TRUE;
}
}
return FALSE;
}
BOOL RingMenu::Popup(HWND hWnd,int x,int y)
{
if(m_hCurrMenu != NULL)
{
//以下两行语句防止菜单弹出后鼠标在菜单外点击菜单不消失
SetForegroundWindow(hWnd);
SetActiveWindow(hWnd);
if(x == -999 && y == -999)
{
POINT pt;
GetCursorPos(&pt);
x = pt.x;
y = pt.y;
}
TrackPopupMenuEx(m_hCurrMenu,
TPM_LEFTALIGN | TPM_TOPALIGN | // default values
TPM_HORIZONTAL | TPM_LEFTBUTTON | // equivalent to 0
TPM_RIGHTBUTTON, // Right selection
x,y,
hWnd,
NULL);
return TRUE;
}
return FALSE;
}
BOOL RingMenu::Insert(UINT uid,UINT nIndex,LPSTR szText,UINT flag)
{
MENUITEMINFO mi;
if(!m_hCurrMenu)
return FALSE;
mi.cbSize = sizeof(mi);
mi.fMask = MIIM_TYPE | MIIM_ID;
mi.wID = uid;
mi.fType = MFT_STRING;
mi.fState = MFS_DEFAULT;
mi.dwTypeData = szText;
mi.cch = strlen(szText);
return InsertMenuItem(m_hCurrMenu,nIndex,flag,&mi);
}
BOOL RingMenu::InsertSep(UINT nIndex,UINT flag)
{
MENUITEMINFO mi;
if(!m_hCurrMenu)
return FALSE;
mi.cbSize=sizeof(mi);
mi.fMask=MIIM_TYPE | MIIM_ID;
mi.fType=MFT_SEPARATOR;
mi.fState=MFS_DEFAULT;
return InsertMenuItem(m_hCurrMenu,nIndex,flag,&mi);
}
BOOL RingMenu::Delete(UINT nIndex,UINT uPos)
{
if(!m_hCurrMenu)
return FALSE;
return DeleteMenu(m_hCurrMenu,nIndex,uPos);
}
//根据菜单项ID得到序号
int RingMenu::GetItemIndex(UINT uIndex)
{
MENUITEMINFO mi;
mi.cbSize=sizeof(mi);
mi.fMask = MIIM_ID;
if(!GetMenuItemInfo(m_hCurrMenu,uIndex,FALSE,&mi))
return -1;
int nItem = GetMenuItemCount(m_hCurrMenu);
while((--nItem)>=0)
{
if(mi.wID == uIndex)
return nItem;
}
return nItem;
}
//根据菜单项序号得到ID
int RingMenu::GetItemId(UINT uIndex)
{
MENUITEMINFO mi;
mi.cbSize=sizeof(mi);
mi.fMask = MIIM_ID;
if(!GetMenuItemInfo(m_hCurrMenu,uIndex,TRUE,&mi))
return -1;
else
return mi.wID;
}
HMENU RingMenu::GetItem(UINT uIndex)
{
return GetSubMenu(m_hCurrMenu,uIndex);
}
void RingMenu::Update(HWND hWnd)
{
DrawMenuBar(hWnd);
}
void RingMenu::SetCheckBmp(UINT uIndex,UINT uFlag,HBITMAP hbmCheck,HBITMAP hbmUncheck)
{
SetMenuItemBitmaps(m_hCurrMenu,uIndex,uFlag,hbmUncheck,hbmCheck);
}
DWORD RingMenu::CheckItem(UINT uIndex,BOOL bChecked,UINT uFlag)
{
UINT flag;
if(bChecked)
flag = MF_CHECKED | uFlag;
else
flag = MF_UNCHECKED | uFlag;
return CheckMenuItem(m_hCurrMenu,uIndex,flag);
}
BOOL RingMenu::CheckRadioItem(UINT idFirst,UINT idEnd,UINT uIndex,UINT uFlag)
{
return CheckMenuRadioItem(m_hCurrMenu,idFirst,idEnd,uIndex,uFlag);
}
void RingMenu::EnableItem(UINT uIndex,BOOL bEnable,UINT uFlag)
{
UINT flag;
if(bEnable)
flag = MF_ENABLED | uFlag;
else
flag = MF_DISABLED | uFlag;
EnableMenuItem(m_hCurrMenu,uIndex,flag);
}
///////////////////////////////////////////////////
//
//RingCoolMenu
//
//说明:
// RingCoolMenu初始化时(当Load菜单或Attach时)会初始化所有子菜单的菜单项
// 设置菜单项为自绘形式,为每一个子菜单构造一个对象,但Load或Attach的菜单
// 的菜单项(即m_hMenu)不做设置,除非构造RingCoolMenu(hMenu,FALSE),这是
// 因为m_hMenu可能是窗口固定菜单或弹出式菜单的父菜单,不恶意使用的话,
// m_hMenu一定是一个Drop-down或Pop-up菜单句柄,设置自绘没有必要,所以如果
// 建立一个RingCoolMenu对象rm,所有设置都应该是调用其子对象(子菜单项)的成
// 员函数,即rm.SubMenu(n)->Func()形式,但这样使用比较麻烦,所以有一个成员
// 数据m_Popup和成员函数LoadPopup起到重定向作用,即可以先调用LoadPopup把一
// 个子菜单项指定给rm,那么以后所有的rm.Func()都会自动重定向到该子菜单。
//
//////////////////////////////////////////////////
HBITMAP RingCoolMenu::m_hbmCheck = NULL;
HBITMAP RingCoolMenu::m_hbmRadio = NULL;
int RingCoolMenu::m_id = 0;
int RingCoolMenu::m_cxFont = 0;
int RingCoolMenu::m_cyFont = 0;
HFONT RingCoolMenu::m_hFont = NULL;
RingCoolMenu::RingCoolMenu(HINSTANCE hInst) : RingMenu(hInst)
{
Init();
}
RingCoolMenu::RingCoolMenu(HINSTANCE hInst, LPCTSTR lpMenuname) : RingMenu(hInst, lpMenuname)
{
Init();
Load(lpMenuname);
}
//参数bParent由InitSubMenu调用,手工调用除非有目的,否则请使用默认参数
RingCoolMenu::RingCoolMenu(HINSTANCE hInst, HMENU hMenu,BOOL bParent) : RingMenu(hInst)
{
Init();
Attach(hMenu);
if(!bParent)
Remap();
}
BOOL RingCoolMenu::Load(LPCTSTR lpMenuname)
{
if(m_hMenu)
return FALSE;
else
{
BOOL bOK = RingMenu::Load(lpMenuname);
InitSubMenu();
return bOK;
}
}
BOOL RingCoolMenu::Attach(HMENU hMenu)
{
if(m_hMenu)
if(m_hMenu == hMenu)
return TRUE;
else
return FALSE;
else
{
m_hMenu = hMenu;
m_hCurrMenu = m_hMenu;
InitSubMenu();
}
return TRUE;
}
HMENU RingCoolMenu::Detach()
{
if(!m_hMenu)
return NULL;
HMENU hTemp = m_hMenu;
Reset();
if(m_lprms != NULL)
m_lprms = (LPRINGMENUSTYLE)Del(m_lprms);
m_hMenu = NULL;
m_hCurrMenu = NULL;
return hTemp;
}
BOOL RingCoolMenu::LoadPopup(LPCTSTR lpMenuname,UINT nIndex)
{
BOOL bOK = RingMenu::LoadPopup(lpMenuname,nIndex);
InitSubMenu();
if(bOK && m_SubMenu)
for(int i=0;i<m_nSubMenuCnt;i++)
if(m_SubMenu[i] && m_hCurrMenu == m_SubMenu[i]->m_hMenu)
{
m_Popup = m_SubMenu[i];
break;
}
return bOK;
}
RingCoolMenu::~RingCoolMenu()
{
if(m_Style.hbrBkg != (HBRUSH)(COLOR_MENU + 1))
DeleteObject(m_Style.hbrBkg);
if(m_Style.hbrHilight != (HBRUSH)(COLOR_HIGHLIGHT + 1))
DeleteObject(m_Style.hbrHilight);
m_Style.crText = GetSysColor(COLOR_HIGHLIGHTTEXT);
m_Style.crTextDef = GetSysColor(COLOR_MENUTEXT);
m_Style.uSelectRect = 0;
m_Style.uMarkerX = 0;
m_Style.uMarkerY = 0;
m_Style.uBkgY = 0;
m_ItemIconPos = 0;
m_Popup = NULL;
m_bInited = FALSE;
m_nSubMenuCnt = 0;
if(m_lprms != NULL)
m_lprms = (LPRINGMENUSTYLE)Del(m_lprms);
if(m_SubMenu)
{
f