win32menuitem.cpp
来自「这是VCF框架的代码」· C++ 代码 · 共 1,152 行 · 第 1/3 页
CPP
1,152 行
} else { int err = GetLastError(); } } } return false;}void Win32MenuItem::setEnabled( const bool& enabled ){ 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 ( true == enabled ){ info.fState |= MFS_ENABLED; info.fState &= ~MFS_DISABLED; } else { info.fState &= ~MFS_ENABLED; info.fState |= MFS_DISABLED; } SetMenuItemInfo( menuHandle, itemId_, FALSE, &info ); } } }}bool Win32MenuItem::isVisible(){ return true;}void Win32MenuItem::setVisible( const bool& visible ){ int index = menuItem_->getIndex(); if ( true == visible ){ } else { //RemoveMenu( itemHandle_, index, MF_BYPOSITION ); }}bool Win32MenuItem::getRadioItem(){ return false;}void Win32MenuItem::setRadioItem( const bool& value ){ if ( true == menuItem_->isSeparator() ){ return; } int index = menuItem_->getIndex(); //MENUITEMINFO info = {0}; //info.cbSize = sizeof(MENUITEMINFO); //info.fMask = MIIM_TYPE | MIIM_STATE; MenuItem* parent = getParent(); if ( NULL != parent ){ Enumerator<MenuItem*>* children = parent->getChildren(); int count = 0; while ( children->hasMoreElements() ) { count ++; children->nextElement(); } MenuItemPeer* parentPeer = parent->getPeer(); HMENU menuHandle = (HMENU)parentPeer->getMenuID(); CheckMenuRadioItem( menuHandle, 0, count-1, itemId_, MF_BYCOMMAND ); /* if ( NULL != menuHandle ){ if ( GetMenuItemInfo( menuHandle, index, TRUE, &info ) ){ info.fType |= MFT_RADIOCHECK | MFT_STRING; info.dwTypeData = 0; info.cch = 0; if ( true == value ){ info.fState |= MFS_CHECKED; } else { info.fState &= ~MFS_CHECKED; } SetMenuItemInfo( menuHandle, index, TRUE, &info ); } } */ }}void Win32MenuItem::setMenuItem( MenuItem* item ){ menuItem_ = item;}String Win32MenuItem::generateCaption( MenuItem* item, String caption ){ String acceleratorText; VCF::AcceleratorKey* accelerator = item->getAccelerator(); //generate accelerator text if we are not owner drawn if ( !item->canPaint() && (NULL != accelerator) ) { if ( accelerator->hasCtrlKey() ) { acceleratorText += "Ctrl"; } if ( accelerator->hasShiftKey() ) { if ( !acceleratorText.empty() ) { acceleratorText += "+"; } acceleratorText += "Shift"; } if ( accelerator->hasAltKey() ) { if ( !acceleratorText.empty() ) { acceleratorText += "+"; } acceleratorText += "Alt"; } if ( !acceleratorText.empty() ) { acceleratorText += "+"; } acceleratorText += StringUtils::translateVKCodeToString( (VirtualKeyCode)accelerator->getKeyCode() ); } if ( !acceleratorText.empty() ) { caption = caption + "\t" + acceleratorText; } return caption;}void Win32MenuItem::setCaption( const String& caption ){ if ( true == menuItem_->isSeparator() ){ return; } int index = menuItem_->getIndex(); String realCaption = generateCaption( menuItem_, caption ); if ( System::isUnicodeEnabled() ) { MENUITEMINFOW info = {0}; info.cbSize = sizeof(info); info.fMask = MIIM_TYPE; MenuItem* parent = getParent(); if ( NULL != parent ){ MenuItemPeer* parentPeer = parent->getPeer(); HMENU menuHandle = (HMENU)parentPeer->getMenuID(); if ( NULL != menuHandle ){ if ( GetMenuItemInfoW( menuHandle, itemId_, FALSE, &info ) ){ info.cch = realCaption.size(); VCFChar* tmpName = new VCFChar[info.cch+1]; memset( tmpName, 0, (info.cch+1)*sizeof(VCFChar) ); realCaption.copy( tmpName, info.cch ); info.dwTypeData = tmpName; SetMenuItemInfoW( menuHandle, itemId_, FALSE, &info ); delete [] tmpName; } } } } else { MENUITEMINFOA info = {0}; info.cbSize = sizeof(info); info.fMask = MIIM_TYPE; MenuItem* parent = getParent(); if ( NULL != parent ){ MenuItemPeer* parentPeer = parent->getPeer(); HMENU menuHandle = (HMENU)parentPeer->getMenuID(); if ( NULL != menuHandle ){ if ( GetMenuItemInfoA( menuHandle, itemId_, FALSE, &info ) ){ AnsiString tmpCaption = realCaption; info.cch = tmpCaption.size(); char* tmpName = new char[info.cch+1]; memset( tmpName, 0, (info.cch+1)*sizeof(char) ); tmpCaption.copy( tmpName, info.cch ); info.dwTypeData = tmpName; SetMenuItemInfoA( menuHandle, itemId_, FALSE, &info ); delete [] tmpName; } } } }}OSHandleID Win32MenuItem::getMenuID(){ if ( NULL != menuItem_ ){ //throw exception !!! //throw InvalidPointerException(); Menu* menuOwner = menuItem_->getMenuOwner(); if ( NULL == menuOwner ){ //throw exception !!!! //throw InvalidPointerException(); MenuItem* parent = menuItem_->getParent(); while ( parent != NULL ) { menuOwner = parent->getMenuOwner(); if ( NULL != menuOwner ) { break; } parent = parent->getParent(); } } if ( (NULL == itemHandle_) && (NULL != menuOwner) ){ PopupMenu* popupOwner = dynamic_cast<PopupMenu*>( menuOwner ); if ( NULL != popupOwner ){ itemHandle_ = ::CreatePopupMenu(); Win32MenuItem::menuItemHandleMap[itemHandle_] = menuItem_; } else { MenuBar* menuBarOwner = dynamic_cast<MenuBar*>( menuOwner ); if ( NULL != menuBarOwner ){ if ( menuItem_->hasParent() ) { itemHandle_ = ::CreatePopupMenu(); Win32MenuItem::menuItemHandleMap[itemHandle_] = menuItem_; } else { itemHandle_ = ::CreateMenu(); Win32MenuItem::menuItemHandleMap[itemHandle_] = menuItem_; } } else { throw RuntimeException(MAKE_ERROR_MSG("Unknown or Invalid Menu Item owner"), __LINE__); } } if ( NULL == itemHandle_ ){ throw RuntimeException(MAKE_ERROR_MSG("Error allocation Resources for Menu Item Peer"), __LINE__); } } } return (OSHandleID)itemHandle_;}MenuItem* Win32MenuItem::getMenuItemFromID( const uint32 id ){ MenuItem* result = NULL; std::map<uint32, MenuItem*>::iterator found = Win32MenuItem::menuItemMap.find( id ); if ( found != Win32MenuItem::menuItemMap.end() ){ result = found->second; } return result;}MenuItem* Win32MenuItem::getMenuItemFromHandle( HMENU handle ){ MenuItem* result = NULL; std::map<HMENU, MenuItem*>::iterator found = Win32MenuItem::menuItemHandleMap.find( handle ); if ( found != Win32MenuItem::menuItemHandleMap.end() ){ result = found->second; } return result;}void Win32MenuItem::setAcceleratorKey( AcceleratorKey* accelerator ){ //just call set caption to reset the menu item caption, //which will in turn take into consideration the presence of the //accelerator setCaption( menuItem_->getCaption() );}void Win32MenuItem::setAsSeparator( const bool& isSeperator ){ int index = menuItem_->getIndex(); MENUITEMINFO info = {0}; info.cbSize = sizeof(MENUITEMINFO); info.fMask = MIIM_TYPE | 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 ( true == isSeperator ) { info.fType |= MFT_SEPARATOR; } else { info.fType &= ~MFT_SEPARATOR; } SetMenuItemInfo( menuHandle, itemId_, FALSE, &info ); } } }}void Win32MenuItem::fillInMeasureItemInfo( MEASUREITEMSTRUCT& measureItemInfo ){ int index = menuItem_->getIndex(); MENUITEMINFO info = {0}; info.cbSize = sizeof(MENUITEMINFO); info.fMask = MIIM_TYPE; 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 ( ODT_MENU != measureItemInfo.CtlType ) { return; } if ( (info.fType & MFT_SEPARATOR) != 0 ) { // separator: use half system height and zero width measureItemInfo.itemHeight = GetSystemMetrics(SM_CYMENU)>>1; measureItemInfo.itemWidth = 0; } else { // compute size of text: use DrawText with DT_CALCRECT NONCLIENTMETRICS ncInfo; ncInfo.cbSize = sizeof(ncInfo); ::SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof(ncInfo), &ncInfo, 0); HFONT menuHFont = CreateFontIndirect( &ncInfo.lfMenuFont ); if ( NULL != menuHFont ) { String caption = menuItem_->getCaption(); if ( menuItem_->getUseLocaleStrings() ) { caption = System::getCurrentThreadLocale()->translate( caption ); } caption = generateCaption( menuItem_, caption ); HDC dc = ::CreateCompatibleDC( NULL );// screen DC--I won't actually draw on it HFONT oldFont = (HFONT)SelectObject( dc, menuHFont ); RECT rcText = {0,0,0,0}; if ( System::isUnicodeEnabled() ) { ::DrawTextW( dc, caption.c_str(), caption.size(), &rcText, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_CALCRECT); } else { AnsiString tmp = caption; ::DrawTextA( dc, tmp.c_str(), tmp.size(), &rcText, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_CALCRECT); } SelectObject( dc, oldFont ); // height of item is just height of a standard menu item measureItemInfo.itemHeight = maxVal<int>( ::GetSystemMetrics(SM_CYMENU), abs(rcText.bottom - rcText.top) ); // width is width of text plus a bunch of stuff int cx = rcText.right - rcText.left; // text width cx += CXTEXTMARGIN << 1; // L/R margin for readability cx += CXGAP; // space between button and menu text //cx += szButton_.cx<<1; // button width (L=button; R=empty margin) // whatever value I return in lpms->itemWidth, Windows will add the
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?