📄 tkframe.c
字号:
static intFrameWidgetCmd(clientData, interp, argc, argv) ClientData clientData; /* Information about frame widget. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ register Frame *framePtr = (Frame *) clientData; int result; size_t length; int c, i; if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option ?arg arg ...?\"", (char *) NULL); return TCL_ERROR; } Tcl_Preserve((ClientData) framePtr); c = argv[1][0]; length = strlen(argv[1]); if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) && (length >= 2)) { if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " cget option\"", (char *) NULL); result = TCL_ERROR; goto done; } result = Tk_ConfigureValue(interp, framePtr->tkwin, configSpecs, (char *) framePtr, argv[2], framePtr->mask); } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) && (length >= 2)) { if (argc == 2) { result = Tk_ConfigureInfo(interp, framePtr->tkwin, configSpecs, (char *) framePtr, (char *) NULL, framePtr->mask); } else if (argc == 3) { result = Tk_ConfigureInfo(interp, framePtr->tkwin, configSpecs, (char *) framePtr, argv[2], framePtr->mask); } else { /* * Don't allow the options -class, -colormap, -container, * -newcmap, -screen, -use, or -visual to be changed. */ for (i = 2; i < argc; i++) { length = strlen(argv[i]); if (length < 2) { continue; } c = argv[i][1]; if (((c == 'c') && (strncmp(argv[i], "-class", length) == 0) && (length >= 2)) || ((c == 'c') && (framePtr->mask == TOPLEVEL) && (strncmp(argv[i], "-colormap", length) == 0) && (length >= 3)) || ((c == 'c') && (strncmp(argv[i], "-container", length) == 0) && (length >= 3)) || ((c == 's') && (framePtr->mask == TOPLEVEL) && (strncmp(argv[i], "-screen", length) == 0)) || ((c == 'u') && (framePtr->mask == TOPLEVEL) && (strncmp(argv[i], "-use", length) == 0)) || ((c == 'v') && (framePtr->mask == TOPLEVEL) && (strncmp(argv[i], "-visual", length) == 0))) { Tcl_AppendResult(interp, "can't modify ", argv[i], " option after widget is created", (char *) NULL); result = TCL_ERROR; goto done; } } result = ConfigureFrame(interp, framePtr, argc-2, argv+2, TK_CONFIG_ARGV_ONLY); } } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be cget or configure", (char *) NULL); result = TCL_ERROR; } done: Tcl_Release((ClientData) framePtr); return result;}/* *---------------------------------------------------------------------- * * DestroyFrame -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release * to clean up the internal structure of a frame at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the frame is freed up. * *---------------------------------------------------------------------- */static voidDestroyFrame(memPtr) char *memPtr; /* Info about frame widget. */{ register Frame *framePtr = (Frame *) memPtr; Tk_FreeOptions(configSpecs, (char *) framePtr, framePtr->display, framePtr->mask); if (framePtr->colormap != None) { Tk_FreeColormap(framePtr->display, framePtr->colormap); } ckfree((char *) framePtr);}/* *---------------------------------------------------------------------- * * ConfigureFrame -- * * This procedure is called to process an argv/argc list, plus * the Tk option database, in order to configure (or * reconfigure) a frame widget. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as text string, colors, font, * etc. get set for framePtr; old resources get freed, if there * were any. * *---------------------------------------------------------------------- */static intConfigureFrame(interp, framePtr, argc, argv, flags) Tcl_Interp *interp; /* Used for error reporting. */ register Frame *framePtr; /* Information about widget; may or may * not already have values for some fields. */ int argc; /* Number of valid entries in argv. */ char **argv; /* Arguments. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */{ char *oldMenuName; /* * Need the old menubar name for the menu code to delete it. */ if (framePtr->menuName == NULL) { oldMenuName = NULL; } else { oldMenuName = ckalloc(strlen(framePtr->menuName) + 1); strcpy(oldMenuName, framePtr->menuName); } if (Tk_ConfigureWidget(interp, framePtr->tkwin, configSpecs, argc, argv, (char *) framePtr, flags | framePtr->mask) != TCL_OK) { return TCL_ERROR; } if (((oldMenuName == NULL) && (framePtr->menuName != NULL)) || ((oldMenuName != NULL) && (framePtr->menuName == NULL)) || ((oldMenuName != NULL) && (framePtr->menuName != NULL) && strcmp(oldMenuName, framePtr->menuName) != 0)) { TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName, framePtr->menuName); } if (framePtr->border != NULL) { Tk_SetBackgroundFromBorder(framePtr->tkwin, framePtr->border); } else { Tk_SetWindowBackgroundPixmap(framePtr->tkwin, None); } if (framePtr->highlightWidth < 0) { framePtr->highlightWidth = 0; } Tk_SetInternalBorder(framePtr->tkwin, framePtr->borderWidth + framePtr->highlightWidth); if ((framePtr->width > 0) || (framePtr->height > 0)) { Tk_GeometryRequest(framePtr->tkwin, framePtr->width, framePtr->height); } if (oldMenuName != NULL) { ckfree(oldMenuName); } if (Tk_IsMapped(framePtr->tkwin)) { if (!(framePtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr); } framePtr->flags |= REDRAW_PENDING; } return TCL_OK;}/* *---------------------------------------------------------------------- * * DisplayFrame -- * * This procedure is invoked to display a frame widget. * * Results: * None. * * Side effects: * Commands are output to X to display the frame in its * current mode. * *---------------------------------------------------------------------- */static voidDisplayFrame(clientData) ClientData clientData; /* Information about widget. */{ register Frame *framePtr = (Frame *) clientData; register Tk_Window tkwin = framePtr->tkwin; GC gc; framePtr->flags &= ~REDRAW_PENDING; if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin) || framePtr->isContainer) { return; } if (framePtr->border != NULL) { Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), framePtr->border, framePtr->highlightWidth, framePtr->highlightWidth, Tk_Width(tkwin) - 2*framePtr->highlightWidth, Tk_Height(tkwin) - 2*framePtr->highlightWidth, framePtr->borderWidth, framePtr->relief); } if (framePtr->highlightWidth != 0) { if (framePtr->flags & GOT_FOCUS) { gc = Tk_GCForColor(framePtr->highlightColorPtr, Tk_WindowId(tkwin)); } else { gc = Tk_GCForColor(framePtr->highlightBgColorPtr, Tk_WindowId(tkwin)); } Tk_DrawFocusHighlight(tkwin, gc, framePtr->highlightWidth, Tk_WindowId(tkwin)); }}/* *-------------------------------------------------------------- * * FrameEventProc -- * * This procedure is invoked by the Tk dispatcher on * structure changes to a frame. For frames with 3D * borders, this procedure is also invoked for exposures. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */static voidFrameEventProc(clientData, eventPtr) ClientData clientData; /* Information about window. */ register XEvent *eventPtr; /* Information about event. */{ register Frame *framePtr = (Frame *) clientData; if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) || (eventPtr->type == ConfigureNotify)) { goto redraw; } else if (eventPtr->type == DestroyNotify) { if (framePtr->menuName != NULL) { TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, framePtr->menuName, NULL); ckfree(framePtr->menuName); framePtr->menuName = NULL; } if (framePtr->tkwin != NULL) { /* * If this window is a container, then this event could be * coming from the embedded application, in which case * Tk_DestroyWindow hasn't been called yet. When Tk_DestroyWindow * is called later, then another destroy event will be generated. * We need to be sure we ignore the second event, since the frame * could be gone by then. To do so, delete the event handler * explicitly (normally it's done implicitly by Tk_DestroyWindow). */ Tk_DeleteEventHandler(framePtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, FrameEventProc, (ClientData) framePtr); framePtr->tkwin = NULL; Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd); } if (framePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayFrame, (ClientData) framePtr); } Tcl_CancelIdleCall(MapFrame, (ClientData) framePtr); Tcl_EventuallyFree((ClientData) framePtr, DestroyFrame); } else if (eventPtr->type == FocusIn) { if (eventPtr->xfocus.detail != NotifyInferior) { framePtr->flags |= GOT_FOCUS; if (framePtr->highlightWidth > 0) { goto redraw; } } } else if (eventPtr->type == FocusOut) { if (eventPtr->xfocus.detail != NotifyInferior) { framePtr->flags &= ~GOT_FOCUS; if (framePtr->highlightWidth > 0) { goto redraw; } } } else if (eventPtr->type == ActivateNotify) { TkpSetMainMenubar(framePtr->interp, framePtr->tkwin, framePtr->menuName); } return; redraw: if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr); framePtr->flags |= REDRAW_PENDING; }}/* *---------------------------------------------------------------------- * * FrameCmdDeletedProc -- * * This procedure is invoked when a widget command is deleted. If * the widget isn't already in the process of being destroyed, * this command destroys it. * * Results: * None. * * Side effects: * The widget is destroyed. * *---------------------------------------------------------------------- */static voidFrameCmdDeletedProc(clientData) ClientData clientData; /* Pointer to widget record for widget. */{ Frame *framePtr = (Frame *) clientData; Tk_Window tkwin = framePtr->tkwin; if (framePtr->menuName != NULL) { TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, framePtr->menuName, NULL); ckfree(framePtr->menuName); framePtr->menuName = NULL; } /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case tkwin * is NULL) or because the command was deleted, and then this procedure * destroys the widget. */ if (tkwin != NULL) { framePtr->tkwin = NULL; Tk_DestroyWindow(tkwin); }}/* *---------------------------------------------------------------------- * * MapFrame -- * * This procedure is invoked as a when-idle handler to map a * newly-created top-level frame. * * Results: * None. * * Side effects: * The frame given by the clientData argument is mapped. * *---------------------------------------------------------------------- */static voidMapFrame(clientData) ClientData clientData; /* Pointer to frame structure. */{ Frame *framePtr = (Frame *) clientData; /* * Wait for all other background events to be processed before * mapping window. This ensures that the window's correct geometry * will have been determined before it is first mapped, so that the * window manager doesn't get a false idea of its desired geometry. */ Tcl_Preserve((ClientData) framePtr); while (1) { if (Tcl_DoOneEvent(TCL_IDLE_EVENTS) == 0) { break; } /* * After each event, make sure that the window still exists * and quit if the window has been destroyed. */ if (framePtr->tkwin == NULL) { Tcl_Release((ClientData) framePtr); return; } } Tk_MapWindow(framePtr->tkwin); Tcl_Release((ClientData) framePtr);}/* *-------------------------------------------------------------- * * TkInstallFrameMenu -- * * This function is needed when a Windows HWND is created * and a menubar has been set to the window with a system * menu. It notifies the menu package so that the system * menu can be rebuilt. * * Results: * None. * * Side effects: * The system menu (if any) is created for the menubar * associated with this frame. * *-------------------------------------------------------------- */voidTkInstallFrameMenu(tkwin) Tk_Window tkwin; /* The window that was just created. */{ TkWindow *winPtr = (TkWindow *) tkwin; if (winPtr->mainPtr != NULL) { Frame *framePtr; framePtr = (Frame*) winPtr->instanceData; TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp, framePtr->menuName); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -