📄 menu.c
字号:
HMENU GUIAPI SetMenu (HWND hwnd, HMENU hmnu)
{
PMAINWIN pWin;
HMENU hOld;
if (!(pWin = CheckAndGetMainWindowPtr (hwnd))) return 0;
hOld = pWin->hMenu;
pWin->hMenu = hmnu;
((PMENUBAR)hmnu)->hwnd = hwnd;
return hOld;
}
HMENU GUIAPI GetMenu (HWND hwnd)
{
PMAINWIN pWin;
if (!(pWin = CheckAndGetMainWindowPtr (hwnd))) return 0;
return pWin->hMenu;
}
HMENU GUIAPI GetSystemMenu (HWND hwnd, BOOL flag)
{
PMAINWIN pWin;
if (!(pWin = CheckAndGetMainWindowPtr (hwnd))) return 0;
return pWin->hSysMenu;
}
/**************************** Menu drawing support ***************************/
static void mnuGetMenuBarItemSize (PMENUITEM pmi, SIZE* size)
{
if (pmi->mnutype & MFT_BITMAP) {
size->cx = pmi->hbmpChecked->bmWidth;
}
else if (pmi->mnutype & MFT_SEPARATOR) {
size->cx = GetMainWinMetrics (MWM_MENUSEPARATORX);
}
else if (pmi->mnutype & MFT_OWNERDRAW) {
}
else {
#if 0
size->cx = strlen ((char*) pmi->typedata)*GetSysCharWidth();
#else
SelectFont (HDC_SCREEN, GetSystemFont (SYSLOGFONT_MENU));
GetTextExtent (HDC_SCREEN, (char*) pmi->typedata, -1, size);
#endif
if (pmi->mnutype & MFT_BMPSTRING) {
size->cx += pmi->hbmpChecked->bmWidth;
size->cx += GetMainWinMetrics (MWM_INTERMENUITEMX)>>1;
}
}
pmi->h = size->cx;
size->cy = GetMainWinMetrics (MWM_MENUBARY);
return;
}
static void mnuDrawMenuBarItem (HDC hdc, PMENUITEM pmi, int x, int y, int w, int h)
{
PBITMAP bmp;
int height;
int inter;
height = GetMainWinMetrics (MWM_MENUBARY);
inter = GetMainWinMetrics (MWM_INTERMENUITEMX)>>1;
SetBrushColor (hdc, GetWindowElementColor (BKC_MENUBAR_NORMAL));
FillBox (hdc, x - inter, y - 3, w + (inter<<1), h + 3);
if (pmi->mnutype & MFT_BITMAP) {
if (pmi->mnustate & MFS_CHECKED)
bmp = pmi->hbmpChecked;
else
bmp = pmi->hbmpUnchecked;
FillBoxWithBitmap (hdc, x, y,
pmi->h,
height,
bmp);
}
else if (pmi->mnutype & MFT_SEPARATOR) {
SetPenColor (hdc, GetWindowElementColor(FGC_MENUBAR_NORMAL));
MoveTo (HDC_SCREEN,
x + (pmi->h>>1), y);
LineTo (HDC_SCREEN,
x + (pmi->h>>1), y + height);
}
else if (pmi->mnutype & MFT_OWNERDRAW) {
}
else {
if (pmi->mnutype & MFT_BMPSTRING) {
if (pmi->mnustate & MFS_CHECKED)
bmp = pmi->hbmpChecked;
else
bmp = pmi->hbmpUnchecked;
FillBoxWithBitmap (hdc, x, y, height, height, bmp);
x += bmp->bmWidth + inter;
}
SelectFont (hdc, GetSystemFont (SYSLOGFONT_MENU));
SetTextColor (hdc, GetWindowElementColor(FGC_MENUBAR_NORMAL));
SetBkColor (hdc, GetWindowElementColor (BKC_MENUBAR_NORMAL));
TextOut (hdc, x, y, (char *)pmi->typedata);
}
return;
}
static int mnuGetNextMenuBarItem (PMENUBAR pmb, int pos)
{
PMENUITEM pmi;
int number;
number = 0;
pmi = pmb->head;
while (pmi) {
number ++;
pmi = pmi->next;
}
number--;
if (pos == number)
return 0;
else
return pos + 1;
}
static int mnuGetPrevMenuBarItem (PMENUBAR pmb, int pos)
{
PMENUITEM pmi;
int number;
number = 0;
pmi = pmb->head;
while (pmi) {
number ++;
pmi = pmi->next;
}
number--;
if (pos == 0)
return number;
else
return pos - 1;
}
HMENU GUIAPI GetMenuBarItemRect (HWND hwnd, int pos, RECT* prc)
{
PMAINWIN pWin;
PMENUBAR pmb;
PMENUITEM pmi;
int x, y, inter, h;
int count;
SIZE size;
if (!(pWin = CheckAndGetMainWindowPtr (hwnd))) return 0;
if (!pWin->hMenu) return 0;
pmb = (PMENUBAR) (pWin->hMenu);
if (pmb->category != TYPE_HMENU) return 0;
if (pmb->type != TYPE_MENUBAR) return 0;
x = pWin->cl - pWin->left;
x += GetMainWinMetrics (MWM_MENUBAROFFX);
y = pWin->ct - pWin->top;
h = GetMainWinMetrics (MWM_MENUBARY)
+ GetMainWinMetrics (MWM_MENUBAROFFY);
y -= h;
inter = GetMainWinMetrics (MWM_INTERMENUITEMX);
count = 0;
pmi = pmb->head;
while (pmi) {
mnuGetMenuBarItemSize (pmi, &size);
if (count == pos)
break;
x = x + inter + size.cx;
count ++;
pmi = pmi->next;
}
if (pmi == NULL) return 0;
prc->left = x;
prc->top = y;
prc->bottom = y + h - 1;
prc->right = x + size.cx - 1;
return (HMENU) pmi;
}
static BOOL mnuGetMenuBarRect (HWND hwnd, RECT* prc)
{
PMAINWIN pWin;
int w, h;
if (!(pWin = CheckAndGetMainWindowPtr (hwnd))) return FALSE;
prc->left = pWin->cl - pWin->left;
w = pWin->cr - pWin->cl + 1;
h = GetMainWinMetrics (MWM_MENUBARY)
+ (GetMainWinMetrics (MWM_MENUBAROFFY)<<1);
prc->top = pWin->ct - pWin->top;
prc->top -= GetMainWinMetrics (MWM_MENUBARY);
prc->top -= GetMainWinMetrics (MWM_MENUBAROFFY)<<1;
prc->right = prc->left + w - 1;
prc->bottom = prc->top + h - 1;
return TRUE;
}
BOOL GUIAPI HiliteMenuBarItem (HWND hwnd, int pos, UINT flags)
{
PMENUITEM pmi;
RECT rcBar;
RECT rc;
HDC hdc;
int inter;
pmi = (PMENUITEM)GetMenuBarItemRect (hwnd, pos, &rc);
if (!pmi) return FALSE;
inter = GetMainWinMetrics (MWM_INTERMENUITEMX)>>1;
hdc = GetDC (hwnd);
mnuGetMenuBarRect (hwnd, &rcBar);
ClipRectIntersect (hdc, &rcBar);
if (flags == HMF_UPITEM) {
Draw3DThinFrameEx (hdc, hwnd, rc.left - inter, rc.top - 3,
rc.right + inter, rc.bottom - 1,
DF_3DBOX_NORMAL | DF_3DBOX_NOTFILL, 0);
}
else if (flags == HMF_DOWNITEM) {
mnuDrawMenuBarItem (hdc, pmi, rc.left + 1, rc.top + 1,
RECTW (rc) - 2, RECTH (rc) - 2);
Draw3DThinFrameEx (hdc, hwnd, rc.left - inter, rc.top - 2,
rc.right + inter, rc.bottom - 2,
DF_3DBOX_PRESSED | DF_3DBOX_NOTFILL, 0);
}
else if (flags == HMF_DEFAULT)
mnuDrawMenuBarItem (hdc, pmi, rc.left, rc.top,
RECTW (rc) + 3, RECTH (rc) + 1);
ReleaseDC (hdc);
return TRUE;
}
int MenuBarHitTest (HWND hwnd, int mx, int my)
{
PMAINWIN pWin;
PMENUBAR pmb;
PMENUITEM pmi;
int x, y, inter, h;
RECT rc;
int count;
SIZE size;
if (!(pWin = CheckAndGetMainWindowPtr (hwnd))) return -1;
if (!pWin->hMenu) return -1;
pmb = (PMENUBAR) (pWin->hMenu);
if (pmb->category != TYPE_HMENU) return -1;
if (pmb->type != TYPE_MENUBAR) return -1;
x = pWin->left;
x += GetMainWinMetrics (MWM_MENUBAROFFX);
y = pWin->ct;
y -= GetMainWinMetrics (MWM_MENUBARY);
y -= GetMainWinMetrics (MWM_MENUBAROFFY);
h = GetMainWinMetrics (MWM_MENUBARY)
+ GetMainWinMetrics (MWM_MENUBAROFFY);
inter = GetMainWinMetrics (MWM_INTERMENUITEMX);
rc.top = y;
rc.bottom = y + h;
count = 0;
pmi = pmb->head;
while (pmi) {
mnuGetMenuBarItemSize (pmi, &size);
rc.left = x;
rc.right = x + size.cx;
if (PtInRect (&rc, mx, my))
return count;
x = x + inter + size.cx;
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->category != 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, GetWindowElementColor(BKC_MENUBAR_NORMAL));
FillBox (hdc, x, y, w + 3, h + 3);
SelectFont (hdc, GetSystemFont (SYSLOGFONT_MENU));
SetBkColor (hdc, GetWindowElementColor(BKC_MENUBAR_NORMAL));
SetTextColor (hdc, GetWindowElementColor(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 = CheckAndGetMainWindowPtr (hwnd))) return;
if (!pWin->hMenu) return;
hdc = GetDC (hwnd);
DrawMenuBarHelper (pWin, hdc, NULL);
ReleaseDC (hdc);
}
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);
//h = ptmi->rc.bottom - ptmi->rc.top;
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 {
SelectFont (HDC_SCREEN, GetSystemFont (SYSLOGFONT_MENU));
GetTabbedTextExtent (HDC_SCREEN, (char*)pmi->typedata, -1, &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);
SelectFont (HDC_SCREEN, GetSystemFont (SYSLOGFONT_MENU));
GetTabbedTextExtent (HDC_SCREEN, (char*)psubmi->typedata, -1, &size);
if (pmi->mnutype & MFT_BMPSTRING)
size.cx += pmi->hbmpChecked->bmWidth;
if (size.cx > w) w = size.cx;
}
if (psubmi->submenu)
has_sub = TRUE;
ptmi->rc.bottom += psubmi->h;
//h += psubmi->h;
psubmi = psubmi->next;
}
ptmi->rc.bottom += GetMainWinMetrics (MWM_MENUBOTTOMMARGIN);
//h += 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;
/* adjust the rect according to the alignment flag */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -