📄 tkwinmenu.c
字号:
if (mePtr != NULL) { TkMenuReferences *menuRefPtr; TkMenuEntry *parentEntryPtr; Tcl_Interp *interp; int code; /* * We have to set the parent of this menu to be active * if this is a submenu so that tearoffs will get the * correct title. */ menuPtr = mePtr->menuPtr; menuRefPtr = TkFindMenuReferences(menuPtr->interp, Tk_PathName(menuPtr->tkwin)); if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) { for (parentEntryPtr = menuRefPtr->parentEntryPtr; strcmp(parentEntryPtr->name, Tk_PathName(menuPtr->tkwin)) != 0; parentEntryPtr = parentEntryPtr->nextCascadePtr) { /* * Empty loop body. */ } if (parentEntryPtr->menuPtr ->entries[parentEntryPtr->index]->state != tkDisabledUid) { TkActivateMenuEntry(parentEntryPtr->menuPtr, parentEntryPtr->index); } } interp = menuPtr->interp; Tcl_Preserve((ClientData)interp); code = TkInvokeMenu(interp, menuPtr, mePtr->index); if ((code != TCL_OK) && (code != TCL_CONTINUE) && (code != TCL_BREAK)) { Tcl_AddErrorInfo(interp, "\n (menu invoke)"); Tcl_BackgroundError(interp); } Tcl_Release((ClientData)interp); } *plResult = 0; returnResult = 1; break; } case WM_MENUCHAR: { unsigned char menuChar = (unsigned char) LOWORD(*pwParam); hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, (char *) *plParam); if (hashEntryPtr != NULL) { int i; *plResult = 0; menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); for (i = 0; i < menuPtr->numEntries; i++) { int underline = menuPtr->entries[i]->underline; if ((-1 != underline) && (NULL != menuPtr->entries[i]->label) && (CharUpper((LPTSTR) menuChar) == CharUpper((LPTSTR) (unsigned char) menuPtr ->entries[i]->label[underline]))) { *plResult = (2 << 16) | i; returnResult = 1; break; } } } break; } case WM_MEASUREITEM: { LPMEASUREITEMSTRUCT itemPtr = (LPMEASUREITEMSTRUCT) *plParam; if (itemPtr != NULL) { mePtr = (TkMenuEntry *) itemPtr->itemData; menuPtr = mePtr->menuPtr; TkRecomputeMenu(menuPtr); itemPtr->itemHeight = mePtr->height; itemPtr->itemWidth = mePtr->width; if (mePtr->hideMargin) { itemPtr->itemWidth += 2 - indicatorDimensions[0]; } else { itemPtr->itemWidth += 2 * menuPtr->activeBorderWidth; } *plResult = 1; returnResult = 1; } break; } case WM_DRAWITEM: { TkWinDrawable *twdPtr; LPDRAWITEMSTRUCT itemPtr = (LPDRAWITEMSTRUCT) *plParam; Tk_FontMetrics fontMetrics; if (itemPtr != NULL) { mePtr = (TkMenuEntry *) itemPtr->itemData; menuPtr = mePtr->menuPtr; twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable)); twdPtr->type = TWD_WINDC; twdPtr->winDC.hdc = itemPtr->hDC; if (mePtr->state != tkDisabledUid) { if (itemPtr->itemState & ODS_SELECTED) { TkActivateMenuEntry(menuPtr, mePtr->index); } else { TkActivateMenuEntry(menuPtr, -1); } } Tk_GetFontMetrics(menuPtr->tkfont, &fontMetrics); TkpDrawMenuEntry(mePtr, (Drawable) twdPtr, menuPtr->tkfont, &fontMetrics, itemPtr->rcItem.left, itemPtr->rcItem.top, itemPtr->rcItem.right - itemPtr->rcItem.left, itemPtr->rcItem.bottom - itemPtr->rcItem.top, 0, 0); ckfree((char *) twdPtr); *plResult = 1; returnResult = 1; } break; } case WM_MENUSELECT: { UINT flags = HIWORD(*pwParam); TkMenuInit(); if ((flags == 0xFFFF) && (*plParam == 0)) { Tcl_SetServiceMode(oldServiceMode); if (modalMenuPtr != NULL) { RecursivelyClearActiveMenu(modalMenuPtr); } } else { menuPtr = NULL; if (*plParam != 0) { hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, (char *) *plParam); if (hashEntryPtr != NULL) { menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); } } if (menuPtr != NULL) { mePtr = NULL; if (flags != 0xFFFF) { if (flags & MF_POPUP) { mePtr = menuPtr->entries[LOWORD(*pwParam)]; } else { hashEntryPtr = Tcl_FindHashEntry(&commandTable, (char *) LOWORD(*pwParam)); if (hashEntryPtr != NULL) { mePtr = (TkMenuEntry *) Tcl_GetHashValue(hashEntryPtr); } } } if ((mePtr == NULL) || (mePtr->state == tkDisabledUid)) { TkActivateMenuEntry(menuPtr, -1); } else { TkActivateMenuEntry(menuPtr, mePtr->index); } MenuSelectEvent(menuPtr); Tcl_ServiceAll(); } } } } return returnResult;}/* *---------------------------------------------------------------------- * * RecursivelyClearActiveMenu -- * * Recursively clears the active entry in the menu's cascade hierarchy. * * Results: * None. * * Side effects: * Generates <<MenuSelect>> virtual events. * *---------------------------------------------------------------------- */voidRecursivelyClearActiveMenu( TkMenu *menuPtr) /* The menu to reset. */{ int i; TkMenuEntry *mePtr; TkActivateMenuEntry(menuPtr, -1); MenuSelectEvent(menuPtr); for (i = 0; i < menuPtr->numEntries; i++) { mePtr = menuPtr->entries[i]; if (mePtr->type == CASCADE_ENTRY) { if ((mePtr->childMenuRefPtr != NULL) && (mePtr->childMenuRefPtr->menuPtr != NULL)) { RecursivelyClearActiveMenu(mePtr->childMenuRefPtr->menuPtr); } } }}/* *---------------------------------------------------------------------- * * TkpSetWindowMenuBar -- * * Associates a given menu with a window. * * Results: * None. * * Side effects: * On Windows and UNIX, associates the platform menu with the * platform window. * *---------------------------------------------------------------------- */voidTkpSetWindowMenuBar(tkwin, menuPtr) Tk_Window tkwin; /* The window we are putting the menubar into.*/ TkMenu *menuPtr; /* The menu we are inserting */{ HMENU winMenuHdl; if (menuPtr != NULL) { Tcl_HashEntry *hashEntryPtr; int newEntry; winMenuHdl = (HMENU) menuPtr->platformData; hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, (char *) winMenuHdl); Tcl_DeleteHashEntry(hashEntryPtr); DestroyMenu(winMenuHdl); winMenuHdl = CreateMenu(); hashEntryPtr = Tcl_CreateHashEntry(&winMenuTable, (char *) winMenuHdl, &newEntry); Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr); menuPtr->platformData = (TkMenuPlatformData) winMenuHdl; TkWinSetMenu(tkwin, winMenuHdl); if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr); menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; } } else { TkWinSetMenu(tkwin, NULL); }}/* *---------------------------------------------------------------------- * * TkpSetMainMenubar -- * * Puts the menu associated with a window into the menubar. Should * only be called when the window is in front. * * Results: * None. * * Side effects: * The menubar is changed. * *---------------------------------------------------------------------- */voidTkpSetMainMenubar( Tcl_Interp *interp, /* The interpreter of the application */ Tk_Window tkwin, /* The frame we are setting up */ char *menuName) /* The name of the menu to put in front. * If NULL, use the default menu bar. */{ /* * Nothing to do. */}/* *---------------------------------------------------------------------- * * GetMenuIndicatorGeometry -- * * Gets the width and height of the indicator area of a menu. * * Results: * widthPtr and heightPtr are set. * * Side effects: * None. * *---------------------------------------------------------------------- */voidGetMenuIndicatorGeometry ( TkMenu *menuPtr, /* The menu we are measuring */ TkMenuEntry *mePtr, /* The entry we are measuring */ Tk_Font tkfont, /* Precalculated font */ CONST Tk_FontMetrics *fmPtr, /* Precalculated font metrics */ int *widthPtr, /* The resulting width */ int *heightPtr) /* The resulting height */{ *heightPtr = indicatorDimensions[0]; if (mePtr->hideMargin) { *widthPtr = 0; } else { *widthPtr = indicatorDimensions[1] - menuPtr->borderWidth; }}/* *---------------------------------------------------------------------- * * GetMenuAccelGeometry -- * * Gets the width and height of the indicator area of a menu. * * Results: * widthPtr and heightPtr are set. * * Side effects: * None. * *---------------------------------------------------------------------- */voidGetMenuAccelGeometry ( TkMenu *menuPtr, /* The menu we are measuring */ TkMenuEntry *mePtr, /* The entry we are measuring */ Tk_Font tkfont, /* The precalculated font */ CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ int *widthPtr, /* The resulting width */ int *heightPtr) /* The resulting height */{ *heightPtr = fmPtr->linespace; if (mePtr->type == CASCADE_ENTRY) { *widthPtr = 0; } else if (mePtr->accel == NULL) { *widthPtr = 0; } else { *widthPtr = Tk_TextWidth(tkfont, mePtr->accel, mePtr->accelLength); }}/* *---------------------------------------------------------------------- * * GetTearoffEntryGeometry -- * * Gets the width and height of the indicator area of a menu. * * Results: * widthPtr and heightPtr are set. * * Side effects: * None. * *---------------------------------------------------------------------- */voidGetTearoffEntryGeometry ( TkMenu *menuPtr, /* The menu we are measuring */ TkMenuEntry *mePtr, /* The entry we are measuring */ Tk_Font tkfont, /* The precalculated font */ CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ int *widthPtr, /* The resulting width */ int *heightPtr) /* The resulting height */{ if (menuPtr->menuType != MASTER_MENU) { *heightPtr = 0; } else { *heightPtr = fmPtr->linespace; } *widthPtr = 0;}/* *---------------------------------------------------------------------- * * GetMenuSeparatorGeometry -- * * Gets the width and height of the indicator area of a menu. * * Results: * widthPtr and heightPtr are set. * * Side effects: * None. * *---------------------------------------------------------------------- */voidGetMenuSeparatorGeometry ( TkMenu *menuPtr, /* The menu we are measuring */ TkMenuEntry *mePtr, /* The entry we are measuring */ Tk_Font tkfont, /* The precalculated font */ CONST Tk_FontMetrics *fmPtr, /* The precalcualted font metrics */ int *widthPtr, /* The resulting width */ int *heightPtr) /* The resulting height */{ *widthPtr = 0; *heightPtr = fmPtr->linespace;}/* *---------------------------------------------------------------------- * * DrawWindowsSystemBitmap -- * * Draws the windows system bitmap given by bitmapID into the rect * given by rectPtr in the drawable. The bitmap is centered in the * rectangle. It is not clipped, so if the bitmap is bigger than * the rect it will bleed. * * Results: * None. * * Side effects: * Drawing occurs. Some storage is allocated and released. * *---------------------------------------------------------------------- */static voidDrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags) Display *display; /* The display we are drawing into */ Drawable drawable; /* The drawable we are working with */ GC gc; /* The GC to draw with */ CONST RECT *rectPtr; /* The rectangle to draw into */ int bitmapID; /* The windows id of the system * bitmap to draw. */ int alignFlags; /* How to align the bitmap inside the * rectangle. */{ TkWinDCState state; HDC hdc = TkWinGetDrawableDC(display, drawable, &state); HDC scratchDC; HBITMAP bitmap; BITMAP bm; POINT ptSize; POINT ptOrg; int topOffset, leftOffset; SetBkColor(hdc, gc->background); SetTextColor(hdc, gc->foreground); scratchDC = CreateCompatibleDC(hdc); bitmap = LoadBitmap(NULL, MAKEINTRESOURCE(bitmapID));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -