📄 menu.c
字号:
count ++; pmi = pmi->next; } return -1;}void DrawMenuBarHelper (const MAINWIN* pWin, HDC hdc, const RECT* pClipRect){ PMENUBAR pmb; PMENUITEM pmi; int x, y, inter; int w, h; SIZE size; RECT rc; if (!pWin->hMenu) return; pmb = (PMENUBAR) (pWin->hMenu); if (pmb->class != TYPE_HMENU) return; x = pWin->cl - pWin->left; w = pWin->right - pWin->cl - (pWin->cl - pWin->left); h = GetMainWinMetrics (MWM_MENUBARY) + (GetMainWinMetrics (MWM_MENUBAROFFY)<<1); y = pWin->ct - pWin->top; y -= h; rc.left = x; rc.top = y; rc.right = x + w; rc.bottom = y + h; SelectClipRect (hdc, &rc); if (pClipRect) ClipRectIntersect (hdc, pClipRect); SetBrushColor (hdc, BKC_MENUBAR_NORMAL); FillBox (hdc, x, y, w + 3, h + 3); SetBkColor (hdc, BKC_MENUBAR_NORMAL); SetTextColor (hdc, FGC_MENUBAR_NORMAL); x += GetMainWinMetrics (MWM_MENUBAROFFX); y += GetMainWinMetrics (MWM_MENUBAROFFY); inter = GetMainWinMetrics (MWM_INTERMENUITEMX); pmi = pmb->head; while (pmi) { if (x > pWin->cr) break; mnuGetMenuBarItemSize (pmi, &size); mnuDrawMenuBarItem (hdc, pmi, x, y, size.cx, h); x = x + inter + size.cx; pmi = pmi->next; } }void GUIAPI DrawMenuBar (HWND hwnd){ PMAINWIN pWin; HDC hdc; if (!(pWin = MainWindow (hwnd))) return; if (!pWin->hMenu) return; hdc = GetDC (hwnd); DrawMenuBarHelper (pWin, hdc, NULL); ReleaseDC (hdc);}// function defined in GDI module.void* SaveCoveredScreenBox (int x, int y, int w, int h);void PutSavedBoxOnScreen (int x, int y, int w, int h, void* vbuf);static void mnuGetPopupMenuExtent (PTRACKMENUINFO ptmi){ PTRACKMENUINFO prevtmi; PMENUITEM pmi = ptmi->pmi; PMENUITEM psubmi; int w = 0, h = 0; int mih; int inter; int mioffx, minx; SIZE size; int offx, offy; BOOL has_sub = FALSE; BOOL has_txt = FALSE; mih = GetMainWinMetrics (MWM_MENUITEMY); inter = GetMainWinMetrics (MWM_INTERMENUITEMY); mioffx = GetMainWinMetrics (MWM_MENUITEMOFFX); minx = GetMainWinMetrics (MWM_MENUITEMMINX); ptmi->rc.right = ptmi->rc.left; ptmi->rc.bottom = ptmi->rc.top + GetMainWinMetrics (MWM_MENUTOPMARGIN); if (pmi->mnutype & MFT_OWNERDRAW) { } else if (pmi->mnutype & MFT_SEPARATOR) { pmi->h = GetMainWinMetrics (MWM_MENUSEPARATORY) + (inter<<1); if (minx > w) w = minx; } else if (pmi->mnutype & MFT_BITMAP) { pmi->h = mih + (inter<<1); if (pmi->hbmpChecked->bmWidth > w) w = pmi->hbmpChecked->bmWidth; } else { GetSysTabbedTextExtent ((char*)pmi->typedata, &size); if (pmi->mnutype & MFT_BMPSTRING) size.cx += pmi->hbmpChecked->bmWidth; if (size.cx > w) w = size.cx; pmi->h = mih + (inter<<1); if (pmi->type == TYPE_PPPMENU) pmi->h += (inter<<1); h = pmi->h; has_txt = TRUE; } ptmi->rc.bottom += pmi->h; if (pmi->type == TYPE_PPPMENU) { psubmi = pmi->submenu; } else psubmi = pmi->next; while (psubmi) { if (psubmi->mnutype & MFT_OWNERDRAW) { } else if (psubmi->mnutype & MFT_SEPARATOR) { psubmi->h = GetMainWinMetrics (MWM_MENUSEPARATORY) + (inter<<1); if (minx > w) w = minx; } else if (psubmi->mnutype & MFT_BITMAP) { psubmi->h = mih + (inter<<1); if (psubmi->hbmpChecked->bmWidth > w) w = psubmi->hbmpChecked->bmWidth; } else { psubmi->h = mih + (inter<<1); GetSysTabbedTextExtent ((char*)psubmi->typedata, &size); if (pmi->mnutype & MFT_BMPSTRING) size.cx += pmi->hbmpChecked->bmWidth; if (size.cx > w) w = size.cx; has_sub = TRUE; } ptmi->rc.bottom += psubmi->h; h += psubmi->h; psubmi = psubmi->next; } ptmi->rc.bottom += GetMainWinMetrics (MWM_MENUBOTTOMMARGIN); if (has_txt) w += mioffx; if (has_sub) w += mioffx; w += GetMainWinMetrics (MWM_MENULEFTMARGIN); w += GetMainWinMetrics (MWM_MENURIGHTMARGIN); ptmi->rc.right += w; if (ptmi->rc.right > g_rcScr.right) { if ((prevtmi = ptmi->prev)) offx = prevtmi->rc.right - prevtmi->rc.left + w; else offx = ptmi->rc.right - g_rcScr.right; if (ptmi->rc.left - offx < 0) { ptmi->rc.left = 0; ptmi->rc.right = w; } else { ptmi->rc.left -= offx; ptmi->rc.right -= offx; } } if (ptmi->rc.bottom > g_rcScr.bottom) { offy = ptmi->rc.bottom - g_rcScr.bottom; if (ptmi->rc.top - offy < 0) { ptmi->rc.top = 0; ptmi->rc.bottom = h; } else { ptmi->rc.top -= offy; ptmi->rc.bottom -= offy; } }}static PBITMAP mnuGetCheckBitmap (PMENUITEM pmi){ if (pmi->mnutype & MFT_BMPSTRING) { if (pmi->mnustate & MFS_CHECKED) return pmi->hbmpChecked; else return pmi->hbmpUnchecked; } else if (!(pmi->mnustate & MFS_CHECKED)) return NULL; // default system check bitmap if (pmi->mnutype & MFT_RADIOCHECK) { if (pmi->mnustate & MFS_DISABLED) { if (pmi->mnustate & MFS_HILITE) return bmpRadio + 3; return bmpRadio + 2; } else { if (pmi->mnustate & MFS_HILITE) return bmpRadio + 1; return bmpRadio; } } else { if (pmi->mnustate & MFS_DISABLED) { if (pmi->mnustate & MFS_HILITE) return bmpCheck + 3; return bmpCheck + 2; } else { if (pmi->mnustate & MFS_HILITE) return bmpCheck + 1; return bmpCheck; } } return NULL;}static PBITMAP mnuGetSubMenuBitmap (PMENUITEM pmi){ if (pmi->mnustate & MFS_DISABLED) { if (pmi->mnustate & MFS_HILITE) return bmpSubMenu + 3; return bmpSubMenu + 2; } else { if (pmi->mnustate & MFS_HILITE) return bmpSubMenu + 1; return bmpSubMenu; }}static int mnuShowPopupMenu (PTRACKMENUINFO ptmi){ PMENUITEM pmi = ptmi->pmi; PMENUITEM psubmi; int x, y, offy; int inter; int mioffx; int marginlx, marginrx; int marginy; PBITMAP bmp; // save screen under this popup menu. ptmi->savedbox = SaveCoveredScreenBox (ptmi->rc.left, ptmi->rc.top, RECTW (ptmi->rc), RECTH (ptmi->rc)); if (ptmi->savedbox == NULL) return -1; inter = GetMainWinMetrics (MWM_INTERMENUITEMY); mioffx = GetMainWinMetrics (MWM_MENUITEMOFFX); marginlx = GetMainWinMetrics (MWM_MENULEFTMARGIN); marginrx = GetMainWinMetrics (MWM_MENURIGHTMARGIN); marginy = GetMainWinMetrics (MWM_MENUTOPMARGIN); // draw background. x = ptmi->rc.left; y = ptmi->rc.top; Draw3DUpFrame (HDC_SCREEN, ptmi->rc.left, ptmi->rc.top, ptmi->rc.right, ptmi->rc.bottom, BKC_MENUITEM_NORMAL); x = ptmi->rc.left + marginlx; y = ptmi->rc.top + marginy; if (pmi->mnutype & MFT_BITMAP) { if (pmi->mnustate & MFS_CHECKED) bmp = pmi->hbmpChecked; else bmp = pmi->hbmpUnchecked; FillBoxWithBitmap (HDC_SCREEN, x, y, bmp->bmWidth, bmp->bmHeight, bmp); } else if (pmi->mnutype & MFT_SEPARATOR) { SetPenColor (HDC_SCREEN, PIXEL_darkgray); MoveTo (HDC_SCREEN, x, y + (pmi->h>>1) - inter + 1); LineTo (HDC_SCREEN, ptmi->rc.right - marginrx, y + (pmi->h>>1) - inter + 1); SetPenColor (HDC_SCREEN, PIXEL_lightwhite); MoveTo (HDC_SCREEN, x, y + (pmi->h>>1) - inter + 2); LineTo (HDC_SCREEN, ptmi->rc.right - marginrx, y + (pmi->h>>1) - inter + 2); } else if (pmi->mnutype & MFT_OWNERDRAW) { } else { SetBkColor (HDC_SCREEN, BKC_MENUITEM_NORMAL); if (pmi->type == TYPE_PPPMENU) { SetTextColor (HDC_SCREEN, FGC_PPPMENUTITLE); TextOut (HDC_SCREEN, x + mioffx, y + inter, (char*)pmi->typedata); SetPenColor (HDC_SCREEN, PIXEL_black); MoveTo (HDC_SCREEN, x, y + pmi->h - (inter<<1)); LineTo (HDC_SCREEN, ptmi->rc.right - marginrx, y + pmi->h - (inter<<1)); MoveTo (HDC_SCREEN, x, y + pmi->h - inter); LineTo (HDC_SCREEN, ptmi->rc.right - marginrx, y + pmi->h - inter); } else { int old_mode, bmp_w = mioffx; // draw check bitmap bmp = mnuGetCheckBitmap (pmi); if (bmp) { offy = (pmi->h - bmp->bmHeight)>>1; FillBoxWithBitmap (HDC_SCREEN, x, y + offy, bmp->bmWidth, pmi->h - (offy<<1), bmp); bmp_w = max (bmp->bmWidth, mioffx); } old_mode = SetBkMode (HDC_SCREEN, BM_TRANSPARENT); SetTextColor (HDC_SCREEN, FGC_MENUITEM_NORMAL); TextOut (HDC_SCREEN, x + bmp_w, y + inter, (char*)pmi->typedata); SetBkMode (HDC_SCREEN, old_mode); if (pmi->submenu) { bmp = mnuGetSubMenuBitmap (pmi); offy = (pmi->h - bmp->bmHeight)>>1; FillBoxWithBitmap (HDC_SCREEN, ptmi->rc.right - mioffx - marginrx, y + offy, bmp->bmWidth, pmi->h - (offy<<1), bmp); } } } y += pmi->h; if (pmi->type == TYPE_PPPMENU) psubmi = pmi->submenu; else psubmi = pmi->next; while (psubmi) { if (psubmi->mnutype & MFT_BITMAP) { if (psubmi->mnustate & MFS_CHECKED) bmp = psubmi->hbmpChecked; else bmp = psubmi->hbmpUnchecked; FillBoxWithBitmap (HDC_SCREEN, x, y, bmp->bmWidth, bmp->bmHeight, bmp); } else if (psubmi->mnutype & MFT_SEPARATOR) { SetPenColor (HDC_SCREEN, PIXEL_darkgray); MoveTo (HDC_SCREEN, x, y + (psubmi->h>>1) - inter + 1); LineTo (HDC_SCREEN, ptmi->rc.right - marginrx, y + (psubmi->h>>1) - inter + 1); SetPenColor (HDC_SCREEN, PIXEL_lightwhite); MoveTo (HDC_SCREEN, x, y + (psubmi->h>>1) - inter + 2); LineTo (HDC_SCREEN, ptmi->rc.right - marginrx, y + (psubmi->h>>1) - inter + 2); } else if (pmi->mnutype & MFT_OWNERDRAW) { } else { int old_mode, bmp_w = mioffx; // draw check bitmap bmp = mnuGetCheckBitmap (psubmi); if (bmp) { offy = (psubmi->h - bmp->bmHeight)>>1; FillBoxWithBitmap (HDC_SCREEN, x, y + offy, bmp->bmWidth, psubmi->h - (offy<<1), bmp); bmp_w = max (bmp->bmWidth, mioffx); } // draw text. SetBkColor (HDC_SCREEN, BKC_MENUITEM_NORMAL); old_mode = SetBkMode (HDC_SCREEN, BM_TRANSPARENT); if (psubmi->mnustate & MFS_DISABLED) SetTextColor (HDC_SCREEN, FGC_MENUITEM_DISABLED); else SetTextColor (HDC_SCREEN, FGC_MENUITEM_NORMAL); TextOut (HDC_SCREEN, x + bmp_w, y + inter, (char*)psubmi->typedata); SetBkMode (HDC_SCREEN, old_mode); if (psubmi->submenu) { bmp = mnuGetSubMenuBitmap (psubmi); offy = (psubmi->h - bmp->bmHeight)>>1; FillBoxWithBitmap (HDC_SCREEN, ptmi->rc.right - mioffx - marginrx, y + offy, bmp->bmWidth, psubmi->h - (offy<<1), bmp); } } y += psubmi->h; psubmi = psubmi->next; } return 0;}static void mnuUnhiliteMenu (PMENUITEM pmi){ if (pmi->type == TYPE_PPPMENU) pmi = pmi->submenu; else { if (pmi->mnustate & MFS_HILITE) pmi->mnustate &= ~MFS_HILITE; pmi = pmi->next; } while (pmi) { if (pmi->mnustate & MFS_HILITE) pmi->mnustate &= ~MFS_HILITE; pmi = pmi->next; }}static void mnuCloseMenu (PTRACKMENUINFO ptmi){ PTRACKMENUINFO phead, plast, ptemp; HMENU hmnu; UINT flags; // menu bar info HWND hwnd; PMENUBAR pmb; int barPos; flags = ptmi->flags; hmnu = (HMENU)ptmi->pmi; // get first tracking menu. phead = ptmi; while (phead->prev) { phead = phead->prev; } pmb = phead->pmb; hwnd = phead->hwnd; barPos = phead->barPos; // get last tracking menu. plast = ptmi; while (plast->next) { plast = plast->next; } while (plast) { ptemp = plast->prev; mnuUnhiliteMenu (plast->pmi); SendMessage (HWND_DESKTOP, MSG_ENDTRACKMENU, 0, (LPARAM)plast); plast = ptemp; } if (pmb && barPos >= 0) HiliteMenuBarItem (hwnd, barPos, HMF_DEFAULT); if (flags & TPM_DESTROY) DestroyMenu (hmnu);}static PTRACKMENUINFO mnuHitTestMenu (PTRACKMENUINFO plast, int x, int y){ PTRACKMENUINFO ptemp; // which popup menu mouse in. ptemp = plast; while (ptemp) { if ( PtInRect(&ptemp->rc, x, y)) return ptemp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -