home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR9 / WDOS0793.ZIP / WILLIAMS.ZIP / WMENU.C next >
C/C++ Source or Header  |  1993-05-07  |  10KB  |  391 lines

  1. /* WMENU application launcher -- Al Williams
  2.  *
  3.  *  To compile:   cc wmenu.c
  4.  */
  5. #include <windows.h>
  6. #include <mmsystem.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <stdarg.h>
  12. #if defined(__BORLANDC__) || defined(__ZTC__)
  13.     #include <dir.h>
  14.     #define CHDIR   chdir
  15.     #define STRDUP  strdup
  16.     #define GETCWD  getcwd
  17. #else
  18.     #include <direct.h>
  19.     #define CHDIR   _chdir
  20.     #define STRDUP  _strdup
  21.     #define GETCWD  _getcwd
  22. #endif
  23. #include "wmenu.h"
  24.  
  25. HANDLE hInst;       /* current instance */
  26. HWND topwindow;     /* main window */
  27. HMENU topmenu;      /* Main menu */
  28. char string[1025];  /* GP string */
  29. char *menulines[100];/* array of menu items */
  30. char *execerr[] =   /* WinExec errors */
  31.   {
  32.   "Out of memory",
  33.   NULL,
  34.   "File not found",
  35.   "Path not found",
  36.   NULL,
  37.   "Can't dynamically link task",
  38.   "Library requires separate data segments",
  39.   NULL,
  40.   NULL,
  41.   NULL,
  42.   "Incorrect Windows version",
  43.   "Bad EXE format",
  44.   "OS/2 application",
  45.   "DOS 4.0 application",
  46.   "Unknown EXE type",
  47.   "Incorrect Windows version",
  48.   "Can't run multiple copies of this program",
  49.   "Can't run multiple copies of this program",
  50.   "This program requires protected mode",
  51.   };
  52.  
  53. /* Main window function */
  54. int PASCAL WinMain (HANDLE hInst, HANDLE prev,
  55.                            LPSTR cmdline, int show)
  56.   {
  57.   MSG msg;
  58.   char cwd[81];
  59.   if (!init (hInst, prev, show))   /* set up app */
  60.     return FALSE;
  61.   topmenu = GetMenu (topwindow);   /* Get handle for menu */
  62.   if (!file_read (cmdline))        /* process file */
  63.     return FALSE;
  64. /* Get directory from profile */
  65.   GetProfileString ("WMENU", "CurrentDirectory", "\\",
  66.                     cwd, sizeof (cwd));
  67. /* Set directory */
  68.   if (CHDIR (cwd))
  69.       {
  70.       MessageBox (topwindow, "Invalid working directory",
  71.                   "Warning", MB_OK | MB_ICONSTOP);
  72.       };
  73.  
  74.   while (GetMessage (&msg, NULL, NULL, NULL))
  75.       {
  76.       TranslateMessage (&msg);
  77.       DispatchMessage (&msg);
  78.       }
  79.   return (msg.wParam);
  80.   }
  81.  
  82. /* Start up stuff */
  83. int init (HANDLE hInst, HANDLE prev, int show)
  84.   {
  85.   if (!prev)
  86.       if (!init_app (hInst))
  87.         return FALSE;
  88.   if (!init_inst (hInst, show))
  89.     return FALSE;
  90.   return TRUE;
  91.   }
  92.  
  93. /* Create window class here */
  94. BOOL init_app (HANDLE hInstance)
  95.   {
  96.   WNDCLASS wc;
  97.   wc.style = NULL;
  98.   wc.lpfnWndProc = (void _far *) win_proc;
  99.   wc.cbClsExtra = 0;
  100.   wc.cbWndExtra = 0;
  101.   wc.hInstance = hInstance;
  102.   wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  103.   wc.hCursor = LoadCursor (NULL, IDC_ARROW);
  104.   wc.hbrBackground = GetStockObject (WHITE_BRUSH);
  105.   wc.lpszMenuName = "WMENU";
  106.   wc.lpszClassName = "WMENU_Class";
  107.   return (RegisterClass (&wc));
  108.   }
  109.  
  110. /* Create window here */
  111. BOOL init_inst (HANDLE hInstance, int nCmdShow)
  112.   {
  113.   HWND hWnd;
  114. /* Save the instance handle in global variable */
  115.   hInst = hInstance;
  116. /* Create the main window */
  117.   topwindow = hWnd = CreateWindow ("WMENU_Class", "WMENU",
  118.          WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,
  119.          0, 0, GetSystemMetrics (SM_CXFULLSCREEN),
  120.          GetSystemMetrics (SM_CYMENU) +
  121.          GetSystemMetrics (SM_CYCAPTION) + 2, NULL, NULL,
  122.          hInstance, NULL);
  123.   if (!hWnd)
  124.     return FALSE;
  125.  
  126.   ShowWindow (hWnd, nCmdShow);
  127.   UpdateWindow (hWnd);
  128.   return (TRUE);
  129.   }
  130.  
  131. long FAR PASCAL _export win_proc (HWND hWnd, WORD message,
  132.                                  WORD wParam, LONG lParam)
  133.   {
  134.   switch (message)
  135.       {
  136. /* menu commands .... */
  137.       case WM_COMMAND:
  138.       menu (hWnd, wParam);
  139.       break;
  140.  
  141. /* End of the road... */
  142.     case WM_DESTROY:
  143.       PostQuitMessage (0);
  144.       break;
  145.  
  146.     default:
  147.       return (DefWindowProc (hWnd, message,
  148.                              wParam, lParam));
  149.       }
  150.   return NULL;
  151.   }
  152.  
  153. /* Menu handling code */
  154. void menu (HWND hWnd, int wParam)
  155.   {
  156.   char cmd[512];
  157.   char *line, *cd;
  158.   int stat;
  159. /* If wParam>=200 then this is a user menu item */
  160.   if (wParam >= 200)
  161.       {
  162.       int offset = 0;
  163. /* adjust to 0 */
  164.       wParam -= 200;
  165. /* skip space */
  166.       while (isspace (menulines[wParam][offset]))
  167.         offset++;
  168. /* If edit requested */
  169.       if (menulines[wParam][offset] == '*')
  170.           {
  171. /* skip asterisk */
  172.           offset += 1;
  173. /* skip space again */
  174.           while (isspace (menulines[wParam][offset]))
  175.             offset++;
  176. /* get line */
  177.           strcpy (cmd, menulines[wParam] + offset);
  178. /* edit it */
  179.           line = get_input (cmd, sizeof (cmd),
  180.               "Edit command line", "Current directory=%s",
  181.                             cd = GETCWD (NULL, 128));
  182.           free (cd);
  183. /* if line is NULL, then cancel */
  184.           if (line)
  185. /* otherwise run command */
  186.             stat = WinExec (line, SW_SHOW);
  187.           }
  188.       else
  189. /* No editing, just run command */
  190.         stat = WinExec (menulines[wParam] + offset, SW_SHOW);
  191.       if (stat < 32)
  192.           {
  193. /* ERROR! */
  194.           if (stat > sizeof (execerr) / sizeof (char *)
  195.               || execerr[stat] == NULL)
  196.             line = "Unknown error";
  197.           else
  198.             line = execerr[stat];
  199.           MessageBox (topwindow, line, NULL,
  200.                       MB_OK | MB_ICONSTOP);
  201.           }
  202.  
  203.       return;
  204.       }
  205. /* "Normal" menu code (from file menu) */
  206.   switch (wParam)
  207.       {
  208.     case IDM_ABOUT:
  209.       MessageBox (topwindow,
  210.                   "WMENU Version 1.0 by Al Williams",
  211.                   "About", MB_OK | MB_ICONINFORMATION);
  212.       return;
  213.  
  214.     case IDM_DIR:
  215. /* Change working directory */
  216.       GETCWD (cmd, sizeof (cmd));
  217.       line = get_input (cmd, sizeof (cmd),
  218.         "Enter working directory", "Current directory=%s",
  219.                         cd = GETCWD (NULL, 128));
  220.       if (line)
  221.           {
  222.           if (CHDIR (line))
  223.               {
  224.               MessageBox (NULL, "Bad directory",
  225.                           NULL, MB_OK | MB_ICONSTOP);
  226.               return;
  227.               }
  228. /* Save in INI file */
  229.           WriteProfileString ("WMENU", "CurrentDirectory",
  230.                               line);
  231.           }
  232.       return;
  233.  
  234.     case IDM_QUIT:
  235.       DestroyWindow (hWnd);
  236.       return;
  237.  
  238.       }
  239.   }
  240.  
  241. /* Process file */
  242. int file_read (LPSTR cmdline)
  243.   {
  244.   FILE *f;
  245.   char far *p, *sp = string;
  246. /* get filename from cmdline. We must copy it to a local
  247.    buffer since we will probably want to use small model.
  248.    fopen() won't take an LPSTR (long pointer to string)
  249.    as an argument. */
  250. /* skip spaces */
  251.   while (isspace (*cmdline))
  252.     cmdline++;
  253.   p = cmdline;
  254. /* skip to next space */
  255.   while (*p && !isspace (*p))
  256.     *sp++ = *p++;
  257. /* if no file name use wmenu.dat in current directory */
  258.   if (p == cmdline)
  259.     strcpy (string, "wmenu.dat");
  260.   else
  261.     *sp = '\0';
  262.   f = fopen (string, "r");
  263.   if (!f)
  264.       {
  265.       MessageBox (topwindow, "Usage: WMENU filename",
  266.                   "Filename Required",
  267.                   MB_OK | MB_ICONSTOP);
  268.       return FALSE;
  269.       }
  270.   else
  271.       {
  272.       int menuid = 200;
  273.       char *p;
  274. /* get line */
  275.       fgets (string, sizeof (string), f);
  276. /* chop off \n */
  277.       p = strchr (string, '\n');
  278.       if (p)
  279.         *p = '\0';
  280. /* Set title (first line) */
  281.       SendMessage (topwindow, WM_SETTEXT, 0,
  282.                                        (long)(LPSTR)string);
  283. /* Get subsequent lines */
  284.       while (fgets (string, sizeof (string), f))
  285.           {
  286.           HMENU pop;
  287. /* chop of \n */
  288.           char *p = strchr (string, '\n');
  289.           if (p)
  290.             *p = '\0';
  291. /* is this a popup line or a item line? */
  292.           p = strchr (string, ':');
  293.           if (!p)
  294.               {
  295. /* popup -- create new one */
  296.               pop = CreatePopupMenu ();
  297.               AppendMenu (topmenu,
  298.                           MF_STRING | MF_POPUP | MF_ENABLED,
  299.                           pop, string);
  300.               }
  301.           else
  302.               {
  303.               *p = '\0';
  304. /* save command line */
  305.               menulines[menuid - 200] = STRDUP (p + 1);
  306. /* add to current popup menu */
  307.               AppendMenu (pop, MF_STRING | MF_ENABLED,
  308.                           menuid++, string);
  309.               }
  310.           }
  311. /* fix menu bar */
  312.       DrawMenuBar (topwindow);
  313.       fclose (f);
  314.       }
  315.   return TRUE;
  316.   }
  317.  
  318. /* Stuff for general purpose input function */
  319. static char *ibuf;
  320. static int isize;
  321. static char print_buf[513];
  322.  
  323. /* Dialog callback for input function */
  324. BOOL FAR PASCAL _export inp_dlg (HWND hDlg,
  325.                  unsigned message, WORD wParam, LONG lParam)
  326.   {
  327.   switch (message)
  328.       {
  329.       case WM_INITDIALOG:
  330. /* Set title */
  331.       SendMessage (hDlg, WM_SETTEXT, 0, lParam);
  332. /* Set prompt */
  333.       SetDlgItemText (hDlg, 101, print_buf);
  334. /* Set field */
  335.       SetDlgItemText (hDlg, 102, ibuf);
  336.       return (TRUE);
  337.  
  338.     case WM_COMMAND:
  339.       if (wParam == IDOK)
  340.           {
  341. /* read input */
  342.           GetDlgItemText (hDlg, 102, ibuf, isize);
  343.           EndDialog (hDlg, TRUE);
  344.           return (TRUE);
  345.           }
  346. /* return NULL for cancel */
  347.       if (wParam == IDCANCEL)
  348.           {
  349.           ibuf = NULL;
  350.           EndDialog (hDlg, TRUE);
  351.           return TRUE;
  352.           }
  353.       break;
  354.       }
  355.   return FALSE;
  356.   }
  357.  
  358.  
  359. /* Input function -- buf of siz bytes contains string to
  360.    edit (or \0). title is the edit box's title, fmt is a
  361.    printf-style format for the prompt. Other arguments
  362.    are for % args in fmt. */
  363. char *get_input (char *buf, unsigned siz,
  364.                       char *title, char *fmt,...)
  365.   {
  366.   FARPROC dlgfunc;
  367.   int rc;
  368.   va_list alist;
  369.   va_start (alist, fmt);
  370. /* print prompt to print_buf */
  371.   rc = vsprintf (print_buf, fmt, alist);
  372.   if (rc != -1)
  373.       {
  374.       dlgfunc = MakeProcInstance ((FARPROC)inp_dlg, hInst);
  375.       if (!dlgfunc)
  376.         return NULL;
  377.       else
  378.           {
  379. /* call dialog */
  380.           ibuf = buf;
  381.           isize = siz;
  382.           rc = DialogBoxParam (hInst, "InputBox",
  383.                                NULL, dlgfunc, (long) title);
  384.           FreeProcInstance (dlgfunc);
  385.           if(rc < 0)
  386.             return NULL;
  387.           }
  388.       }
  389.   return ibuf;
  390.   }
  391.