winMain.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:9k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * winMain.c --
  3.  *
  4.  * Main entry point for wish and other Tk-based applications.
  5.  *
  6.  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  7.  * Copyright (c) 1998-1999 by Scriptics Corporation.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  *
  12.  * RCS: @(#) $Id: winMain.c,v 1.15.2.2 2003/12/12 00:42:10 davygrvy Exp $
  13.  */
  14. #include <tk.h>
  15. #define WIN32_LEAN_AND_MEAN
  16. #include <windows.h>
  17. #undef WIN32_LEAN_AND_MEAN
  18. #include <malloc.h>
  19. #include <locale.h>
  20. #include "tkInt.h"
  21. /*
  22.  * The following declarations refer to internal Tk routines.  These
  23.  * interfaces are available for use, but are not supported.
  24.  */
  25. /*
  26.  * Forward declarations for procedures defined later in this file:
  27.  */
  28. static void setargv _ANSI_ARGS_((int *argcPtr, char ***argvPtr));
  29. static Tcl_PanicProc WishPanic;
  30. #ifdef TK_TEST
  31. extern int Tktest_Init(Tcl_Interp *interp);
  32. #endif /* TK_TEST */
  33. static BOOL consoleRequired = TRUE;
  34. /*
  35.  * The following #if block allows you to change the AppInit
  36.  * function by using a #define of TCL_LOCAL_APPINIT instead
  37.  * of rewriting this entire file.  The #if checks for that
  38.  * #define and uses Tcl_AppInit if it doesn't exist.
  39.  */
  40.     
  41. #ifndef TK_LOCAL_APPINIT
  42. #define TK_LOCAL_APPINIT Tcl_AppInit    
  43. #endif
  44. extern int TK_LOCAL_APPINIT _ANSI_ARGS_((Tcl_Interp *interp));
  45.     
  46. /*
  47.  * The following #if block allows you to change how Tcl finds the startup
  48.  * script, prime the library or encoding paths, fiddle with the argv,
  49.  * etc., without needing to rewrite Tk_Main()
  50.  */
  51. #ifdef TK_LOCAL_MAIN_HOOK
  52. extern int TK_LOCAL_MAIN_HOOK _ANSI_ARGS_((int *argc, char ***argv));
  53. #endif
  54. /*
  55.  *----------------------------------------------------------------------
  56.  *
  57.  * WinMain --
  58.  *
  59.  * Main entry point from Windows.
  60.  *
  61.  * Results:
  62.  * Returns false if initialization fails, otherwise it never
  63.  * returns. 
  64.  *
  65.  * Side effects:
  66.  * Just about anything, since from here we call arbitrary Tcl code.
  67.  *
  68.  *----------------------------------------------------------------------
  69.  */
  70. int APIENTRY
  71. WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  72.     HINSTANCE hInstance;
  73.     HINSTANCE hPrevInstance;
  74.     LPSTR lpszCmdLine;
  75.     int nCmdShow;
  76. {
  77.     char **argv;
  78.     int argc;
  79.     char buffer[MAX_PATH+1];
  80.     char *p;
  81.     Tcl_SetPanicProc(WishPanic);
  82.     /*
  83.      * Create the console channels and install them as the standard
  84.      * channels.  All I/O will be discarded until Tk_CreateConsoleWindow is
  85.      * called to attach the console to a text widget.
  86.      */
  87.     consoleRequired = TRUE;
  88.     /*
  89.      * Set up the default locale to be standard "C" locale so parsing
  90.      * is performed correctly.
  91.      */
  92.     setlocale(LC_ALL, "C");
  93.     setargv(&argc, &argv);
  94.     /*
  95.      * Replace argv[0] with full pathname of executable, and forward
  96.      * slashes substituted for backslashes.
  97.      */
  98.     GetModuleFileName(NULL, buffer, sizeof(buffer));
  99.     argv[0] = buffer;
  100.     for (p = buffer; *p != ''; p++) {
  101. if (*p == '\') {
  102.     *p = '/';
  103. }
  104.     }
  105. #ifdef TK_LOCAL_MAIN_HOOK
  106.     TK_LOCAL_MAIN_HOOK(&argc, &argv);
  107. #endif
  108.     Tk_Main(argc, argv, TK_LOCAL_APPINIT);
  109.     return 1;
  110. }
  111. /*
  112.  *----------------------------------------------------------------------
  113.  *
  114.  * Tcl_AppInit --
  115.  *
  116.  * This procedure performs application-specific initialization.
  117.  * Most applications, especially those that incorporate additional
  118.  * packages, will have their own version of this procedure.
  119.  *
  120.  * Results:
  121.  * Returns a standard Tcl completion code, and leaves an error
  122.  * message in the interp's result if an error occurs.
  123.  *
  124.  * Side effects:
  125.  * Depends on the startup script.
  126.  *
  127.  *----------------------------------------------------------------------
  128.  */
  129. int
  130. Tcl_AppInit(interp)
  131.     Tcl_Interp *interp; /* Interpreter for application. */
  132. {
  133.     if (Tcl_Init(interp) == TCL_ERROR) {
  134. goto error;
  135.     }
  136.     if (Tk_Init(interp) == TCL_ERROR) {
  137. goto error;
  138.     }
  139.     Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit);
  140.     /*
  141.      * Initialize the console only if we are running as an interactive
  142.      * application.
  143.      */
  144.     if (consoleRequired) {
  145. if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
  146.     goto error;
  147. }
  148.     }
  149. #if defined(STATIC_BUILD) && defined(TCL_USE_STATIC_PACKAGES)
  150.     {
  151. extern Tcl_PackageInitProc Registry_Init;
  152. extern Tcl_PackageInitProc Dde_Init;
  153. if (Registry_Init(interp) == TCL_ERROR) {
  154.     return TCL_ERROR;
  155. }
  156. Tcl_StaticPackage(interp, "registry", Registry_Init, NULL);
  157. if (Dde_Init(interp) == TCL_ERROR) {
  158.     return TCL_ERROR;
  159. }
  160. Tcl_StaticPackage(interp, "dde", Dde_Init, NULL);
  161.    }
  162. #endif
  163. #ifdef TK_TEST
  164.     if (Tktest_Init(interp) == TCL_ERROR) {
  165. goto error;
  166.     }
  167.     Tcl_StaticPackage(interp, "Tktest", Tktest_Init,
  168.             (Tcl_PackageInitProc *) NULL);
  169. #endif /* TK_TEST */
  170.     Tcl_SetVar(interp, "tcl_rcFileName", "~/wishrc.tcl", TCL_GLOBAL_ONLY);
  171.     return TCL_OK;
  172. error:
  173.     MessageBeep(MB_ICONEXCLAMATION);
  174.     MessageBox(NULL, Tcl_GetStringResult(interp), "Error in Wish",
  175.     MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
  176.     ExitProcess(1);
  177.     /* we won't reach this, but we need the return */
  178.     return TCL_ERROR;
  179. }
  180. /*
  181.  *----------------------------------------------------------------------
  182.  *
  183.  * WishPanic --
  184.  *
  185.  * Display a message and exit.
  186.  *
  187.  * Results:
  188.  * None.
  189.  *
  190.  * Side effects:
  191.  * Exits the program.
  192.  *
  193.  *----------------------------------------------------------------------
  194.  */
  195. void
  196. WishPanic TCL_VARARGS_DEF(CONST char *,arg1)
  197. {
  198.     va_list argList;
  199.     char buf[1024];
  200.     CONST char *format;
  201.     
  202.     format = TCL_VARARGS_START(CONST char *,arg1,argList);
  203.     vsprintf(buf, format, argList);
  204.     MessageBeep(MB_ICONEXCLAMATION);
  205.     MessageBox(NULL, buf, "Fatal Error in Wish",
  206.     MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
  207. #ifdef _MSC_VER
  208.     DebugBreak();
  209. #endif
  210.     ExitProcess(1);
  211. }
  212. /*
  213.  *-------------------------------------------------------------------------
  214.  *
  215.  * setargv --
  216.  *
  217.  * Parse the Windows command line string into argc/argv.  Done here
  218.  * because we don't trust the builtin argument parser in crt0.  
  219.  * Windows applications are responsible for breaking their command
  220.  * line into arguments.
  221.  *
  222.  * 2N backslashes + quote -> N backslashes + begin quoted string
  223.  * 2N + 1 backslashes + quote -> literal
  224.  * N backslashes + non-quote -> literal
  225.  * quote + quote in a quoted string -> single quote
  226.  * quote + quote not in quoted string -> empty string
  227.  * quote -> begin quoted string
  228.  *
  229.  * Results:
  230.  * Fills argcPtr with the number of arguments and argvPtr with the
  231.  * array of arguments.
  232.  *
  233.  * Side effects:
  234.  * Memory allocated.
  235.  *
  236.  *--------------------------------------------------------------------------
  237.  */
  238. static void
  239. setargv(argcPtr, argvPtr)
  240.     int *argcPtr; /* Filled with number of argument strings. */
  241.     char ***argvPtr; /* Filled with argument strings (malloc'd). */
  242. {
  243.     char *cmdLine, *p, *arg, *argSpace;
  244.     char **argv;
  245.     int argc, size, inquote, copy, slashes;
  246.     
  247.     cmdLine = GetCommandLine(); /* INTL: BUG */
  248.     /*
  249.      * Precompute an overly pessimistic guess at the number of arguments
  250.      * in the command line by counting non-space spans.
  251.      */
  252.     size = 2;
  253.     for (p = cmdLine; *p != ''; p++) {
  254. if ((*p == ' ') || (*p == 't')) { /* INTL: ISO space. */
  255.     size++;
  256.     while ((*p == ' ') || (*p == 't')) { /* INTL: ISO space. */
  257. p++;
  258.     }
  259.     if (*p == '') {
  260. break;
  261.     }
  262. }
  263.     }
  264.     argSpace = (char *) Tcl_Alloc(
  265.     (unsigned) (size * sizeof(char *) + strlen(cmdLine) + 1));
  266.     argv = (char **) argSpace;
  267.     argSpace += size * sizeof(char *);
  268.     size--;
  269.     p = cmdLine;
  270.     for (argc = 0; argc < size; argc++) {
  271. argv[argc] = arg = argSpace;
  272. while ((*p == ' ') || (*p == 't')) { /* INTL: ISO space. */
  273.     p++;
  274. }
  275. if (*p == '') {
  276.     break;
  277. }
  278. inquote = 0;
  279. slashes = 0;
  280. while (1) {
  281.     copy = 1;
  282.     while (*p == '\') {
  283. slashes++;
  284. p++;
  285.     }
  286.     if (*p == '"') {
  287. if ((slashes & 1) == 0) {
  288.     copy = 0;
  289.     if ((inquote) && (p[1] == '"')) {
  290. p++;
  291. copy = 1;
  292.     } else {
  293. inquote = !inquote;
  294.     }
  295.                 }
  296.                 slashes >>= 1;
  297.             }
  298.             while (slashes) {
  299. *arg = '\';
  300. arg++;
  301. slashes--;
  302.     }
  303.     if ((*p == '')
  304.     || (!inquote && ((*p == ' ') || (*p == 't')))) { /* INTL: ISO space. */
  305. break;
  306.     }
  307.     if (copy != 0) {
  308. *arg = *p;
  309. arg++;
  310.     }
  311.     p++;
  312.         }
  313. *arg = '';
  314. argSpace = arg + 1;
  315.     }
  316.     argv[argc] = NULL;
  317.     *argcPtr = argc;
  318.     *argvPtr = argv;
  319. }
  320. #if !defined(__GNUC__) || defined(TK_TEST)
  321. /*
  322.  *----------------------------------------------------------------------
  323.  *
  324.  * main --
  325.  *
  326.  * Main entry point from the console.
  327.  *
  328.  * Results:
  329.  * None: Tk_Main never returns here, so this procedure never
  330.  *      returns either.
  331.  *
  332.  * Side effects:
  333.  * Whatever the applications does.
  334.  *
  335.  *----------------------------------------------------------------------
  336.  */
  337. int main(int argc, char **argv)
  338. {
  339.     Tcl_SetPanicProc(WishPanic);
  340.     /*
  341.      * Set up the default locale to be standard "C" locale so parsing
  342.      * is performed correctly.
  343.      */
  344.     setlocale(LC_ALL, "C");
  345.     /*
  346.      * Create the console channels and install them as the standard
  347.      * channels.  All I/O will be discarded until Tk_CreateConsoleWindow is
  348.      * called to attach the console to a text widget.
  349.      */
  350.     consoleRequired = FALSE;
  351.     Tk_Main(argc, argv, Tcl_AppInit);
  352.     return 0;
  353. }
  354. #endif /* !__GNUC__ || TK_TEST */