home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / w3_prog / zap.arj / Z1.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-12  |  16.1 KB  |  553 lines

  1. /***********************************************************************
  2. * Zap                                                                  *
  3. * ===                                                                  *
  4. *                                                                      *
  5. * Windows 3 Text Editor                                                *
  6. *                                                                      *
  7. * This programme uses the Windows edit control as an editting engine,  *
  8. * and hence is limited to 32K - 1 characters.  The edit control is     *
  9. * sub-classed to provide additional functionality.                     *
  10. *                                                                      *
  11. * Main module                                                          *
  12. *   int  PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);                   *
  13. *   BOOL InitApplication(HANDLE);                                      *
  14. *   BOOL InitInstance(HANDLE, int);                                    *
  15. *   long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);           *
  16. *   BOOL FAR PASCAL AboutProc(HWND, unsigned, WORD, LONG);             *
  17. *   void Comment(char *);                                              *
  18. *                                                                      *
  19. * This programme was developed using Microsoft C6.0 and the Microsoft  *
  20. * SDK, however any ANSI C could be used if suitable libraries and the  *
  21. * Windows header are available.                                        *
  22. ***********************************************************************/
  23.  
  24. #include <windows.h>
  25. #include <commdlg.h>
  26. #include <string.h>
  27. #include "zap.h"
  28. #include "zapdlg.h"
  29.  
  30.  
  31. /***********************************************************************
  32. * Global variables                                                     *
  33. ***********************************************************************/
  34.  
  35. /*** System variables */
  36.  
  37. HANDLE hInst;
  38. HWND   hMainWnd;
  39.  
  40. /*** Edit windows */
  41.  
  42. EDIT_WND EditWnd[MAX_FILES];
  43. int NumFiles, CurrentFile;
  44.  
  45. /*** Pointer to sub-classing function */
  46.  
  47. FARPROC lpNewEditWndProc;
  48.  
  49. /*** Buffer for manipulating window contents */
  50.  
  51. HANDLE hTransBuf;
  52. LPSTR  TransBuf;
  53.  
  54. /*** Dialog box variables */
  55.  
  56. OPENFILENAME OpenFileInfo;
  57. char FilterSpec[128] = "All Files  (*.*)\0*.*\0"
  58.                        "Text Files (*.TXT)\0*.TXT\0"
  59.                        "C programs (*.C)\0*.C\0";
  60.  
  61. char FileName[MAX_DOS_NAME], FileTitle[MAX_DOS_NAME];
  62.  
  63. /*** Miscellaneous variables */
  64.  
  65. int  CharWd, CharDp;
  66.  
  67. char WorkStr[WORK_STR_LEN];
  68.  
  69.  
  70. /***********************************************************************
  71. * Entry point from Windows                                             *
  72. ***********************************************************************/
  73.  
  74. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow )
  75. { WORD i, j;
  76.   HDC hDC;
  77.   MSG msg;
  78.  
  79. /*** Initialise application */
  80.  
  81.   if (!hPrevInstance)
  82.   { if (!InitApplication(hInstance))
  83.     { Comment("System error: Cannot register window class");
  84.       return(FALSE);
  85.     }
  86.   }
  87.  
  88.   if (!InitInstance(hInstance, nCmdShow)) return(FALSE);
  89.  
  90. /*** If a file name was given open it */
  91.  
  92.   if (lpszCmdLine[0] != '\0')
  93.   { for (i = 0; lpszCmdLine[i] == ' '; i++);
  94.     for (j = 0; lpszCmdLine[i] != ' ' && lpszCmdLine[i] != '\0'; j++, i++)
  95.       FileName[j] = lpszCmdLine[i];
  96.     FileName[j] = '\0';
  97.  
  98.     if ((j = _lopen(FileName, OF_READ)) == -1)
  99.     { sprintf(WorkStr, "Cannot open file \"%s\"", FileName);
  100.       Comment(WorkStr);
  101.     }
  102.     else
  103.     { if ((i = _lread(j, TransBuf, TRANS_BUF_SIZE - 1)) == TRANS_BUF_SIZE - 1)
  104.         Comment("Warning: file is too big and has been truncated");
  105.       TransBuf[i] = '\0';
  106.  
  107.       _lclose(j);
  108.  
  109.       SetWindowText(EditWnd[0].hwnd, TransBuf);
  110.       strcpy(EditWnd[0].name, FileName);
  111.  
  112.       hDC = GetDC(hMainWnd);
  113.       RedrawStatusBar(hDC, 0);
  114.       ReleaseDC(hMainWnd, hDC);
  115.     }
  116.   }
  117.  
  118. /*** Enter message loop */
  119.  
  120.   while (GetMessage(&msg, NULL, NULL, NULL))
  121.   { TranslateMessage(&msg);
  122.     DispatchMessage(&msg);
  123.   }
  124.  
  125.   return (msg.wParam);
  126. }
  127.  
  128.  
  129. /***********************************************************************
  130. * Application initialisation routine                                   *
  131. * Creates window class for application                                 *
  132. ***********************************************************************/
  133.  
  134. BOOL InitApplication(HANDLE hInstance)
  135. { WNDCLASS  wc;
  136.  
  137.   wc.style         = CS_OWNDC;
  138.   wc.lpfnWndProc   = MainWndProc;
  139.   wc.cbClsExtra    = 0;
  140.   wc.cbWndExtra    = 0;
  141.   wc.hInstance     = hInstance;
  142.   wc.hIcon         = LoadIcon(hInstance, "ZapIcon");
  143.   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  144.   wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  145.   wc.lpszMenuName  = "ZapMenu";
  146.   wc.lpszClassName = "ZapWClass";
  147.  
  148.   return (RegisterClass(&wc));
  149.  
  150.  
  151. /****************************************************************************
  152. * Instance initialisation routine
  153. ****************************************************************************/
  154.  
  155. BOOL InitInstance(HANDLE hInstance, int nCmdShow)
  156. { int i;
  157.   HDC hDC;
  158.   RECT wrect;
  159.   TEXTMETRIC tm;
  160.  
  161.   hInst = hInstance;
  162.  
  163. /*** Allocate the file transfer buffer */
  164.  
  165.   if (!(hTransBuf = GlobalAlloc(GMEM_MOVEABLE, TRANS_BUF_SIZE)))
  166.   { Comment("System error: Insufficient memory for buffers");
  167.     return(FALSE);
  168.   }
  169.  
  170.   if (!(TransBuf = GlobalLock(hTransBuf)))
  171.   { Comment("System error: Insufficient memory to lock buffers");
  172.     return(FALSE);
  173.   }
  174.  
  175. /*** Create instance for the subclassing procedure */
  176.  
  177.   lpNewEditWndProc = MakeProcInstance((FARPROC)NewEditWndProc, hInst);
  178.  
  179. /*** Create window and get context */
  180.  
  181.   hMainWnd = CreateWindow("ZapWClass",
  182.                           "Zap",
  183.                           WS_OVERLAPPEDWINDOW,
  184.                           CW_USEDEFAULT,
  185.                           CW_USEDEFAULT,
  186.                           CW_USEDEFAULT,
  187.                           CW_USEDEFAULT,
  188.                           NULL,
  189.                           NULL,
  190.                           hInstance,
  191.                           NULL);
  192.   if (!hMainWnd) return (FALSE);
  193.  
  194. /*** Create the edit control */
  195.  
  196.   NumFiles = 0;
  197.  
  198.   if (!CreateEditWindow())
  199.   { DestroyWindow(hMainWnd);
  200.     return(FALSE);
  201.   }
  202.  
  203. /*** Resize main window and centre it on screen */
  204.  
  205.   hDC = GetDC(hMainWnd);
  206.  
  207.   SelectObject(hDC, GetStockObject(ANSI_FIXED_FONT));
  208.   GetTextMetrics(hDC, &tm);
  209.   CharWd = tm.tmAveCharWidth;
  210.   CharDp = tm.tmHeight;
  211.  
  212.   GetWindowRect(hMainWnd, &wrect);
  213.   srand(wrect.left);
  214.  
  215.   wrect.right  = CharWd*INITIAL_WIDTH
  216.                          + 2*GetSystemMetrics(SM_CXFRAME);
  217.  
  218.   wrect.bottom = CharDp*INITIAL_DEPTH
  219.                          + 2*GetSystemMetrics(SM_CYFRAME)
  220.                          +   GetSystemMetrics(SM_CYCAPTION)
  221.                          +   GetSystemMetrics(SM_CYMENU);
  222.  
  223.   wrect.left = rand() % (GetDeviceCaps(hDC, HORZRES) - wrect.right);
  224.   wrect.top  = rand() % (GetDeviceCaps(hDC, VERTRES) - wrect.bottom);
  225.   MoveWindow(hMainWnd, wrect.left, wrect.top, wrect.right, wrect.bottom, FALSE);
  226.  
  227.   ReleaseDC(hMainWnd, hDC);
  228.  
  229. /*** File dialog box info structure */
  230.  
  231.   OpenFileInfo.lStructSize       = sizeof(OPENFILENAME);
  232.   OpenFileInfo.hwndOwner         = hMainWnd;
  233.   OpenFileInfo.lpstrFilter       = FilterSpec;
  234.   OpenFileInfo.lpstrCustomFilter = NULL;
  235.   OpenFileInfo.nMaxCustFilter    = 0;
  236.   OpenFileInfo.nFilterIndex      = 1;
  237.   OpenFileInfo.lpstrFile         = FileName;
  238.   OpenFileInfo.nMaxFile          = MAX_DOS_NAME;
  239.   OpenFileInfo.lpstrInitialDir   = NULL;
  240.   OpenFileInfo.lpstrFileTitle    = FileTitle;
  241.   OpenFileInfo.nMaxFileTitle     = MAX_DOS_NAME;
  242.   OpenFileInfo.lpstrTitle        = NULL;
  243.   OpenFileInfo.lpstrDefExt       = "TXT";
  244.   OpenFileInfo.Flags             = 0;
  245.  
  246. /*** Display window and return*/
  247.  
  248.   ShowWindow(hMainWnd, nCmdShow);
  249.   UpdateWindow(hMainWnd);
  250.  
  251.   return(TRUE);
  252. }
  253.  
  254.  
  255. /***********************************************************************
  256. * Message handler for main window                                      *
  257. ***********************************************************************/
  258.  
  259. long FAR PASCAL MainWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
  260. { int i;
  261.   FARPROC lp_proc;
  262.   HDC hDC;
  263.   PAINTSTRUCT ps;
  264.  
  265.   switch (message)
  266.   { case WM_COMMAND:
  267.       switch (wParam)
  268.       {
  269.  
  270. /*** Create a new file */
  271.  
  272.         case IDM_FILE_NEW:
  273.           if (SendMessage(CurWnd, EM_GETMODIFY, 0, 0L))
  274.           { sprintf(WorkStr, "Save %s", EditWnd[CurrentFile].name);
  275.             i = MessageBox(GetFocus(), WorkStr, "Zap", MB_YESNOCANCEL | MB_ICONQUESTION);
  276.             if (i == IDCANCEL)
  277.               break;
  278.             if (i == IDYES)
  279.               SaveFile(CurrentFile, TRUE);
  280.           }
  281.  
  282.           SetWindowText(CurWnd, "");
  283.           SendMessage(CurWnd, EM_SETMODIFY, 0, 0L);
  284.           strcpy(EditWnd[CurrentFile].name, UNTITLED);
  285.  
  286.           hDC = GetDC(hMainWnd);
  287.           RedrawStatusBar(hDC, CurrentFile);
  288.           ReleaseDC(hMainWnd, hDC);
  289.  
  290.           break;
  291.  
  292. /*** Open a file */
  293.  
  294.         case IDM_FILE_OPEN:
  295.           if (SendMessage(CurWnd, EM_GETMODIFY, 0, 0L))
  296.           { sprintf(WorkStr, "Save %s", EditWnd[CurrentFile].name);
  297.             i = MessageBox(GetFocus(), WorkStr, "Zap", MB_YESNOCANCEL | MB_ICONQUESTION);
  298.             if (i == IDCANCEL)
  299.               break;
  300.             if (i == IDYES)
  301.               SaveFile(CurrentFile, TRUE);
  302.           }
  303.  
  304.           ReadFile(CurrentFile, TRUE);
  305.           SendMessage(CurWnd, EM_SETMODIFY, 0, 0L);
  306.  
  307.           hDC = GetDC(hMainWnd);
  308.           RedrawStatusBar(hDC, CurrentFile);
  309.           ReleaseDC(hMainWnd, hDC);
  310.  
  311.           break;
  312.  
  313. /*** Save the file using the current name */
  314.  
  315.         case IDM_FILE_SAVE:
  316.           SaveFile(CurrentFile, TRUE);
  317.           SendMessage(CurWnd, EM_SETMODIFY, 0, 0L);
  318.           break;
  319.  
  320. /*** Save the file supplying a name */
  321.  
  322.         case IDM_FILE_SAVEAS:
  323.           SaveFile(CurrentFile, FALSE);
  324.           SendMessage(CurWnd, EM_SETMODIFY, 0, 0L);
  325.           break;
  326.  
  327. /*** Insert the contents of a file */
  328.  
  329.         case IDM_FILE_INSERT:
  330.           ReadFile(CurrentFile, FALSE);
  331.           SendMessage(CurWnd, EM_SETMODIFY, 1, 0L);
  332.           break;
  333.  
  334. /*** Print a file */
  335.  
  336.         case IDM_FILE_PRINT:
  337.           PrintFile(CurrentFile);
  338.           break;
  339.  
  340. /*** Exit */
  341.  
  342.         case IDM_FILE_EXIT:
  343.           for (i = 0; i < NumFiles; i++)
  344.           { if (SendMessage(EditWnd[i].hwnd, EM_GETMODIFY, 0, 0L))
  345.             { sprintf(WorkStr, "Save %s", EditWnd[i].name);
  346.               i = MessageBox(GetFocus(), WorkStr, "Zap", MB_YESNOCANCEL | MB_ICONQUESTION);
  347.               if (i == IDCANCEL)
  348.                 return(0L);
  349.               if (i == IDYES)
  350.                 SaveFile(CurrentFile, TRUE);
  351.             }
  352.           }
  353.  
  354.           DestroyWindow(hMainWnd);
  355.           break;
  356.  
  357. /*** Traditional about box */
  358.  
  359.         case IDM_FILE_ABOUT:
  360.           lp_proc = MakeProcInstance(AboutProc, hInst);
  361.           DialogBox(hInst, "AboutBox", hWnd, lp_proc);
  362.           FreeProcInstance(lp_proc);
  363.           break;
  364.  
  365. /*** The edit commands are mostly passed straight on to the controls */
  366.  
  367.         case IDM_EDIT_UNDO:
  368.           CallWindowProc(CurWndProc, CurWnd, EM_UNDO, 0, 0L);
  369.           break;
  370.  
  371.         case IDM_EDIT_CUT:
  372.           CallWindowProc(CurWndProc, CurWnd, WM_CUT, 0, 0L);
  373.           break;
  374.  
  375.         case IDM_EDIT_COPY:
  376.           CallWindowProc(CurWndProc, CurWnd, WM_COPY, 0, 0L);
  377.           break;
  378.  
  379.         case IDM_EDIT_PASTE:
  380.           CallWindowProc(CurWndProc, CurWnd, WM_PASTE, 0, 0L);
  381.           break;
  382.  
  383.         case IDM_EDIT_CLEAR:
  384.           CallWindowProc(CurWndProc, CurWnd, WM_CLEAR, 0, 0L);
  385.           break;
  386.  
  387.         case IDM_EDIT_SELECTALL:
  388.           CallWindowProc(CurWndProc, CurWnd, EM_SETSEL, 0, MAKELONG(0, 0X7FFF));
  389.           break;
  390.  
  391. /*** Search file for string */
  392.  
  393.         case IDM_EDIT_SEARCH:
  394.           lp_proc = MakeProcInstance(SearchProc, hInst);
  395.           DialogBox(hInst, "SearchBox", hWnd, lp_proc);
  396.           FreeProcInstance(lp_proc);
  397.           break;
  398.  
  399. /*** Replace string in file */
  400.  
  401.         case IDM_EDIT_REPLACE:
  402.           lp_proc = MakeProcInstance(ReplaceProc, hInst);
  403.           DialogBox(hInst, "ReplaceBox", hWnd, lp_proc);
  404.           FreeProcInstance(lp_proc);
  405.           break;
  406.  
  407. /*** Open a new window */
  408.  
  409.         case IDM_WINDOW_OPEN:
  410.           if (CreateEditWindow())
  411.           { ReadFile(CurrentFile, TRUE);
  412.             SendMessage(CurWnd, EM_SETMODIFY, 0, 0L);
  413.             RearrangeEditWindows();
  414.           }
  415.           break;
  416.  
  417. /*** Close a window */
  418.  
  419.         case IDM_WINDOW_CLOSE:
  420.           if (NumFiles == 1)
  421.           { PostMessage(hWnd, WM_COMMAND, IDM_FILE_EXIT, 0L);
  422.             break;
  423.           }
  424.  
  425.           if (SendMessage(CurWnd, EM_GETMODIFY, 0, 0L))
  426.           { sprintf(WorkStr, "Save %s", EditWnd[CurrentFile].name);
  427.             i = MessageBox(GetFocus(), WorkStr, "Zap", MB_YESNOCANCEL | MB_ICONQUESTION);
  428.             if (i == IDCANCEL)
  429.               break;
  430.             if (i == IDYES)
  431.               SaveFile(CurrentFile, TRUE);
  432.           }
  433.  
  434.           DestroyWindow(CurWnd);
  435.           GlobalFree(EditWnd[CurrentFile].ds);
  436.           for (i = CurrentFile + 1; i < NumFiles; i++)
  437.             EditWnd[i-1] = EditWnd[i];
  438.           NumFiles--;
  439.  
  440.           if (CurrentFile == NumFiles) CurrentFile--;
  441.           RearrangeEditWindows();
  442.           SetFocus(CurWnd);
  443.           break;
  444.  
  445. /*** Finally check for messages from edit controls */
  446.  
  447.         default:
  448.           for (i = 0; i < NumFiles; i++)
  449.           { if (wParam == IDC_EDIT + i)
  450.             { switch (HIWORD(lParam))
  451.               { case EN_ERRSPACE:
  452.                   sprintf(WorkStr, "%s is too big for Zap; file has been truncated", EditWnd[i].name);
  453.                   Comment(WorkStr);
  454.                   break;
  455.  
  456.                 case EN_SETFOCUS:
  457.                   CurrentFile = i;
  458.                   break;
  459.               }
  460.             }
  461.           }
  462.           break;
  463.       }
  464.       break;
  465.  
  466. /*** The only painting needed is the status bars */
  467.  
  468.     case WM_PAINT:
  469.       hDC = BeginPaint(hWnd, &ps);
  470.       for (i = 0; i < NumFiles; i++) RedrawStatusBar(hDC, i);
  471.       EndPaint(hWnd, &ps);
  472.       break;
  473.  
  474. /*** Adjust window size down to nearest whole number of characters */
  475.  
  476.     case WM_SIZE:
  477.       if (IsWindowVisible(hWnd))
  478.         RearrangeEditWindows();
  479.       break;
  480.  
  481. /*** Pass the focus on to the current edit window */
  482.  
  483.     case WM_SETFOCUS:
  484.       SetFocus(CurWnd);
  485.       break;
  486.  
  487. /*** On closure check all files are saved */
  488.  
  489.     case WM_CLOSE:
  490.       for (i = 0; i < NumFiles; i++)
  491.       { if (SendMessage(EditWnd[i].hwnd, EM_GETMODIFY, 0, 0L))
  492.         { sprintf(WorkStr, "Save %s", EditWnd[i].name);
  493.           i = MessageBox(GetFocus(), WorkStr, "Zap", MB_YESNOCANCEL | MB_ICONQUESTION);
  494.           if (i == IDCANCEL)
  495.             return(0L);;
  496.           if (i == IDYES)
  497.             SaveFile(CurrentFile, TRUE);
  498.         }
  499.       }
  500.       return DefWindowProc( hWnd, message, wParam, lParam );
  501.  
  502. /*** If window destroyed quit */
  503.  
  504.     case WM_DESTROY:
  505.       PostQuitMessage(0);
  506.       break;
  507.  
  508. /*** Default action */
  509.  
  510.     default:
  511.       return DefWindowProc( hWnd, message, wParam, lParam );
  512.   }
  513.  
  514.   return(0L);
  515. }
  516.  
  517.  
  518. /***********************************************************************
  519. * Message handler for About dialog box                                 *
  520. ***********************************************************************/
  521.  
  522. BOOL FAR PASCAL AboutProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  523. {
  524.   switch (message)
  525.   { case WM_INITDIALOG:
  526.       return (TRUE);
  527.  
  528.     case WM_COMMAND:
  529.       if (wParam == IDOK)
  530.       { EndDialog(hDlg, TRUE);
  531.         return (TRUE);
  532.       }
  533.       break;
  534.   }
  535.  
  536.   return (FALSE);
  537. }
  538.  
  539.  
  540. /***********************************************************************
  541. * Message routine                                                      *
  542. ***********************************************************************/
  543.  
  544. void Comment(char *str)
  545. {
  546.   MessageBox(GetFocus(),
  547.              str,
  548.              "Zap",
  549.              MB_ICONEXCLAMATION | MB_OK);
  550. }
  551.  
  552.