⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tkwinmenu.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * tkWinMenu.c -- * *	This module implements the Windows platform-specific features of menus. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkWinMenu.c 1.102 97/10/28 13:56:58 */#define OEMRESOURCE#include <string.h>#include "tkMenu.h"#include "tkWinInt.h"/* * The class of the window for popup menus. */#define MENU_CLASS_NAME "MenuWindowClass"/* * Used to align a windows bitmap inside a rectangle */#define ALIGN_BITMAP_LEFT   0x00000001#define ALIGN_BITMAP_RIGHT  0x00000002#define ALIGN_BITMAP_TOP    0x00000004#define ALIGN_BITMAP_BOTTOM 0x00000008/* * Platform-specific menu flags: * * MENU_SYSTEM_MENU	Non-zero means that the Windows menu handle *			was retrieved with GetSystemMenu and needs *			to be disposed of specially. * MENU_RECONFIGURE_PENDING *			Non-zero means that an idle handler has *			been set up to reconfigure the Windows menu *			handle for this menu. */#define MENU_SYSTEM_MENU	    MENU_PLATFORM_FLAG1#define MENU_RECONFIGURE_PENDING    MENU_PLATFORM_FLAG2static int indicatorDimensions[2];				/* The dimensions of the indicator space				 * in a menu entry. Calculated at init				 * time to save time. */static Tcl_HashTable commandTable;				/* A map of command ids to menu entries */static int inPostMenu;		/* We cannot be re-entrant like X Windows. */static WORD lastCommandID;	/* The last command ID we allocated. */static HWND menuHWND;		/* A window to service popup-menu messages				 * in. */static int oldServiceMode;	/* Used while processing a menu; we need				 * to set the event mode specially when we				 * enter the menu processing modal loop				 * and reset it when menus go away. */static TkMenu *modalMenuPtr;	/* The menu we are processing inside the modal				 * loop. We need this to reset all of the 				 * active items when menus go away since				 * Windows does not see fit to give this				 * to us when it sends its WM_MENUSELECT. */static OSVERSIONINFO versionInfo;				/* So we don't have to keep doing this */static Tcl_HashTable winMenuTable;				/* Need this to map HMENUs back to menuPtrs *//* * The following are default menu value strings. */static char borderString[5];	/* The string indicating how big the border is */static Tcl_DString menuFontDString;				/* A buffer to store the default menu font				 * string. *//* * Forward declarations for procedures defined later in this file: */static void		DrawMenuEntryAccelerator _ANSI_ARGS_((			    TkMenu *menuPtr, TkMenuEntry *mePtr, 			    Drawable d, GC gc, Tk_Font tkfont,			    CONST Tk_FontMetrics *fmPtr,			    Tk_3DBorder activeBorder, int x, int y,			    int width, int height, int drawArrow));static void		DrawMenuEntryBackground _ANSI_ARGS_((			    TkMenu *menuPtr, TkMenuEntry *mePtr,			    Drawable d, Tk_3DBorder activeBorder,			    Tk_3DBorder bgBorder, int x, int y,			    int width, int heigth));static void		DrawMenuEntryIndicator _ANSI_ARGS_((			    TkMenu *menuPtr, TkMenuEntry *mePtr,			    Drawable d, GC gc, GC indicatorGC, 			    Tk_Font tkfont,			    CONST Tk_FontMetrics *fmPtr, int x, int y,			    int width, int height));static void		DrawMenuEntryLabel _ANSI_ARGS_((			    TkMenu * menuPtr, TkMenuEntry *mePtr, Drawable d,			    GC gc, Tk_Font tkfont,			    CONST Tk_FontMetrics *fmPtr, int x, int y,			    int width, int height));static void		DrawMenuSeparator _ANSI_ARGS_((TkMenu *menuPtr,			    TkMenuEntry *mePtr, Drawable d, GC gc, 			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, 			    int x, int y, int width, int height));static void		DrawTearoffEntry _ANSI_ARGS_((TkMenu *menuPtr,			    TkMenuEntry *mePtr, Drawable d, GC gc, 			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, 			    int x, int y, int width, int height));static void		DrawMenuUnderline _ANSI_ARGS_((TkMenu *menuPtr,			    TkMenuEntry *mePtr, Drawable d, GC gc,			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x,			    int y, int width, int height));static void		DrawWindowsSystemBitmap _ANSI_ARGS_((			    Display *display, Drawable drawable, 			    GC gc, CONST RECT *rectPtr, int bitmapID,			    int alignFlags));static void		FreeID _ANSI_ARGS_((int commandID));static char *		GetEntryText _ANSI_ARGS_((TkMenuEntry *mePtr));static void		GetMenuAccelGeometry _ANSI_ARGS_((TkMenu *menuPtr,			    TkMenuEntry *mePtr, Tk_Font tkfont,			    CONST Tk_FontMetrics *fmPtr, int *widthPtr,			    int *heightPtr));static void		GetMenuLabelGeometry _ANSI_ARGS_((TkMenuEntry *mePtr,			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,			    int *widthPtr, int *heightPtr));static void		GetMenuIndicatorGeometry _ANSI_ARGS_((			    TkMenu *menuPtr, TkMenuEntry *mePtr, 			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, 			    int *widthPtr, int *heightPtr));static void		GetMenuSeparatorGeometry _ANSI_ARGS_((			    TkMenu *menuPtr, TkMenuEntry *mePtr,			    Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr,			    int *widthPtr, int *heightPtr));static void		GetTearoffEntryGeometry _ANSI_ARGS_((TkMenu *menuPtr,			    TkMenuEntry *mePtr, Tk_Font tkfont,			    CONST Tk_FontMetrics *fmPtr, int *widthPtr,			    int *heightPtr));static int		GetNewID _ANSI_ARGS_((TkMenuEntry *mePtr,			    int *menuIDPtr));static void		MenuExitProc _ANSI_ARGS_((ClientData clientData));static int		MenuKeyBindProc _ANSI_ARGS_((			    ClientData clientData, 			    Tcl_Interp *interp, XEvent *eventPtr,			    Tk_Window tkwin, KeySym keySym));static void		MenuSelectEvent _ANSI_ARGS_((TkMenu *menuPtr));static void		ReconfigureWindowsMenu _ANSI_ARGS_((			    ClientData clientData));static void		RecursivelyClearActiveMenu _ANSI_ARGS_((			    TkMenu *menuPtr));static LRESULT CALLBACK	TkWinMenuProc _ANSI_ARGS_((HWND hwnd,			    UINT message, WPARAM wParam,			    LPARAM lParam));/* *---------------------------------------------------------------------- * * GetNewID -- * *	Allocates a new menu id and marks it in use. * * Results: *	Returns TCL_OK if succesful; TCL_ERROR if there are no more *	ids of the appropriate type to allocate. menuIDPtr contains *	the new id if succesful. * * Side effects: *	An entry is created for the menu in the command hash table, *	and the hash entry is stored in the appropriate field in the *	menu data structure. * *---------------------------------------------------------------------- */static intGetNewID(mePtr, menuIDPtr)    TkMenuEntry *mePtr;		/* The menu we are working with */    int *menuIDPtr;		/* The resulting id */{    int found = 0;    int newEntry;    Tcl_HashEntry *commandEntryPtr;    WORD returnID;    WORD curID = lastCommandID + 1;    /*     * The following code relies on WORD wrapping when the highest value is     * incremented.     */        while (curID != lastCommandID) {    	commandEntryPtr = Tcl_CreateHashEntry(&commandTable,		(char *) curID, &newEntry);    	if (newEntry == 1) {    	    found = 1;    	    returnID = curID;    	    break;    	}    	curID++;    }    if (found) {    	Tcl_SetHashValue(commandEntryPtr, (char *) mePtr);    	*menuIDPtr = (int) returnID;    	lastCommandID = returnID;    	return TCL_OK;    } else {    	return TCL_ERROR;    }}/* *---------------------------------------------------------------------- * * FreeID -- * *	Marks the itemID as free. * * Results: *	None. * * Side effects: *	The hash table entry for the ID is cleared. * *---------------------------------------------------------------------- */static voidFreeID(commandID)    int commandID;{    Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&commandTable,	    (char *) commandID);        if (entryPtr != NULL) {    	 Tcl_DeleteHashEntry(entryPtr);    }}/* *---------------------------------------------------------------------- * * TkpNewMenu -- * *	Gets a new blank menu. Only the platform specific options are filled *	in. * * Results: *	Standard TCL error. * * Side effects: *	Allocates a Windows menu handle and places it in the platformData *	field of the menuPtr. * *---------------------------------------------------------------------- */intTkpNewMenu(menuPtr)    TkMenu *menuPtr;	/* The common structure we are making the			 * platform structure for. */{    HMENU winMenuHdl;    Tcl_HashEntry *hashEntryPtr;    int newEntry;    winMenuHdl = CreatePopupMenu();        if (winMenuHdl == NULL) {    	Tcl_AppendResult(menuPtr->interp, "No more menus can be allocated.",    		(char *) NULL);    	return TCL_ERROR;    }    /*     * We hash all of the HMENU's so that we can get their menu ptrs     * back when dispatch messages.     */    hashEntryPtr = Tcl_CreateHashEntry(&winMenuTable, (char *) winMenuHdl,	    &newEntry);    Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr);    menuPtr->platformData = (TkMenuPlatformData) winMenuHdl;    return TCL_OK;}/* *---------------------------------------------------------------------- * * TkpDestroyMenu -- * *	Destroys platform-specific menu structures. * * Results: *	None. * * Side effects: *	All platform-specific allocations are freed up. * *---------------------------------------------------------------------- */voidTkpDestroyMenu(menuPtr)    TkMenu *menuPtr;	    /* The common menu structure */{    HMENU winMenuHdl = (HMENU) menuPtr->platformData;    if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) {	Tcl_CancelIdleCall(ReconfigureWindowsMenu, (ClientData) menuPtr);    }        if (winMenuHdl == NULL) {	return;    }    if (menuPtr->menuFlags & MENU_SYSTEM_MENU) {	TkMenuEntry *searchEntryPtr;	Tcl_HashTable *tablePtr = TkGetMenuHashTable(menuPtr->interp);	char *menuName = Tcl_GetHashKey(tablePtr, 		menuPtr->menuRefPtr->hashEntryPtr);	/*	 * Search for the menu in the menubar, if it is present, get the	 * wrapper window associated with the toplevel and reset its	 * system menu to the default menu.	 */	for (searchEntryPtr = menuPtr->menuRefPtr->parentEntryPtr;	     searchEntryPtr != NULL;	     searchEntryPtr = searchEntryPtr->nextCascadePtr) {	    if (strcmp(searchEntryPtr->name, menuName) == 0) {		Tk_Window parentTopLevelPtr = searchEntryPtr		    ->menuPtr->parentTopLevelPtr;		if (parentTopLevelPtr != NULL) {		    GetSystemMenu(TkWinGetWrapperWindow(parentTopLevelPtr),			    TRUE);		}		break;	    }	}    } else {	Tcl_HashEntry *hashEntryPtr; 	/*	 * Remove the menu from the menu hash table, then destroy the handle.	 */	hashEntryPtr = Tcl_FindHashEntry(&winMenuTable, (char *) winMenuHdl);	if (hashEntryPtr != NULL) {	    Tcl_DeleteHashEntry(hashEntryPtr);	} 	DestroyMenu(winMenuHdl);    }    menuPtr->platformData = NULL;}/* *---------------------------------------------------------------------- * * TkpDestroyMenuEntry -- * *	Cleans up platform-specific menu entry items. * * Results: *	None * * Side effects: *	All platform-specific allocations are freed up. * *---------------------------------------------------------------------- */voidTkpDestroyMenuEntry(mePtr)    TkMenuEntry *mePtr;		    /* The entry to destroy */{    TkMenu *menuPtr = mePtr->menuPtr;    HMENU winMenuHdl = (HMENU) menuPtr->platformData;    if (NULL != winMenuHdl) {        if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) {	    menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING;	    Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr);	}    }    FreeID((int) mePtr->platformEntryData);    mePtr->platformEntryData = NULL;}/* *---------------------------------------------------------------------- * * GetEntryText -- * *	Given a menu entry, gives back the text that should go in it. *	Separators should be done by the caller, as they have to be *	handled specially. Allocates the memory with alloc. The caller *	should free the memory. * * Results: *	itemText points to the new text for the item. * * Side effects: *	None. * *---------------------------------------------------------------------- */static char *GetEntryText(mePtr)    TkMenuEntry *mePtr;		/* A pointer to the menu entry. */{    char *itemText;    if (mePtr->type == TEAROFF_ENTRY) {	itemText = ckalloc(sizeof("(Tear-off)"));	strcpy(itemText, "(Tear-off)");    } else if (mePtr->imageString != NULL) {	itemText = ckalloc(sizeof("(Image)"));	strcpy(itemText, "(Image)");    } else if (mePtr->bitmap != None) {	itemText = ckalloc(sizeof("(Pixmap)"));	strcpy(itemText, "(Pixmap)");    } else if (mePtr->label == NULL || mePtr->labelLength == 0) {	itemText = ckalloc(sizeof("( )"));	strcpy(itemText, "( )");    } else {	int size = mePtr->labelLength + 1;	int i, j;	/*	 * We have to construct the string with an ampersand	 * preceeding the underline character, and a tab seperating	 * the text and the accel text. We have to be careful with	 * ampersands in the string.	 */	for (i = 0; i < mePtr->labelLength; i++) {	    if (mePtr->label[i] == '&') {		size++;	    }	}	if (mePtr->underline >= 0) {	    size++;	    if (mePtr->label[mePtr->underline] == '&') {		size++;	    }	}	if (mePtr->accelLength > 0) {	    size += mePtr->accelLength + 1;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -