📄 cnmenu.cpp
字号:
return CheckMenuRadioItem(m_hCurrMenu,idFirst,idEnd,uIndex,uFlag);}BOOL CNCoolMenu::SetCheckItem(UINT uIndex,int nType){ MENUITEMINFO mi; ZeroMemory(&mi,sizeof(mi)); mi.cbSize=sizeof(mi); mi.fMask = MIIM_CHECKMARKS; GetMenuItemInfo(m_hCurrMenu,uIndex,FALSE,&mi); if(!mi.hbmpChecked && !mi.hbmpUnchecked) if(nType == MENUCHECK_CHECKBOX) mi.hbmpChecked = m_hbmCheck; else mi.hbmpChecked = m_hbmRadio; SetMenuItemInfo(m_hCurrMenu,uIndex,FALSE,&mi); return TRUE;}HBITMAP CNCoolMenu::SetBkg(HBITMAP hbmBkg){ if(m_Popup) return m_Popup->SetBkg(hbmBkg); HBITMAP hbmtemp = m_Style.hbmBkg; m_Style.hbmBkg = hbmBkg; if(hbmBkg) { BITMAP bm; GetObject(hbmBkg,sizeof(BITMAP),&bm); m_Style.uBkgY = (UINT)bm.bmHeight; } else m_Style.uBkgY = 0; return hbmtemp;}void CNCoolMenu::SetColor(COLORREF crBkg,COLORREF crHilight,COLORREF crBkgText,COLORREF crSelText){ if(crBkg != COLOR_PREV && crBkg != COLOR_TRANSPARENT) { if(m_Style.hbrBkg != (HBRUSH)(COLOR_MENU + 1)) DeleteObject(m_Style.hbrBkg); if(crBkg == COLOR_DEF) m_Style.hbrBkg = (HBRUSH)(COLOR_MENU + 1); else m_Style.hbrBkg = CreateSolidBrush(crBkg); } if(crHilight != COLOR_PREV) { if(m_Style.hbrHilight != (HBRUSH)(COLOR_HIGHLIGHT + 1)) DeleteObject(m_Style.hbrHilight); if(crHilight == COLOR_TRANSPARENT) m_Style.hbrHilight = (HBRUSH)GetStockObject(NULL_BRUSH); else if(crHilight == COLOR_DEF) m_Style.hbrHilight = (HBRUSH)(COLOR_HIGHLIGHT + 1); else m_Style.hbrHilight = CreateSolidBrush(crHilight); } if(crBkgText != COLOR_TRANSPARENT && crBkgText != COLOR_PREV) if(crBkgText == COLOR_DEF) m_Style.crTextDef = GetSysColor(COLOR_MENUTEXT); else m_Style.crTextDef = crBkgText; if(crSelText != COLOR_TRANSPARENT && crSelText != COLOR_PREV) if(crSelText == COLOR_DEF) m_Style.crText = GetSysColor(COLOR_HIGHLIGHTTEXT); else m_Style.crText = crSelText; if(m_SubMenu) for(int i=0;i<m_nSubMenuCnt;i++) if(m_SubMenu[i]) m_SubMenu[i]->SetColor(crBkg,crHilight,crBkgText,crSelText);}HBITMAP CNCoolMenu::SetSelectBkg(HBITMAP hbmHilight,COLORREF crText){ HBITMAP hbmtemp = m_Style.hbmHilight; m_Style.hbmHilight = hbmHilight; if(crText != COLOR_TRANSPARENT && crText != COLOR_PREV) if(crText == COLOR_DEF) m_Style.crText = GetSysColor(COLOR_HIGHLIGHTTEXT); else m_Style.crText = crText; if(m_SubMenu) for(int i=0;i<m_nSubMenuCnt;i++) if(m_SubMenu[i]) m_SubMenu[i]->SetSelectBkg(hbmHilight,crText); return hbmtemp;}void CNCoolMenu::SetSelectRectType(UINT uRectStyle){ m_Style.uSelectRect = uRectStyle; if(m_SubMenu) for(int i=0;i<m_nSubMenuCnt;i++) if(m_SubMenu[i]) m_SubMenu[i]->SetSelectRectType(uRectStyle);}HBITMAP CNCoolMenu::SetMarker(HBITMAP hbmMarker){ if(m_Popup) return m_Popup->SetMarker(hbmMarker); HBITMAP hbmtemp = m_Style.hbmMarker; m_Style.hbmMarker = hbmMarker; if(hbmMarker) { BITMAP bm; GetObject(hbmMarker,sizeof(BITMAP),&bm); m_Style.uMarkerX = (UINT)bm.bmWidth; m_Style.uMarkerY = (UINT)bm.bmHeight; } else { m_Style.uMarkerX = 0; m_Style.uMarkerY = 0; } return hbmtemp;}BOOL CNCoolMenu::Remap(){ int nItem = GetMenuItemCount(m_hCurrMenu); MENUITEMINFO mi; int i = 0; if(m_lprms == NULL) { m_nItemCnt = nItem + 1; m_lprms = (LPCNMENUSTYLE)New(m_nItemCnt * sizeof(CNMENUSTYLE)); if(m_lprms == NULL) return FALSE; for(int i=0;i<=nItem;i++) m_lprms[i].uID = 0xffffffff; } else return TRUE; m_Style.nMenuHeight = 0; while ((--nItem)>=0) { ZeroMemory(&mi,sizeof(mi)); mi.cbSize = sizeof(mi); mi.fMask = MIIM_DATA | MIIM_ID | MIIM_TYPE; GetMenuItemInfo(m_hCurrMenu,nItem,TRUE,&mi); if((mi.fType & MFT_SEPARATOR)) { m_Style.nMenuHeight += MENUSEP_HEIGHT; mi.dwItemData = (DWORD)&m_SepData; } else { m_Style.nMenuHeight += m_cyFont; mi.dwItemData = (DWORD)&m_lprms[i]; } if(!(mi.fType & MFT_OWNERDRAW) && !(mi.fType & MFT_BITMAP)) { m_lprms[i].uID = mi.wID; m_lprms[i].pMenu = this; mi.fType |= MFT_OWNERDRAW; SetMenuItemInfo(m_hCurrMenu,nItem,TRUE,&mi); if(!(mi.fType & MFT_SEPARATOR)) i++; } } return TRUE;}void CNCoolMenu::Reset(){ int nItem = GetMenuItemCount(m_hCurrMenu); MENUITEMINFO mi; char txt[MAX_MENUTEXT]; m_Style.nMenuHeight = 0; while ((--nItem)>=0) { ZeroMemory(&mi,sizeof(mi)); mi.cbSize = sizeof(mi); mi.fMask = MIIM_TYPE | MIIM_DATA | MIIM_STATE | MIIM_CHECKMARKS; txt[0] = '\0'; GetMenuString(m_hCurrMenu,nItem,txt,MAX_MENUTEXT,MF_BYPOSITION); GetMenuItemInfo(m_hCurrMenu,nItem,TRUE,&mi); if((mi.fType & MFT_OWNERDRAW)) { mi.fType ^= MFT_OWNERDRAW; mi.dwItemData = NULL; mi.dwTypeData = txt; if(mi.hbmpChecked == m_hbmCheck || mi.hbmpChecked == m_hbmRadio) mi.hbmpChecked = NULL; SetMenuItemInfo(m_hCurrMenu,nItem,TRUE,&mi); } } if(m_SubMenu) for(int i=0;i<m_nSubMenuCnt;i++) if(m_SubMenu[i]) m_SubMenu[i]->Reset();}BOOL CNCoolMenu::Insert(UINT uid,UINT nIndex,LPSTR szText,UINT flag){ if(m_Popup) return m_Popup->Insert(uid,nIndex,szText,flag); if(!m_hMenu) return FALSE; if(!m_lprms) Remap(); MENUITEMINFO mi; BOOL bOK; 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); bOK = InsertMenuItem(m_hMenu,nIndex,flag,&mi); if(bOK) { int nItem = GetMenuItemCount(m_hMenu); int i; for(i=0;i<=nItem;i++) if(m_lprms[i].uID == 0xffffffff) { m_lprms[i].uID = uid; m_lprms[i].pMenu = this; break; } mi.fType |= MFT_OWNERDRAW; mi.fMask = MIIM_DATA | MIIM_TYPE | MIIM_ID; mi.dwItemData = (DWORD)&m_lprms[i]; SetMenuItemInfo(m_hCurrMenu,nIndex,flag,&mi); m_Style.nMenuHeight += m_cyFont; if(i >= m_nItemCnt -1) ResetItemData(); } return bOK;}BOOL CNCoolMenu::InsertSep(UINT nIndex,UINT flag){ if(m_Popup) return m_Popup->InsertSep(nIndex,flag); MENUITEMINFO mi; BOOL bOK; if(!m_hCurrMenu) return FALSE; mi.cbSize=sizeof(mi); mi.fMask = MIIM_DATA | MIIM_TYPE | MIIM_ID; mi.fType=MFT_SEPARATOR | MFT_OWNERDRAW; mi.fState=MFS_DEFAULT; mi.dwItemData = (DWORD)&m_SepData; bOK = InsertMenuItem(m_hCurrMenu,nIndex,flag,&mi); if(bOK) m_Style.nMenuHeight += MENUSEP_HEIGHT; return bOK;}//每个菜单项绑定一个CNMENUSTYLE,当菜单项超出m_lprms长度时,//重新调整该缓冲区,并重新设置菜单项的itemDatavoid CNCoolMenu::ResetItemData(){ int nItem = GetMenuItemCount(m_hMenu); int i = 0; m_nItemCnt += MENU_PER_INSERT + 1; LPCNMENUSTYLE temp = (LPCNMENUSTYLE)New(m_nItemCnt * sizeof(CNMENUSTYLE)); LPCNMENUSTYLE temp1; if(temp == NULL) return; for(int j=0;j<m_nItemCnt;j++) temp[j].uID = 0xffffffff; MENUITEMINFO mi; ZeroMemory(&mi,sizeof(mi)); mi.cbSize = sizeof(mi); mi.fMask = MIIM_ID | MIIM_CHECKMARKS | MIIM_STATE |MIIM_TYPE | MIIM_DATA | MIIM_SUBMENU; while ((--nItem)>=0) { GetMenuItemInfo(m_hMenu,nItem,TRUE,&mi); if((mi.fType & MFT_OWNERDRAW) && !(mi.fType & MFT_SEPARATOR)) { temp1 = (LPCNMENUSTYLE)mi.dwItemData; temp[i] = *temp1; mi.dwItemData = (DWORD)&temp[i]; SetMenuItemInfo(m_hCurrMenu,nItem,TRUE,&mi); i ++; } } Del(m_lprms); m_lprms = temp;}BOOL CNCoolMenu::Delete(UINT nIndex,UINT uPos){ if(m_Popup) return m_Popup->Delete(nIndex,uPos); MENUITEMINFO mi; BOOL bOK; ZeroMemory(&mi,sizeof(mi)); mi.cbSize = sizeof(mi); mi.fMask = MIIM_DATA; GetMenuItemInfo(m_hCurrMenu,nIndex,uPos,&mi); bOK = CNMenu::Delete(nIndex,uPos); if(bOK) { if((mi.fType & MFT_SEPARATOR)) m_Style.nMenuHeight -= MENUSEP_HEIGHT; else { m_Style.nMenuHeight -= m_cyFont; if(mi.dwItemData) { LPCNMENUSTYLE lprms; lprms = (LPCNMENUSTYLE)mi.dwItemData; lprms->hIcon = NULL; lprms->uID = 0xffffffff; } } } return bOK;}void CNCoolMenu::SetItemDrawFunc(FUNC_COOLMENU_DRAWITEM drawer){ if(m_Popup) { m_Popup->SetItemDrawFunc(drawer); return; } if(drawer) m_DrawItemFunc = drawer;}//默认自绘菜单函数void CNCoolMenu_DrawItem_def(CNCoolMenu* rm,LPDRAWITEMSTRUCT lps){ LPCNMENUSTYLE lprms = (LPCNMENUSTYLE)lps->itemData; HDC hDC = lps->hDC; HDC hMemDC = CreateCompatibleDC(hDC); RECT rc = lps->rcItem,rrc; char txt[MAX_MENUTEXT]; txt[0] = '\0'; GetMenuString(rm->m_hCurrMenu,lps->itemID,txt,MAX_MENUTEXT,MF_BYCOMMAND);//绘制版权条 if(rm->m_Style.hbmMarker != NULL) { SelectObject(hMemDC,rm->m_Style.hbmMarker); if((rm->m_Style.nMenuHeight - rc.top) > (int)rm->m_Style.uMarkerY) BitBlt(hDC,rc.left,rc.top,rm->m_Style.uMarkerX,rc.bottom - rc.top,hMemDC,0,0,SRCCOPY); else BitBlt(hDC,rc.left,rc.top,rm->m_Style.uMarkerX,rc.bottom - rc.top,hMemDC,0,rm->m_Style.uMarkerY - rm->m_Style.nMenuHeight + rc.top,SRCCOPY); } rc.left += rm->m_Style.uMarkerX; rrc = rc; rrc.right = rrc.left + rm->m_cyFont; SetBkMode(hDC,TRANSPARENT); FillRect(hDC,&rc,rm->m_Style.hbrBkg);//绘制背景图象 if(rm->m_Style.hbmBkg) { SelectObject(hMemDC,rm->m_Style.hbmBkg); if(rc.top > (int)rm->m_Style.uBkgY) BitBlt(hDC,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,hMemDC,0,rc.top % rm->m_Style.uBkgY,SRCCOPY); else BitBlt(hDC,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,hMemDC,0,rc.top,SRCCOPY); } BOOL bSel = lps->itemState & ODS_SELECTED; if((rc.bottom - rc.top) == MENUSEP_HEIGHT) //是分隔线 { rc.top += 2; rc.bottom -= 2; rc.left += 1; rc.right -= 1; DrawEdge(hDC,&rc,BDR_SUNKENOUTER,BF_RECT); DeleteDC(hMemDC); return; } if(lprms) { BOOL bChecked = lps->itemState & ODS_CHECKED; if(lprms->hIcon) //有图标,绘制图标 { if(bChecked) DrawEdge(hDC,&rrc,BDR_SUNKENOUTER,BF_RECT); else if(bSel) DrawEdge(hDC,&rrc,BDR_RAISEDINNER,BF_RECT); int ext = (rm->m_cyFont - 16) >> 1; DrawIconEx(hDC,rc.left + ext,rc.top + ext,lprms->hIcon,16,16,0,NULL,DI_NORMAL); rrc.right = rc.right; rrc.left += rm->m_cyFont; } else { MENUITEMINFO mi; ZeroMemory(&mi,sizeof(mi)); mi.cbSize=sizeof(mi); mi.fMask = MIIM_CHECKMARKS; GetMenuItemInfo(rm->m_hCurrMenu,lps->itemID,FALSE,&mi); DeleteDC(hMemDC); hMemDC = CreateCompatibleDC(hDC); if(bChecked) SelectObject(hMemDC,mi.hbmpChecked); else SelectObject(hMemDC,mi.hbmpUnchecked); BitBlt(hDC,rc.left,rc.top,rm->m_cyFont,rm->m_cyFont,hMemDC,0,0,SRCAND);//绘制选中图案 if(mi.hbmpChecked || mi.hbmpUnchecked) { if(bChecked && mi.hbmpChecked != rm->m_hbmRadio) DrawEdge(hDC,&rrc,BDR_SUNKENOUTER,BF_RECT); rrc.left += rm->m_cyFont; } rrc.right = rc.right; } } else rrc.right = rc.right; rc.left += rm->m_cyFont + 2; if((lps->itemState & ODS_DISABLED) || (lps->itemState & ODS_GRAYED)) { SetTextColor(hDC,GetSysColor(COLOR_GRAYTEXT)); DrawText(hDC,txt,-1,&rc,DT_LEFT|DT_VCENTER|DT_SINGLELINE); return; } if(bSel) { SetTextColor(hDC,rm->m_Style.crText); if(rm->m_Style.hbmHilight) { SelectObject(hMemDC,rm->m_Style.hbmHilight); BitBlt(hDC,rrc.left,rc.top,rrc.right - rrc.left,rc.bottom - rc.top,hMemDC,rrc.left,0,SRCCOPY); } else FillRect(hDC,&rrc,rm->m_Style.hbrHilight); if(rm->m_Style.uSelectRect) DrawEdge(hDC,&rrc,rm->m_Style.uSelectRect,BF_RECT); } DrawText(hDC,txt,-1,&rc,DT_LEFT|DT_VCENTER|DT_SINGLELINE); DeleteDC(hMemDC);}void CNCoolMenu_DrawItem_XP(CNCoolMenu* rm,LPDRAWITEMSTRUCT lps){ LPCNMENUSTYLE lprms; HDC hDC = lps->hDC; HDC hMemDC = CreateCompatibleDC(hDC); RECT rc = lps->rcItem,rrc; char txt[MAX_MENUTEXT]; txt[0] = '\0'; GetMenuString(rm->m_hCurrMenu,lps->itemID,txt,MAX_MENUTEXT,MF_BYCOMMAND); if(rm->m_Style.hbmMarker != NULL) { SelectObject(hMemDC,rm->m_Style.hbmMarker); if((rm->m_Style.nMenuHeight - rc.top) > (int)rm->m_Style.uMarkerY) BitBlt(hDC,rc.left,rc.top,rm->m_Style.uMarkerX,rc.bottom - rc.top,hMemDC,0,0,SRCCOPY); else BitBlt(hDC,rc.left,rc.top,rm->m_Style.uMarkerX,rc.bottom - rc.top,hMemDC,0,rm->m_Style.uMarkerY - rm->m_Style.nMenuHeight + rc.top,SRCCOPY); } rc.left += rm->m_Style.uMarkerX; rrc = rc; rrc.right = rrc.left + rm->m_cyFont; SetBkMode(hDC,TRANSPARENT); lprms = (LPCNMENUSTYLE)lps->itemData; FillRect(hDC,&rc,rm->m_Style.hbrBkg); if(rm->m_Style.hbmBkg) { SelectObject(hMemDC,rm->m_Style.hbmBkg); if(rc.top > (int)rm->m_Style.uBkgY) BitBlt(hDC,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,hMemDC,0,rc.top % rm->m_Style.uBkgY,SRCCOPY); else BitBlt(hDC,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,hMemDC,0,rc.top,SRCCOPY); } if((rc.bottom - rc.top) == MENUSEP_HEIGHT) { rc.top += 2; rc.bottom -= 2; rc.left += rm->m_cyFont + rm->m_ItemIconPos + 1; rc.right -= 1; DrawEdge(hDC,&rc,BDR_SUNKENOUTER,BF_RECT); rrc.right += rm->m_ItemIconPos; FillRect(hDC,&rrc,(HBRUSH)(COLOR_BTNFACE + 1)); DeleteDC(hMemDC); return; } BOOL bSel = lps->itemState & ODS_SELECTED; if(bSel) { SetTextColor(hDC,rm->m_Style.crText); if(rm->m_Style.hbmHilight) { SelectObject(hMemDC,rm->m_Style.hbmHilight); BitBlt(hDC,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,hMemDC,rc.left,0,SRCCOPY); DeleteDC(hMemDC); } else { if(!rm->m_Style.hPen) rm->m_Style.hPen = CreatePen(PS_SOLID,1,0x00ff0000); SelectObject(hDC,rm->m_Style.hbrHilight); SelectObject(hDC,rm->m_Style.hPen); Rectangle(hDC,rc.left,rc.top,rc.right,rc.bottom); } } else { rrc.right += rm->m_ItemIconPos; FillRect(hDC,&rrc,(HBRUSH)(COLOR_BTNFACE + 1)); rrc.right -= rm->m_ItemIconPos; } rc.left += rm->m_ItemIconPos; if(lprms) { BOOL bChecked = lps->itemState & ODS_CHECKED; if(lprms->hIcon) { int ext = (rm->m_cyFont - 16) >> 1; if(bSel) DrawIconEx(hDC,rc.left + ext - 1,rc.top + ext - 1,lprms->hIcon,16,16,0,NULL,DI_NORMAL); else DrawIconEx(hDC,rc.left + ext,rc.top + ext,lprms->hIcon,16,16,0,NULL,DI_NORMAL); } { MENUITEMINFO mi; ZeroMemory(&mi,sizeof(mi)); mi.cbSize=sizeof(mi); mi.fMask = MIIM_CHECKMARKS; GetMenuItemInfo(rm->m_hCurrMenu,lps->itemID,FALSE,&mi); DeleteDC(hMemDC); hMemDC = CreateCompatibleDC(hDC); if(bChecked) SelectObject(hMemDC,mi.hbmpChecked); else SelectObject(hMemDC,mi.hbmpUnchecked); BitBlt(hDC,rrc.left,rrc.top,rm->m_cyFont,rm->m_cyFont,hMemDC,0,0,SRCAND); if(mi.hbmpChecked || mi.hbmpUnchecked) { if(bChecked && mi.hbmpChecked != rm->m_hbmRadio) DrawEdge(hDC,&rrc,BDR_SUNKENOUTER,BF_RECT); } } } rc.left += rm->m_cyFont + 5; if((lps->itemState & ODS_DISABLED) || (lps->itemState & ODS_GRAYED)) { SetTextColor(hDC,GetSysColor(COLOR_GRAYTEXT)); DrawText(hDC,txt,-1,&rc,DT_LEFT|DT_VCENTER|DT_SINGLELINE); return; } DrawText(hDC,txt,-1,&rc,DT_LEFT|DT_VCENTER|DT_SINGLELINE); DeleteDC(hMemDC);}/////////////////////////////////////////////////////// 通用函数:////////////////////////////////////////////////////void Errmsg(LPSTR format,...){ char buf[MAX_PATH]; va_list ap; va_start(ap, format); vsprintf(buf, format, ap); va_end(ap); MessageBox(GetFocus(),buf,"错误",MB_OK | MB_ICONWARNING);}LPVOID New(DWORD dwSize){ HGLOBAL hgMem; hgMem = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,dwSize); if(hgMem==NULL) { Errmsg("内存分配失败,请检查虚拟内存空间"); return NULL; } return (LPVOID)hgMem;}LPVOID Del(LPVOID lpv){ if(lpv!=NULL) GlobalFree(lpv); return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -