win32menuitem.cpp

来自「这是VCF框架的代码」· C++ 代码 · 共 1,152 行 · 第 1/3 页

CPP
1,152
字号
//Win32MenuItem.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/ApplicationKitPrivate.h"#include "vcf/ApplicationKit/Win32MenuItem.h"#define BASE_MENU_ID	32000int globalLastMenuID = BASE_MENU_ID;#define CXGAP				1		// num pixels between button and text#define CXTEXTMARGIN		2		// num pixels after hilite to start text#define CXBUTTONMARGIN		2		// num pixels wider button is than bitmap#define CYBUTTONMARGIN		2		// ditto for heightusing namespace VCF;std::map<uint32, MenuItem*> Win32MenuItem::menuItemMap;std::map<HMENU,MenuItem*> Win32MenuItem::menuItemHandleMap;Win32MenuItem::Win32MenuItem( MenuItem* item ):	itemAdded_(false){	menuItem_ = item;	init();}Win32MenuItem::Win32MenuItem():	itemAdded_(false){	init();}Win32MenuItem::~Win32MenuItem(){	std::map<uint32,MenuItem*>::iterator found = menuItemMap.find( itemId_ );	if ( found != menuItemMap.end() ){		menuItemMap.erase( found );	}	std::map<HMENU,MenuItem*>::iterator found2 = Win32MenuItem::menuItemHandleMap.find( itemHandle_ );	if ( found2 != Win32MenuItem::menuItemHandleMap.end() ){		Win32MenuItem::menuItemHandleMap.erase( found2 );	}	//globalLastMenuID --;	if ( ::IsMenu( itemHandle_ ) ){		DestroyMenu( itemHandle_ );	}	else if ( NULL != itemHandle_ ){		if ( ! DestroyMenu( itemHandle_ ) ) {			int err = GetLastError();			//StringUtils::traceWithArgs( "Menu Item handle leak for handle %p with id of: %d, GetLastError(): %d\n", itemHandle_, itemId_, err );		}	}}void Win32MenuItem::init(){	itemHandle_ = NULL;	globalLastMenuID ++;	itemId_ = globalLastMenuID;	menuItemMap[itemId_] = menuItem_;}void Win32MenuItem::insertSimpleMenuItem( MenuItem* child, HMENU menu ){	if ( NULL == menu ) {		return;	}	MenuItemPeer* itemImpl = child->getPeer();	Win32MenuItem* win32ChildImpl = (Win32MenuItem*)itemImpl;		String itemName = child->getCaption();	if ( child->getUseLocaleStrings() ) {		itemName = System::getCurrentThreadLocale()->translate( itemName );	}	itemName = generateCaption( child, itemName );	DWORD mask = MIIM_ID  | MIIM_STATE | MIIM_TYPE;	DWORD type = 0;	DWORD state = MFS_ENABLED;	HMENU subMenu = NULL;	DWORD id = win32ChildImpl->itemId_;	if ( true == child->isSeparator() ){		type |= MFT_SEPARATOR;	}	else {		type = MFT_STRING;	}	//put this back in later	if ( true == child->canPaint() ) {		type |= MFT_OWNERDRAW;	}	if ( child->hasChildren() ){		mask |= MIIM_SUBMENU;		subMenu = (HMENU) itemImpl->getMenuID();	}		if ( System::isUnicodeEnabled() ) {		MENUITEMINFOW info = {0};		info.cbSize = sizeof(info);		info.fMask = mask;		info.fState = state;		info.fType = type;				info.wID = id;		info.hSubMenu = subMenu;		info.cch = itemName.size();		wchar_t* tmpName = new wchar_t[info.cch+1];		memset( tmpName, 0, (info.cch+1)*sizeof(wchar_t) );		itemName.copy( tmpName, info.cch );		info.dwTypeData = tmpName;		if ( InsertMenuItemW( menu, child->getIndex()/*info.wID*/, TRUE, &info ) ) {			win32ChildImpl->itemAdded_ = true;		}		delete [] tmpName;		MenuItem* parentItem = menuItem_->getParent();				if ( NULL != parentItem ) {			int index = menuItem_->getIndex();			Win32MenuItem* win32ParentImpl = (Win32MenuItem*)parentItem->getPeer();			HMENU parentMenuHandle = (HMENU)win32ParentImpl->getMenuID();						MENUITEMINFOW thisInfo = {0};									thisInfo.cbSize = sizeof(thisInfo);			thisInfo.fMask = MIIM_SUBMENU;									if ( NULL != parentMenuHandle ){				if ( ::GetMenuItemInfoW( parentMenuHandle, itemId_, FALSE, &thisInfo ) ){					thisInfo.fMask |= MIIM_SUBMENU;					thisInfo.hSubMenu = (HMENU)getMenuID();					::SetMenuItemInfoW( parentMenuHandle, itemId_, FALSE, &thisInfo );				}				else {					//throw exception				}			}		}	}	else{		MENUITEMINFOA info = {0};		info.cbSize = sizeof(info);		info.fMask = mask;		info.fState = state;		info.fType = type;				info.wID = id;		info.hSubMenu = subMenu;		AnsiString s = itemName;		info.cch = s.size();		char* tmpName = new char[info.cch+1];		memset( tmpName, 0, (info.cch+1) );		s.copy( tmpName, info.cch );		info.dwTypeData = tmpName;		if ( InsertMenuItemA( menu, child->getIndex()/*info.wID*/, TRUE, &info ) ) {			win32ChildImpl->itemAdded_ = true;		}		delete [] tmpName;		MenuItem* parentItem = menuItem_->getParent();				if ( NULL != parentItem ) {			int index = menuItem_->getIndex();			Win32MenuItem* win32ParentImpl = (Win32MenuItem*)parentItem->getPeer();			HMENU parentMenuHandle = (HMENU)win32ParentImpl->getMenuID();			MENUITEMINFOA thisInfo = {0};									thisInfo.cbSize = sizeof(thisInfo);			thisInfo.fMask = MIIM_SUBMENU;									if ( NULL != parentMenuHandle ){				if ( ::GetMenuItemInfoA( parentMenuHandle, itemId_, FALSE, &thisInfo ) ){					thisInfo.fMask |= MIIM_SUBMENU;					thisInfo.hSubMenu = (HMENU)getMenuID();					::SetMenuItemInfoA( parentMenuHandle, itemId_, FALSE, &thisInfo );				}				else {					//throw exception				}			}		}	}		/**	check to see if we have children that have not yet been added	*/	fixChildren( child );	}void Win32MenuItem::fixChildren( MenuItem* child ){	if ( child->hasChildren() ) {		Enumerator<MenuItem*>* children = child->getChildren();		while ( children->hasMoreElements() ) {			MenuItem* item = children->nextElement();			Win32MenuItem* itemPeer = (Win32MenuItem*) item->getPeer();			if ( false == itemPeer->itemAdded_ ) {				item->setMenuOwner( child->getMenuOwner() );				Win32MenuItem* peer = (Win32MenuItem*) child->getPeer();				peer->insertSimpleMenuItem( item, (HMENU)peer->getMenuID() );			}		}	}}void Win32MenuItem::addChild( MenuItem* child ){	VCF_ASSERT( NULL != child );		insertSimpleMenuItem( child, (HMENU)getMenuID() );		//mark the child as being bound to the peer	long state = child->getState();	state |= MenuItem::mdsBoundToMenuPeer;	child->setState( state );}void Win32MenuItem::insertChild( const unsigned long& index, MenuItem* child ){	child->setIndex( index );	insertSimpleMenuItem( child, itemHandle_ );}void Win32MenuItem::deleteChild( MenuItem* child ){	int index = child->getIndex();	Win32MenuItem* peer = (Win32MenuItem*)child->getPeer();	peer->itemAdded_ = false;	DeleteMenu( (HMENU)getMenuID(), peer->itemId_, MF_BYCOMMAND );}void Win32MenuItem::deleteChild( const unsigned long& index ){	MenuItem* child = menuItem_->getChildAt(index);	Win32MenuItem* peer = (Win32MenuItem*)child->getPeer();	peer->itemAdded_ = false;	DeleteMenu( (HMENU)getMenuID(), peer->itemId_, MF_BYCOMMAND );}void Win32MenuItem::clearChildren(){	int count = GetMenuItemCount( itemHandle_ );	for ( int i=0;i<count;i++ ){		if ( !DeleteMenu( itemHandle_, 0, MF_BYPOSITION ) ) {			int err = GetLastError();			StringUtils::traceWithArgs( Format("DeleteMenu( %p, 0, MF_BYPOSITION ) failed,GetLastError(): %d\n") %										itemHandle_ % err );		}	}}bool Win32MenuItem::isChecked(){	if ( true == menuItem_->isSeparator() ){		return false;	}	/**	JC	Fix for bug	[ 1119206 ] Win32MenuItem::isChecked returns "false". Allways!!!	*/	MenuItem* parent = getParent();	if ( NULL != parent ){		MenuItemPeer* parentPeer = parent->getPeer();		HMENU menuHandle = (HMENU)parentPeer->getMenuID();		if ( NULL != menuHandle ){			MENUITEMINFO info = {0};			info.cbSize = sizeof(MENUITEMINFO);			info.fMask = MIIM_STATE;			if ( GetMenuItemInfo( menuHandle, itemId_, FALSE, &info ) ){				return ((info.fState & MFS_CHECKED) != 0) ? true : false;			}		}	}	return false;}void Win32MenuItem::setChecked( const bool& checked ){	if ( true == menuItem_->isSeparator() ){		return;	}	int index = menuItem_->getIndex();	MENUITEMINFO info = {0};	info.cbSize = sizeof(MENUITEMINFO);	info.fMask = MIIM_STATE;	MenuItem* parent = getParent();	if ( NULL != parent ){		MenuItemPeer* parentPeer = parent->getPeer();		HMENU menuHandle = (HMENU)parentPeer->getMenuID();		if ( NULL != menuHandle ){			if ( GetMenuItemInfo( menuHandle, itemId_, FALSE, &info ) ){				if ( checked ){					info.fState |= MFS_CHECKED;					info.fState &= ~MFS_UNCHECKED;				}				else {					info.fState &= ~MFS_CHECKED;					info.fState |= MFS_UNCHECKED;				}				SetMenuItemInfo( menuHandle, itemId_, FALSE, &info );			}		}	}}bool Win32MenuItem::hasParent(){	return false;}MenuItem* Win32MenuItem::getParent(){	return menuItem_->getParent();}MenuItem* Win32MenuItem::getChildAt( const unsigned long& index ){	return NULL;}bool Win32MenuItem::isEnabled(){	if ( true == menuItem_->isSeparator() ){		return false;	}	MenuItem* parent = getParent();	if ( NULL != parent ) {		int index = menuItem_->getIndex();		MENUITEMINFO info = {0};		info.cbSize = sizeof(MENUITEMINFO);		info.fMask = MIIM_STATE;		MenuItemPeer* parentPeer = parent->getPeer();		HMENU menuHandle = (HMENU)parentPeer->getMenuID();		//HMENU menuHandle = (HMENU)getMenuID();		if ( NULL != menuHandle ){			if ( GetMenuItemInfo( menuHandle, itemId_, FALSE, &info ) ){				bool res = ((info.fState == MFS_ENABLED) != 0) ? true : false;				return res;

⌨️ 快捷键说明

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