?? tkwindialog.c
字號:
/* * tkWinDialog.c -- * * Contains the Windows implementation of the common dialog boxes. * * Copyright (c) 1996-1997 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: @(#) tkWinDialog.c 1.10 97/10/21 11:29:18 * */ #include "tkWinInt.h"#include "tkFileFilter.h"#include <commdlg.h> /* includes common dialog functionality */#include <dlgs.h> /* includes common dialog template defines */#include <cderr.h> /* includes the common dialog error codes */#if ((TK_MAJOR_VERSION == 4) && (TK_MINOR_VERSION <= 2))/* * The following function is implemented on tk4.3 and after only */#define Tk_GetHWND TkWinGetHWND#endif#define SAVE_FILE 0#define OPEN_FILE 1/*---------------------------------------------------------------------- * MsgTypeInfo -- * * This structure stores the type of available message box in an * easy-to-process format. Used by th Tk_MessageBox() function *---------------------------------------------------------------------- */typedef struct MsgTypeInfo { char * name; int type; int numButtons; char * btnNames[3];} MsgTypeInfo;#define NUM_TYPES 6static MsgTypeInfo msgTypeInfo[NUM_TYPES] = { {"abortretryignore", MB_ABORTRETRYIGNORE, 3, {"abort", "retry", "ignore"}}, {"ok", MB_OK, 1, {"ok" }}, {"okcancel", MB_OKCANCEL, 2, {"ok", "cancel" }}, {"retrycancel", MB_RETRYCANCEL, 2, {"retry", "cancel" }}, {"yesno", MB_YESNO, 2, {"yes", "no" }}, {"yesnocancel", MB_YESNOCANCEL, 3, {"yes", "no", "cancel"}}};/* * The following structure is used in the GetOpenFileName() and * GetSaveFileName() calls. */typedef struct _OpenFileData { Tcl_Interp * interp; TCHAR szFile[MAX_PATH+1];} OpenFileData;/* * The following structure is used in the ChooseColor() call. */typedef struct _ChooseColorData { Tcl_Interp * interp; char * title; /* Title of the color dialog */} ChooseColorData;static int GetFileName _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv, int isOpen));static UINT CALLBACK ColorDlgHookProc _ANSI_ARGS_((HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam));static int MakeFilter _ANSI_ARGS_((Tcl_Interp *interp, OPENFILENAME *ofnPtr, char * string));static int ParseFileDlgArgs _ANSI_ARGS_((Tcl_Interp * interp, OPENFILENAME *ofnPtr, int argc, char ** argv, int isOpen));static int ProcessCDError _ANSI_ARGS_((Tcl_Interp * interp, DWORD dwErrorCode, HWND hWnd));/* *---------------------------------------------------------------------- * * EvalArgv -- * * Invokes the Tcl procedure with the arguments. argv[0] is set by * the caller of this function. It may be different than cmdName. * The TCL command will see argv[0], not cmdName, as its name if it * invokes [lindex [info level 0] 0] * * Results: * TCL_ERROR if the command does not exist and cannot be autoloaded. * Otherwise, return the result of the evaluation of the command. * * Side effects: * The command may be autoloaded. * *---------------------------------------------------------------------- */static int EvalArgv(interp, cmdName, argc, argv) Tcl_Interp *interp; /* Current interpreter. */ char * cmdName; /* Name of the TCL command to call */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tcl_CmdInfo cmdInfo; if (!Tcl_GetCommandInfo(interp, cmdName, &cmdInfo)) { char * cmdArgv[2]; /* * This comand is not in the interpreter yet -- looks like we * have to auto-load it */ if (!Tcl_GetCommandInfo(interp, "auto_load", &cmdInfo)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "cannot execute command \"auto_load\"", NULL); return TCL_ERROR; } cmdArgv[0] = "auto_load"; cmdArgv[1] = cmdName; if ((*cmdInfo.proc)(cmdInfo.clientData, interp, 2, cmdArgv)!= TCL_OK){ return TCL_ERROR; } if (!Tcl_GetCommandInfo(interp, cmdName, &cmdInfo)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "cannot auto-load command \"", cmdName, "\"",NULL); return TCL_ERROR; } } return (*cmdInfo.proc)(cmdInfo.clientData, interp, argc, argv);}/* *---------------------------------------------------------------------- * * Tk_ChooseColorCmd -- * * This procedure implements the color dialog box for the Windows * platform. See the user documentation for details on what it * does. * * Results: * See user documentation. * * Side effects: * A dialog window is created the first time this procedure is called. * This window is not destroyed and will be reused the next time the * application invokes the "tk_chooseColor" command. * *---------------------------------------------------------------------- */intTk_ChooseColorCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window parent = Tk_MainWindow(interp); ChooseColorData custData; int oldMode; CHOOSECOLOR chooseColor; char * colorStr = NULL; int i; int winCode, tclCode; XColor * colorPtr = NULL; static inited = 0; static long dwCustColors[16]; static long oldColor; /* the color selected last time */ custData.title = NULL; if (!inited) { /* * dwCustColors stores the custom color which the user can * modify. We store these colors in a fixed array so that the next * time the color dialog pops up, the same set of custom colors * remain in the dialog. */ for (i=0; i<16; i++) { dwCustColors[i] = (RGB(255-i*10, i, i*10)) ; } oldColor = RGB(0xa0,0xa0,0xa0); inited = 1; } /* * 1. Parse the arguments */ chooseColor.lStructSize = sizeof(CHOOSECOLOR) ; chooseColor.hwndOwner = 0; /* filled in below */ chooseColor.hInstance = 0; chooseColor.rgbResult = oldColor; chooseColor.lpCustColors = (LPDWORD) dwCustColors ; chooseColor.Flags = CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK; chooseColor.lCustData = (LPARAM)&custData; chooseColor.lpfnHook = ColorDlgHookProc; chooseColor.lpTemplateName = NULL; for (i=1; i<argc; i+=2) { int v = i+1; int len = strlen(argv[i]); if (strncmp(argv[i], "-initialcolor", len)==0) { if (v==argc) {goto arg_missing;} colorStr = argv[v]; } else if (strncmp(argv[i], "-parent", len)==0) { if (v==argc) {goto arg_missing;} parent=Tk_NameToWindow(interp, argv[v], Tk_MainWindow(interp)); if (parent == NULL) { return TCL_ERROR; } } else if (strncmp(argv[i], "-title", len)==0) { if (v==argc) {goto arg_missing;} custData.title = argv[v]; } else { Tcl_AppendResult(interp, "unknown option \"", argv[i], "\", must be -initialcolor, -parent or -title", NULL); return TCL_ERROR; } } if (Tk_WindowId(parent) == None) { Tk_MakeWindowExist(parent); } chooseColor.hwndOwner = Tk_GetHWND(Tk_WindowId(parent)); if (colorStr != NULL) { colorPtr = Tk_GetColor(interp, Tk_MainWindow(interp), colorStr); if (!colorPtr) { return TCL_ERROR; } chooseColor.rgbResult = RGB((colorPtr->red/0x100), (colorPtr->green/0x100), (colorPtr->blue/0x100)); } /* * 2. Popup the dialog */ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); winCode = ChooseColor(&chooseColor); (void) Tcl_SetServiceMode(oldMode); /* * Clear the interp result since anything may have happened during the * modal loop. */ Tcl_ResetResult(interp); /* * 3. Process the result of the dialog */ if (winCode) { /* * User has selected a color */ char result[100]; sprintf(result, "#%02x%02x%02x", GetRValue(chooseColor.rgbResult), GetGValue(chooseColor.rgbResult), GetBValue(chooseColor.rgbResult)); Tcl_AppendResult(interp, result, NULL); tclCode = TCL_OK; oldColor = chooseColor.rgbResult; } else { /* * User probably pressed Cancel, or an error occurred */ tclCode = ProcessCDError(interp, CommDlgExtendedError(), chooseColor.hwndOwner); } if (colorPtr) { Tk_FreeColor(colorPtr); } return tclCode; arg_missing: Tcl_AppendResult(interp, "value for \"", argv[argc-1], "\" missing", NULL); return TCL_ERROR;}/* *---------------------------------------------------------------------- * * ColorDlgHookProc -- * * Gets called during the execution of the color dialog. It processes * the "interesting" messages that Windows send to the dialog. * * Results: * TRUE if the message has been processed, FALSE otherwise. * * Side effects: * Changes the title of the dialog window when it is popped up. * *---------------------------------------------------------------------- */static UINTCALLBACK ColorDlgHookProc(hDlg, uMsg, wParam, lParam) HWND hDlg; /* Handle to the color dialog */ UINT uMsg; /* Type of message */ WPARAM wParam; /* word param, interpretation depends on uMsg*/ LPARAM lParam; /* long param, interpretation depends on uMsg*/{ CHOOSECOLOR * ccPtr; ChooseColorData * pCustData; switch (uMsg) { case WM_INITDIALOG: /* Save the pointer to CHOOSECOLOR so that we can use it later */ SetWindowLong(hDlg, DWL_USER, lParam); /* Set the title string of the dialog */ ccPtr = (CHOOSECOLOR*)lParam; pCustData = (ChooseColorData*)(ccPtr->lCustData); if (pCustData->title && *(pCustData->title)) { SetWindowText(hDlg, (LPCSTR)pCustData->title); } return TRUE; } return FALSE;}/* *---------------------------------------------------------------------- * * Tk_GetOpenFileCmd -- * * This procedure implements the "open file" dialog box for the * Windows platform. See the user documentation for details on what * it does. * * Results: * See user documentation. * * Side effects: * A dialog window is created the first this procedure is called. * This window is not destroyed and will be reused the next time * the application invokes the "tk_getOpenFile" or * "tk_getSaveFile" command. * *---------------------------------------------------------------------- */intTk_GetOpenFileCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ return GetFileName(clientData, interp, argc, argv, OPEN_FILE);}/* *---------------------------------------------------------------------- * * Tk_GetSaveFileCmd -- * * Same as Tk_GetOpenFileCmd but opens a "save file" dialog box * instead * * Results: * Same as Tk_GetOpenFileCmd. * * Side effects: * Same as Tk_GetOpenFileCmd. * *---------------------------------------------------------------------- */intTk_GetSaveFileCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ return GetFileName(clientData, interp, argc, argv, SAVE_FILE);}/* *---------------------------------------------------------------------- * * GetFileName -- * * Calls GetOpenFileName() or GetSaveFileName(). * * Results: * See user documentation. * * Side effects: * See user documentation. * *---------------------------------------------------------------------- */static int GetFileName(clientData, interp, argc, argv, isOpen) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ int isOpen; /* true if we should call GetOpenFileName(), * false if we should call GetSaveFileName() */{ OPENFILENAME openFileName, *ofnPtr; int tclCode, winCode, oldMode; OpenFileData *custData; char buffer[MAX_PATH+1]; ofnPtr = &openFileName; /* * 1. Parse the arguments. */ if (ParseFileDlgArgs(interp, ofnPtr, argc, argv, isOpen) != TCL_OK) { return TCL_ERROR; } custData = (OpenFileData*) ofnPtr->lCustData; /* * 2. Call the common dialog function. */ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); GetCurrentDirectory(MAX_PATH+1, buffer); if (isOpen) { winCode = GetOpenFileName(ofnPtr); } else { winCode = GetSaveFileName(ofnPtr); } SetCurrentDirectory(buffer); (void) Tcl_SetServiceMode(oldMode); /* * Clear the interp result since anything may have happened during the * modal loop. */ Tcl_ResetResult(interp); if (ofnPtr->lpstrInitialDir != NULL) { ckfree((char*) ofnPtr->lpstrInitialDir); } /* * 3. Process the results. */ if (winCode) { char *p; Tcl_ResetResult(interp); for (p = custData->szFile; p && *p; p++) { /* * Change the pathname to the Tcl "normalized" pathname, where * back slashes are used instead of forward slashes */ if (*p == '\\') { *p = '/'; } } Tcl_AppendResult(interp, custData->szFile, NULL); tclCode = TCL_OK; } else { tclCode = ProcessCDError(interp, CommDlgExtendedError(), ofnPtr->hwndOwner); } if (custData) { ckfree((char*)custData); } if (ofnPtr->lpstrFilter) { ckfree((char*)ofnPtr->lpstrFilter); } return tclCode;}/* *---------------------------------------------------------------------- * * ParseFileDlgArgs -- * * Parses the arguments passed to tk_getOpenFile and tk_getSaveFile. * * Results: * A standard TCL return value. * * Side effects: * The OPENFILENAME structure is initialized and modified according
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -