home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mnth0107.zip / Anderson / listings / edit.cls next >
Text File  |  1992-02-27  |  49KB  |  845 lines

  1.             Listing for edit.c                                          Page 5
  2.  
  3.           102|   /*
  4.           103|    *  EDIT.C -- A Simple Programmer's Editor Using MLE
  5.           104|    *  
  6.           105|    *  Programmer: Brian R. Anderson
  7.           106|    *  Date: January 1992
  8.           107|    *
  9.           108|    */
  10.           109|   
  11.           110|   #define INCL_WINHELP
  12.           111|   #define INCL_WIN
  13.           112|   #define INCL_GPI
  14.           113|   #define INCL_DOS
  15.           114|   #include <os2.h>
  16.           115|   #include <stdio.h>
  17.           116|   #include <string.h>
  18.           117|   #include <stdlib.h>
  19.           118|   #include "edit.h"
  20.           119|   #include "efile.h"
  21.           120|   #include "edlg.h"
  22.           121|   
  23.           122|   /* custom messages, etc. */
  24.           123|   #define WM_ARGS (WM_USER + 0)
  25.           124|   #define WM_CLEANFILE (WM_USER + 1)
  26.           125|   #define ID_MLE 13   /* my lucky number! */
  27.           126|   #define ID_UPDATE 14
  28.           127|   #define TAB 3
  29.           128|   
  30.           129|   /* local function prototypes */
  31.           130|   MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM);
  32.           131|   MRESULT EXPENTRY TabWndProc (HWND, USHORT, MPARAM, MPARAM);
  33.           132|   VOID SetPtrArrow (VOID);
  34.           133|   VOID SetPtrWait (VOID);
  35.           134|   
  36.           135|   /* global variables */
  37.           136|   HAB hab;   /* anchor block handle */
  38.           137|   HELPINIT hmiHelpData;   /* Help initialization structure*/
  39.           138|   HWND hwndHelpInstance;   /* Handle to Help window        */
  40.           139|   char szFileName[80];   /* current filename */
  41.           140|   BOOL hasName = FALSE;   /* TRUE if current file has a name */ 
  42.           141|   USHORT NeedToSave = FALSE;   /* TRUE if current file is 'Dirty' */
  43.           142|   char szFind[60];   /* target string for search */
  44.           143|   char szReplace[60];   /* replacement for search/replace */
  45.           144|   char szLine[20];   /* line number to go to */
  46.           145|   PFNWP pfMLE;   /* original MLE window procedure: subclassed to TabWndProc */
  47.           146|   
  48.           147|   
  49.           148|   int main (int argc, char *argv[])
  50.           149|   {
  51.           150|      static CHAR  szClientClass[] = "Edit";
  52.           151|      static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU |
  53.           152|                                  FCF_SIZEBORDER    | FCF_MINMAX  |
  54.           153|                                  FCF_SHELLPOSITION | FCF_TASKLIST |
  55.           154|                                  FCF_MENU | FCF_ACCELTABLE | FCF_ICON;
  56.           155|      HMQ hmq;
  57.           156|      HWND hwndFrame, hwndClient;
  58. edit.c                                                                  Page 6
  59.  
  60.           157|      QMSG qmsg;
  61.           158|      USHORT res;
  62.           159|         
  63.           160|      hab = WinInitialize (0);
  64.           161|      hmq = WinCreateMsgQueue (hab, 0);
  65.           162|   
  66.           163|      WinRegisterClass (
  67.           164|                     hab,                /* Anchor block handle            */
  68.           165|                     szClientClass,      /* Name of class being registered */
  69.           166|                     ClientWndProc,      /* Window procedure for class     */
  70.           167|                     CS_SIZEREDRAW,      /* Class style                    */
  71.           168|                     0);                 /* Extra bytes to reserve         */
  72.           169|   
  73.           170|      /* Initialization IPF structure and create help instance */
  74.           171|      hmiHelpData.cb = sizeof (HELPINIT);
  75.           172|      hmiHelpData.ulReturnCode = 0L;   /* store HM return code from init. */
  76.           173|      hmiHelpData.pszTutorialName = NULL;   /* no tutorial program */
  77.           174|      hmiHelpData.phtHelpTable = (PVOID)(0xffff0000 | ID_EDIT);  /* table in RC */
  78.           175|      hmiHelpData.hmodAccelActionBarModule = 0L;   /* normal action bar */
  79.           176|      hmiHelpData.idAccelTable = 0;
  80.           177|      hmiHelpData.idActionBar = 0;
  81.           178|      hmiHelpData.pszHelpWindowTitle = "Edit Help";
  82.           179|      hmiHelpData.hmodHelpTableModule = 0L;   /* help not in DLL */
  83.           180|      hmiHelpData.usShowPanelId = 0;   /* don't display help panel IDs */
  84.           181|      hmiHelpData.pszHelpLibraryName = "EDIT.HLP";
  85.           182|   
  86.           183|      hwndHelpInstance = WinCreateHelpInstance (hab, &hmiHelpData);
  87.           184|      if (!hwndHelpInstance) {
  88.           185|         WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  89.           186|            "Help Not Available", "Help Creation Error", 0,
  90.           187|             MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE);
  91.           188|      }
  92.           189|      else {
  93.           190|         if (hmiHelpData.ulReturnCode) {
  94.           191|            WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  95.           192|               "Help Terminated Due to Error", "Help Creation Error", 0,
  96.           193|               MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE);
  97.           194|            WinDestroyHelpInstance(hwndHelpInstance);
  98.           195|         }
  99.           196|      }
  100.           197|   
  101.           198|      hwndFrame = WinCreateStdWindow (
  102.           199|                     HWND_DESKTOP,       /* Parent window handle            */
  103.           200|                     WS_VISIBLE,         /* Style of frame window           */
  104.           201|                     &flFrameFlags,      /* Pointer to control data         */
  105.           202|                     szClientClass,      /* Client window class name        */
  106.           203|                     NULL,               /* Title bar text                  */
  107.           204|                     0L,                 /* Style of client window          */
  108.           205|                     0,                  /* Module handle for resources     */
  109.           206|                     ID_EDIT,            /* ID of resources                 */
  110.           207|                     &hwndClient);       /* Pointer to client window handle */
  111.           208|   
  112.           209|      WinStartTimer (hab, hwndClient, ID_UPDATE, 200);   /* 1/5 second */
  113.           210|      
  114.           211|      if (argc > 1) {
  115. edit.c                                                                  Page 7
  116.  
  117.           212|         strcpy (szFileName, argv[1]);
  118.           213|         WinSendMsg (hwndClient, WM_ARGS, (MPARAM) 0L, (MPARAM) 0L);
  119.           214|      }
  120.           215|   
  121.           216|      if (hwndHelpInstance) 
  122.           217|         WinAssociateHelpInstance (hwndHelpInstance, hwndFrame);
  123.           218|   
  124.           219|      for (;;) {   
  125.           220|         while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  126.           221|            WinDispatchMsg (hab, &qmsg);
  127.           222|   
  128.           223|         if (NeedToSave) {
  129.           224|            res = WinMessageBox (HWND_DESKTOP, hwndClient,
  130.           225|                                 "Save before exit?", "End Session", 0,
  131.           226|                                 MB_YESNOCANCEL | MB_ICONQUESTION | MB_MOVEABLE);
  132.           227|                           
  133.           228|            if (res == MBID_YES) {
  134.           229|               WinSendMsg (hwndClient, WM_COMMAND, 
  135.           230|                  MPFROM2SHORT (IDM_SAVE, 0), (MPARAM) 0L);
  136.           231|               break;
  137.           232|            }
  138.           233|            else if (res == MBID_NO)
  139.           234|               break;
  140.           235|            else   /* res == MBID_CANCEL */
  141.           236|               WinCancelShutdown (hmq, TRUE);
  142.           237|         }
  143.           238|         else
  144.           239|            break;   /* terminate */
  145.           240|      }                                     
  146.           241|   
  147.           242|      if (hwndHelpInstance) 
  148.           243|         WinDestroyHelpInstance (hwndHelpInstance);
  149.           244|      WinStopTimer (hab, hwndClient, ID_UPDATE);
  150.           245|      WinDestroyWindow (hwndFrame);
  151.           246|      WinDestroyMsgQueue (hmq);
  152.           247|      WinTerminate (hab);
  153.           248|      return 0;
  154.           249|   }
  155.           250|   
  156.           251|   
  157.           252|   /* main window procedure for application */
  158.           253|   MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  159.           254|   {
  160.           255|      HDC hdc;   /* device context */
  161.           256|      LONG lHRes, lVRes;   /* device resolution */
  162.           257|      HPS hps;   /* presentation space */
  163.           258|      RECTL rcl;   /* rectangle drawing coordinates */
  164.           259|      PSWP pswp;   /* set window position structure */
  165.           260|      static HWND hwndFrame, hwndClient, hwndMenu, hwndMLE;   /* window handles */
  166.           261|      static USHORT cyClient, cxClient;   /* size of edit window */
  167.           262|      LONG selmin, selmax;   /* text selected for deletion */
  168.           263|      SHORT undoable;   /* TRUE if last operation can be undone */
  169.           264|      static BOOL undone = FALSE;   /* allows for redo immediately after undo */
  170.           265|      CHAR str[60];   /* character string for output messages */
  171.           266|      USHORT newline, newcolumn;   /* latest cursor position -- changed? */
  172. edit.c                                                                  Page 8
  173.  
  174.           267|      static USHORT line, column;   /* current cursor position */
  175.           268|      USHORT usfInfo;   /* flags for query clipboard information */
  176.           269|      static USHORT menuheight;   /* height of standard window */
  177.           270|      PCHAR buffer;   /* buffer for file I/O */
  178.           271|      LONG bufferlen;   /* number of characters read into buffer */
  179.           272|      FATTRS fattrs;   /* font attributes -- try to change to monospaced */
  180.           273|      FONTMETRICS *pfm;   /* find a monospaced system font */
  181.           274|      LONG lNumberFonts, lRequestFonts;   /* look for 10 point font */
  182.           275|      USHORT res;   /* response from dialog or message box */
  183.           276|      static USHORT resNew;   /* result of IDM_NEW (allows Cancel) */
  184.           277|      BOOL first;   /* set to TRUE if replace dialog called for first time */
  185.           278|      MLE_SEARCHDATA SearchData;   /* used is MLM_SEARCH message */
  186.           279|      LONG goline, gochar;   /* go to line specified by user */
  187.           280|      POINTS ps;   /* simulate mouse click to place cursor on specified line */
  188.           281|      int i;   /* simple loop counter */
  189.           282|               
  190.           283|      switch (msg) {
  191.           284|         case WM_CREATE:
  192.           285|            hwndClient = hwnd;
  193.           286|            hwndFrame = WinQueryWindow (hwnd, QW_PARENT, FALSE);
  194.           287|            hwndMenu = WinWindowFromID (hwndFrame, FID_MENU);
  195.           288|            menuheight = (USHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYMENU);
  196.           289|            WinSetWindowText (hwndFrame, "EDIT");
  197.           290|               
  198.           291|            hwndMLE = WinCreateWindow (
  199.           292|               hwndClient,
  200.           293|               WC_MLE, 
  201.           294|               "", 
  202.           295|               WS_VISIBLE | MLS_HSCROLL | MLS_VSCROLL | MLS_BORDER,
  203.           296|               0, 0, 0, 0,   /* will set size & position later */
  204.           297|               hwndClient,
  205.           298|               HWND_TOP,
  206.           299|               ID_MLE,
  207.           300|               NULL, NULL);
  208.           301|   
  209.           302|            /* subclass to intercept tabs (convert to spaces) */
  210.           303|            pfMLE = WinSubclassWindow (hwndMLE, TabWndProc);
  211.           304|            
  212.           305|            /* override v2.x MLE colors */
  213.           306|            WinSendMsg (hwndMLE, MLM_SETTEXTCOLOR, 
  214.           307|               MPFROMLONG (CLR_DEFAULT), 0L);
  215.           308|            WinSendMsg (hwndMLE, MLM_SETBACKCOLOR, 
  216.           309|               MPFROMLONG (CLR_BACKGROUND), 0L);
  217.           310|      
  218.           311|            /* try to switch to System Monospaced 10-point font */                     
  219.           312|            hps = WinGetPS (hwndMLE);
  220.           313|            hdc = GpiQueryDevice (hps);
  221.           314|            DevQueryCaps (hdc, CAPS_HORIZONTAL_FONT_RES, 1L, &lHRes);
  222.           315|            DevQueryCaps (hdc, CAPS_VERTICAL_FONT_RES, 1L, &lVRes);
  223.           316|            lRequestFonts = 0L;
  224.           317|            lNumberFonts = GpiQueryFonts (hps, QF_PUBLIC, "System Monospaced",
  225.           318|                              &lRequestFonts, 0L, NULL);
  226.           319|            pfm = malloc ((SHORT) lNumberFonts * sizeof (FONTMETRICS));
  227.           320|            GpiQueryFonts (hps, QF_PUBLIC, "System Monospaced",  
  228.           321|               &lNumberFonts, (LONG) sizeof (FONTMETRICS), pfm);
  229. edit.c                                                                  Page 9
  230.  
  231.           322|   
  232.           323|            for (i = 0; i < (int)lNumberFonts; i++) {
  233.           324|               if (pfm[i].sXDeviceRes == (SHORT)lHRes &&   /* does font... */
  234.           325|                   pfm[i].sYDeviceRes == (SHORT)lVRes &&   /* match device? */
  235.           326|                   pfm[i].sNominalPointSize == 100) {   /* 10 point? */
  236.           327|                  WinSendMsg (hwndMLE, MLM_QUERYFONT, 
  237.           328|                     MPFROMP (&fattrs), (MPARAM) 0L);
  238.           329|                  fattrs.lMatch = pfm[i].lMatch;
  239.           330|                  strcpy (fattrs.szFacename, "System Monospaced"); 
  240.           331|                  WinSendMsg (hwndMLE, MLM_SETFONT, 
  241.           332|                     MPFROMP (&fattrs), (MPARAM) 0L);
  242.           333|                  break;   /* exit for loop */
  243.           334|               }
  244.           335|            }
  245.           336|            free (pfm);
  246.           337|            WinReleasePS (hps);                     
  247.           338|            
  248.           339|            /* set up some MLE parameters */
  249.           340|            WinSendMsg (hwndMLE, MLM_SETTEXTLIMIT, 
  250.           341|               MPFROMLONG (65535L), (MPARAM) 0L);
  251.           342|                        
  252.           343|            WinSendMsg (hwndMLE, MLM_SETTABSTOP, 
  253.           344|               MPFROMSHORT (64), (MPARAM) 0L);
  254.           345|                        
  255.           346|            WinSendMsg (hwndMLE, MLM_FORMAT, 
  256.           347|               MPFROMSHORT (MLFIE_CFTEXT), (MPARAM) 0L);
  257.           348|   
  258.           349|            WinSendMsg (hwndMLE, MLM_RESETUNDO, (MPARAM) 0L, (MPARAM) 0L);
  259.           350|            WinSetFocus (HWND_DESKTOP, hwndMLE);
  260.           351|            return 0;
  261.           352|   
  262.           353|         case WM_MINMAXFRAME:
  263.           354|            pswp = PVOIDFROMMP (mp1);
  264.           355|            if (pswp->fs & SWP_MINIMIZE) 
  265.           356|               WinSetWindowText (hwndFrame, "EDIT");
  266.           357|            else {
  267.           358|               if (hasName) {
  268.           359|                  sprintf (str, "EDIT -- %s", szFileName);            
  269.           360|                  WinSetWindowText (hwndFrame, str);
  270.           361|               }
  271.           362|            }
  272.           363|            return 0;
  273.           364|            
  274.           365|         case WM_INITMENU:
  275.           366|            if (SHORT1FROMMP (mp1) == IDM_EDIT) {
  276.           367|               /* enable Cut, Copy, or Delete only if text selected */
  277.           368|               selmin = LONGFROMMR (WinSendMsg (hwndMLE, MLM_QUERYSEL, 
  278.           369|                                       (MPARAM) MLFQS_MINSEL, (MPARAM) 0L));
  279.           370|               selmax = LONGFROMMR (WinSendMsg (hwndMLE, MLM_QUERYSEL, 
  280.           371|                                       (MPARAM) MLFQS_MAXSEL, (MPARAM) 0L));
  281.           372|               WinSendMsg (hwndMenu, MM_SETITEMATTR,
  282.           373|                  MPFROM2SHORT (IDM_CUT, TRUE),
  283.           374|                  MPFROM2SHORT (MIA_DISABLED, 
  284.           375|                  (selmin == selmax) ? MIA_DISABLED : 0));
  285.           376|               WinSendMsg (hwndMenu, MM_SETITEMATTR,
  286. edit.c                                                                  Page 10
  287.  
  288.           377|                  MPFROM2SHORT (IDM_COPY, TRUE),
  289.           378|                  MPFROM2SHORT (MIA_DISABLED, 
  290.           379|                  (selmin == selmax) ? MIA_DISABLED : 0));
  291.           380|               WinSendMsg (hwndMenu, MM_SETITEMATTR,
  292.           381|                  MPFROM2SHORT (IDM_DELETE, TRUE),
  293.           382|                  MPFROM2SHORT (MIA_DISABLED, 
  294.           383|                  (selmin == selmax) ? MIA_DISABLED : 0));
  295.           384|                     
  296.           385|               /* enable Paste only if data available in Clipboard */
  297.           386|               WinSendMsg (hwndMenu, MM_SETITEMATTR,
  298.           387|                  MPFROM2SHORT (IDM_PASTE, TRUE),
  299.           388|                  MPFROM2SHORT (MIA_DISABLED,
  300.           389|                  WinQueryClipbrdFmtInfo (hab, CF_TEXT, &usfInfo)
  301.           390|                  ? 0 : MIA_DISABLED));
  302.           391|                        
  303.           392|               /* enable Undo only if operation may be undone */
  304.           393|               undoable = SHORT1FROMMR (WinSendMsg (hwndMLE, MLM_QUERYUNDO, 
  305.           394|                                           (MPARAM) 0L, (MPARAM) 0L));
  306.           395|               WinSendMsg (hwndMenu, MM_SETITEMATTR,
  307.           396|                  MPFROM2SHORT (IDM_UNDO, TRUE),
  308.           397|                  MPFROM2SHORT (MIA_DISABLED, (undoable || undone) 
  309.           398|                                              ? 0 : MIA_DISABLED)); 
  310.           399|            }
  311.           400|            return 0;
  312.           401|   
  313.           402|         case WM_TIMER:
  314.           403|            if (SHORT1FROMMP (mp1) == ID_UPDATE) {
  315.           404|               /* determine position (line/column) of text cursor (caret) */
  316.           405|               selmin = LONGFROMMR (WinSendMsg (hwndMLE, MLM_QUERYSEL, 
  317.           406|                                       (MPARAM) MLFQS_MINSEL, (MPARAM) 0L));
  318.           407|               newline = (int) LONGFROMMR (WinSendMsg (hwndMLE, 
  319.           408|                                              MLM_LINEFROMCHAR,
  320.           409|                                              MPFROMLONG (selmin), 
  321.           410|                                              (MPARAM) 0L));
  322.           411|               newcolumn = (int) (selmin - LONGFROMMR (WinSendMsg (hwndMLE, 
  323.           412|                                              MLM_CHARFROMLINE,
  324.           413|                                              MPFROMLONG ((long) newline), 
  325.           414|                                              (MPARAM) 0L)));
  326.           415|            
  327.           416|               /* update on screen only if line or column changed */
  328.           417|               if (newline != line || newcolumn != column) {
  329.           418|                  line = newline;   column = newcolumn;
  330.           419|                  WinInvalidateRect (hwnd, NULL, FALSE);
  331.           420|               }
  332.           421|            }
  333.           422|            return 0;
  334.           423|   
  335.           424|         case WM_CONTROL:
  336.           425|            switch (SHORT2FROMMP (mp1)) {
  337.           426|               case MLN_OVERFLOW:
  338.           427|                  if (SHORT1FROMMP (mp1) == ID_MLE) {
  339.           428|                     WinMessageBox (HWND_DESKTOP, hwnd, 
  340.           429|                        "File too large -- 64K limit exceeded.",
  341.           430|                        "Error", 0, MB_OK | MB_ICONHAND | MB_MOVEABLE);
  342.           431|                  }
  343. edit.c                                                                  Page 11
  344.  
  345.           432|                  return 0;
  346.           433|   
  347.           434|               case MLN_CHANGE:
  348.           435|                  if (SHORT1FROMMP (mp1) == ID_MLE) {
  349.           436|                     NeedToSave = TRUE;
  350.           437|                     undone = FALSE;
  351.           438|                  }
  352.           439|                  return 0;
  353.           440|               
  354.           441|               default:
  355.           442|                  break;
  356.           443|            }
  357.           444|            break;
  358.           445|       
  359.           446|         case WM_CLEANFILE:
  360.           447|            WinSendMsg (hwndMLE, MLM_RESETUNDO, (MPARAM) 0L, (MPARAM) 0L);
  361.           448|            NeedToSave = FALSE;
  362.           449|            return 0;
  363.           450|         
  364.           451|         case WM_ARGS:
  365.           452|            /* read file into buffer */            
  366.           453|            bufferlen = ReadFile (szFileName, &buffer);             
  367.           454|            if (bufferlen == CANTREAD) {             
  368.           455|               WinMessageBox (HWND_DESKTOP, hwnd, 
  369.           456|                  "Specified file does not exist.",
  370.           457|                  "New File", 0, MB_OK | MB_ICONASTERISK | MB_MOVEABLE);
  371.           458|               hasName = TRUE;
  372.           459|               sprintf (str, "EDIT -- %s", szFileName);            
  373.           460|               WinSetWindowText (hwndFrame, str);             
  374.           461|               NeedToSave = TRUE;
  375.           462|            }             
  376.           463|            else if (bufferlen == TOOLONG) {              
  377.           464|               WinMessageBox (HWND_DESKTOP, hwnd, 
  378.           465|                  "File too large -- 64K limit exceeded.",
  379.           466|                  "Error", 0, MB_OK | MB_ICONHAND | MB_MOVEABLE);
  380.           467|               WinSetWindowText (hwndFrame, "EDIT");
  381.           468|            }             
  382.           469|            else if (bufferlen == NOMEMORY) {            
  383.           470|               WinMessageBox (HWND_DESKTOP, hwnd, 
  384.           471|                  "Cannot allocate memory.",
  385.           472|                  "Error", 0, MB_OK | MB_ICONHAND | MB_MOVEABLE);
  386.           473|               WinSendMsg (hwnd, WM_QUIT, (MPARAM) 0L, (MPARAM) 0L);
  387.           474|            }             
  388.           475|            else {    /* normal */
  389.           476|               /* transfer buffer to MLE */
  390.           477|               WinSendMsg (hwndMLE, MLM_SETIMPORTEXPORT,
  391.           478|                  MPFROMP (buffer),
  392.           479|                  MPFROMSHORT ((USHORT)bufferlen));            
  393.           480|                   selmin = 0L;
  394.           481|               WinSendMsg (hwndMLE, MLM_IMPORT,
  395.           482|                  MPFROMP (&selmin), MPFROMLONG (bufferlen));            
  396.           483|                   /* free buffer */
  397.           484|               Release (buffer);    
  398.           485|               hasName = TRUE;
  399.           486|               sprintf (str, "EDIT -- %s", szFileName);            
  400. edit.c                                                                  Page 12
  401.  
  402.           487|               WinSetWindowText (hwndFrame, str);             
  403.           488|               WinPostMsg (hwnd, WM_CLEANFILE, (MPARAM) 0L, (MPARAM) 0L);
  404.           489|            }             
  405.           490|            return 0;
  406.           491|   
  407.           492|         case WM_COMMAND:
  408.           493|            switch (SHORT1FROMMP (mp1)) {
  409.           494|               case IDM_NEW:
  410.           495|                  if (NeedToSave) {
  411.           496|                      res = WinMessageBox (HWND_DESKTOP, hwnd,
  412.           497|                               "Save current file?", "New", 0,
  413.           498|                                MB_YESNOCANCEL | MB_ICONQUESTION | MB_MOVEABLE);
  414.           499|                                   
  415.           500|                     if (res == MBID_YES) {
  416.           501|                        WinSendMsg (hwnd, WM_COMMAND, 
  417.           502|                           MPFROM2SHORT (IDM_SAVE, 0), (MPARAM) 0L);
  418.           503|                     }
  419.           504|                     else if (res == MBID_CANCEL) {
  420.           505|                        resNew = MBID_CANCEL;
  421.           506|                        return 0;
  422.           507|                     }
  423.           508|                  }
  424.           509|                  SetPtrWait();
  425.           510|                     
  426.           511|                  /* empty MLE */
  427.           512|                  selmin = 0L;
  428.           513|                  selmax = LONGFROMMR (WinSendMsg (hwndMLE, MLM_QUERYTEXTLENGTH,
  429.           514|                                          (MPARAM) 0L, (MPARAM) 0L));
  430.           515|                  WinSendMsg (hwndMLE, MLM_DELETE, 
  431.           516|                     MPFROMLONG (selmin), MPFROMLONG (selmax));
  432.           517|                              
  433.           518|                  hasName = FALSE;
  434.           519|                  WinSetWindowText (hwndFrame, "EDIT");
  435.           520|                  WinPostMsg (hwnd, WM_CLEANFILE, (MPARAM) 0L, (MPARAM) 0L);
  436.           521|                  
  437.           522|                  SetPtrArrow();
  438.           523|                  resNew = MBID_OK;
  439.           524|                  return 0;
  440.           525|                  
  441.           526|               case IDM_OPEN:
  442.           527|                  WinSendMsg (hwnd, WM_COMMAND, 
  443.           528|                     MPFROMSHORT (IDM_NEW), (MPARAM) 0L);
  444.           529|                  if (resNew == MBID_CANCEL)
  445.           530|                     return 0;
  446.           531|                     
  447.           532|                  if (WinDlgBox (HWND_DESKTOP, hwnd, OpenDlgProc,
  448.           533|                         0, IDD_OPEN, NULL)) {
  449.           534|                                 
  450.           535|                     SetPtrWait();
  451.           536|                        
  452.           537|                     /* user selected a (valid) file to open */
  453.           538|                     /* read file into buffer */
  454.           539|                     bufferlen = ReadFile (szFileName, &buffer);
  455.           540|                     
  456.           541|                     SetPtrArrow();
  457. edit.c                                                                  Page 13
  458.  
  459.           542|                        
  460.           543|                     if (bufferlen == CANTREAD) {
  461.           544|                        WinMessageBox (HWND_DESKTOP, hwnd, 
  462.           545|                           "Specified file does not exist.",
  463.           546|                           "New File", 0, MB_OK | MB_ICONASTERISK | MB_MOVEABLE);
  464.           547|                        hasName = TRUE;
  465.           548|                        sprintf (str, "EDIT -- %s", szFileName);            
  466.           549|                        WinSetWindowText (hwndFrame, str);             
  467.           550|                        NeedToSave = TRUE;
  468.           551|                     }
  469.           552|                     else if (bufferlen == TOOLONG) {
  470.           553|                        WinMessageBox (HWND_DESKTOP, hwnd, 
  471.           554|                           "File too large -- 64K limit exceeded.",
  472.           555|                           "Error", 0, MB_OK | MB_ICONHAND | MB_MOVEABLE);
  473.           556|                        WinSetWindowText (hwndFrame, "EDIT");
  474.           557|                        NeedToSave = FALSE;
  475.           558|                     }
  476.           559|                     else if (bufferlen == NOMEMORY) {
  477.           560|                        WinMessageBox (HWND_DESKTOP, hwnd, 
  478.           561|                           "Cannot allocate memory.",
  479.           562|                           "Error", 0, MB_OK | MB_ICONHAND | MB_MOVEABLE);
  480.           563|                        WinSendMsg (hwnd, WM_QUIT, (MPARAM) 0L, (MPARAM) 0L);
  481.           564|                     }
  482.           565|                     else {   /* normal */
  483.           566|                        SetPtrWait();
  484.           567|                           
  485.           568|                        /* transfer buffer to MLE */
  486.           569|                        WinSendMsg (hwndMLE, MLM_SETIMPORTEXPORT, 
  487.           570|                           MPFROMP (buffer), MPFROMSHORT ((USHORT)bufferlen));
  488.           571|                        selmin = 0L;            
  489.           572|                        WinSendMsg (hwndMLE, MLM_IMPORT, 
  490.           573|                           MPFROMP (&selmin), MPFROMLONG (bufferlen));
  491.           574|                        /* free buffer */
  492.           575|                        Release (buffer);
  493.           576|                        hasName = TRUE;
  494.           577|                        sprintf (str, "EDIT -- %s", szFileName);
  495.           578|                        WinSetWindowText (hwndFrame, str);
  496.           579|                        WinPostMsg (hwnd, WM_CLEANFILE, (MPARAM) 0L, (MPARAM) 0L);
  497.           580|                        
  498.           581|                        SetPtrArrow();
  499.           582|                     }
  500.           583|                  } 
  501.           584|                  return 0;
  502.           585|          
  503.           586|               case IDM_SAVE:
  504.           587|                  if (hasName) {
  505.           588|                     /* determine amount of text in MLE */
  506.           589|                     bufferlen = LONGFROMMR (WinSendMsg (hwndMLE, 
  507.           590|                                                MLM_QUERYFORMATTEXTLENGTH, 
  508.           591|                                                (MPARAM) 0L, MPFROMLONG (-1L)));
  509.           592|                                       
  510.           593|                     /* allocate space for buffer */
  511.           594|                     if (NOMEMORY == MakeWriteBuffer (bufferlen, &buffer)) {
  512.           595|                        WinMessageBox (HWND_DESKTOP, hwnd, 
  513.           596|                           "Cannot allocate memory.",
  514. edit.c                                                                  Page 14
  515.  
  516.           597|                           "Error", 0, MB_OK | MB_ICONHAND | MB_MOVEABLE);
  517.           598|                        WinSendMsg (hwnd, WM_QUIT, (MPARAM) 0L, (MPARAM) 0L);
  518.           599|                     }
  519.           600|                     SetPtrWait();
  520.           601|                        
  521.           602|                     /* transfer text from MLE to buffer */
  522.           603|                     WinSendMsg (hwndMLE, MLM_SETIMPORTEXPORT, 
  523.           604|                        MPFROMP (buffer), 
  524.           605|                        MPFROMSHORT ((USHORT)bufferlen));
  525.           606|                     selmin = 0L;   selmax = bufferlen;
  526.           607|                     WinSendMsg (hwndMLE, MLM_EXPORT, 
  527.           608|                        MPFROMP (&selmin), MPFROMP (&selmax));
  528.           609|   
  529.           610|                     /* write to file */
  530.           611|                     if (CANTWRITE == WriteFile (szFileName, bufferlen, buffer)) {
  531.           612|                        WinMessageBox (HWND_DESKTOP, hwnd, 
  532.           613|                           "Unable to write to file.",
  533.           614|                           "Error", 0, MB_OK | MB_ICONHAND | MB_MOVEABLE);
  534.           615|                     }
  535.           616|                                 
  536.           617|                     /* deallocate buffer */
  537.           618|                     Release (buffer);
  538.           619|                     WinPostMsg (hwnd, WM_CLEANFILE, (MPARAM) 0L, (MPARAM) 0L);
  539.           620|                     
  540.           621|                     SetPtrArrow();
  541.           622|                  }
  542.           623|                  else {
  543.           624|                     WinSendMsg (hwnd, WM_COMMAND, 
  544.           625|                        MPFROM2SHORT (IDM_SAVEAS, 0), (MPARAM) 0L);
  545.           626|                  } 
  546.           627|                  return 0;
  547.           628|                  
  548.           629|               case IDM_SAVEAS:
  549.           630|                  if (WinDlgBox (HWND_DESKTOP, hwnd, SaveasDlgProc,
  550.           631|                         0, IDD_SAVEAS, NULL)) {
  551.           632|                     hasName = TRUE;
  552.           633|                     sprintf (str, "EDIT -- %s", szFileName);
  553.           634|                     WinSetWindowText (hwndFrame, str);
  554.           635|                     WinSendMsg (hwnd, WM_COMMAND, 
  555.           636|                        MPFROM2SHORT (IDM_SAVE, 0), (MPARAM) 0L);
  556.           637|                  }
  557.           638|                  return 0;
  558.           639|               
  559.           640|               case IDM_EXIT:
  560.           641|                  WinSendMsg (hwnd, WM_CLOSE, (MPARAM) 0L, (MPARAM) 0L);
  561.           642|                  return 0;
  562.           643|                  
  563.           644|               case IDM_UNDO:
  564.           645|                  WinSendMsg (hwndMLE, MLM_UNDO, (MPARAM) 0L, (MPARAM) 0L);
  565.           646|                  undone = TRUE;
  566.           647|                  return 0;
  567.           648|                  
  568.           649|               case IDM_CUT:
  569.           650|                  WinSendMsg (hwndMLE, MLM_CUT, (MPARAM) 0L, (MPARAM) 0L);
  570.           651|                  return 0;
  571. edit.c                                                                  Page 15
  572.  
  573.           652|               
  574.           653|               case IDM_COPY:
  575.           654|                  WinSendMsg (hwndMLE, MLM_COPY, (MPARAM) 0L, (MPARAM) 0L);
  576.           655|                  return 0;
  577.           656|                  
  578.           657|               case IDM_PASTE:
  579.           658|                  WinSendMsg (hwndMLE, MLM_PASTE, (MPARAM) 0L, (MPARAM) 0L);
  580.           659|                  return 0;
  581.           660|                  
  582.           661|               case IDM_DELETE:
  583.           662|                  WinSendMsg (hwndMLE, MLM_CLEAR, (MPARAM) 0L, (MPARAM) 0L);
  584.           663|                  return 0;  
  585.           664|               
  586.           665|               case IDM_FIND:
  587.           666|                  if (DID_OK == WinDlgBox (HWND_DESKTOP, hwnd, FindDlgProc,
  588.           667|                                   0, IDD_FIND, NULL)) {
  589.           668|                     SetPtrWait();
  590.           669|         
  591.           670|                     SearchData.cb = sizeof (MLE_SEARCHDATA);
  592.           671|                     SearchData.pchFind = szFind;
  593.           672|                     SearchData.cchFind = strlen (szFind);
  594.           673|                     SearchData.iptStart = (-1L);
  595.           674|                     SearchData.iptStop = (-1L);
  596.           675|         
  597.           676|                     res = SHORT1FROMMR (WinSendMsg (hwndMLE, MLM_SEARCH, 
  598.           677|                                             MPFROMLONG (MLFSEARCH_SELECTMATCH),
  599.           678|                                             MPFROMP (&SearchData)));
  600.           679|         
  601.           680|                     SetPtrArrow();
  602.           681|         
  603.           682|                     if (!res) {
  604.           683|                        WinMessageBox (HWND_DESKTOP, hwnd, 
  605.           684|                           "Search string not found.", "Find", 0, 
  606.           685|                           MB_OK | MB_ICONASTERISK | MB_MOVEABLE);
  607.           686|                     }
  608.           687|                  }
  609.           688|                  return 0;
  610.           689|                  
  611.           690|               case IDM_REPLACE:
  612.           691|                  first = TRUE;
  613.           692|                  res = WinDlgBox (HWND_DESKTOP, hwnd, ReplaceDlgProc,
  614.           693|                           0, IDD_REPLACE, (PVOID)(&first));
  615.           694|                  first = FALSE;
  616.           695|                  for (;;) {
  617.           696|                     if (res == DID_CANCEL)
  618.           697|                        break;
  619.           698|                     else if (res == DID_OK) {                                   
  620.           699|                        SetPtrWait();
  621.           700|                           
  622.           701|                        SearchData.cb = sizeof (MLE_SEARCHDATA);
  623.           702|                        SearchData.pchFind = szFind;
  624.           703|                        SearchData.cchFind = strlen (szFind);
  625.           704|                        SearchData.iptStart = (-1L);
  626.           705|                        SearchData.iptStop = (-1L);
  627.           706|                        
  628. edit.c                                                                  Page 16
  629.  
  630.           707|                        res = SHORT1FROMMR (WinSendMsg (hwndMLE, MLM_SEARCH, 
  631.           708|                                               MPFROMLONG (MLFSEARCH_SELECTMATCH),
  632.           709|                                               MPFROMP (&SearchData)));
  633.           710|                                          
  634.           711|                        SetPtrArrow();
  635.           712|                           
  636.           713|                        if (!res) {                  
  637.           714|                           WinMessageBox (HWND_DESKTOP, hwnd, 
  638.           715|                              "Search string not found.", "Replace", 0,
  639.           716|                               MB_OK | MB_ICONASTERISK | MB_MOVEABLE);
  640.           717|                           break;   /* exit search/replace */
  641.           718|                        }
  642.           719|                     }
  643.           720|                     else if (res == DID_DOREPLACE)
  644.           721|                        WinSendMsg (hwndMLE, MLM_INSERT, 
  645.           722|                           MPFROMP (szReplace), (MPARAM) 0L);
  646.           723|                     else if (res == DID_REPLACEALL) {
  647.           724|                        SetPtrWait();
  648.           725|                           
  649.           726|                        WinSendMsg (hwndMLE, MLM_INSERT, 
  650.           727|                           MPFROMP (szReplace), (MPARAM) 0L);
  651.           728|                                    
  652.           729|                        SearchData.cb = sizeof (MLE_SEARCHDATA);
  653.           730|                        SearchData.pchFind = szFind;
  654.           731|                        SearchData.cchFind = strlen (szFind);
  655.           732|                        SearchData.pchReplace = szReplace;
  656.           733|                        SearchData.cchReplace = strlen (szReplace);
  657.           734|                        SearchData.iptStart = (-1L);
  658.           735|                        SearchData.iptStop = (-1L);
  659.           736|                        WinSendMsg (hwndMLE, MLM_SEARCH, 
  660.           737|                           MPFROMLONG (MLFSEARCH_CHANGEALL), 
  661.           738|                           MPFROMP (&SearchData));
  662.           739|                                    
  663.           740|                        SetPtrArrow();
  664.           741|                           
  665.           742|                        WinMessageBox (HWND_DESKTOP, hwnd, 
  666.           743|                           "All occurrences replaced.", "Replace", 0,
  667.           744|                           MB_OK | MB_ICONASTERISK | MB_MOVEABLE);
  668.           745|                        break;   /* exit search/replace */
  669.           746|                     }
  670.           747|                     else
  671.           748|                        break;   /* exit search/replace */
  672.           749|                        
  673.           750|                     res = WinDlgBox (HWND_DESKTOP, hwnd, ReplaceDlgProc,
  674.           751|                              0, IDD_REPLACE, (PVOID)(&first));
  675.           752|                  }
  676.           753|                  return 0;
  677.           754|   
  678.           755|               case IDM_GO:
  679.           756|                     res = WinDlgBox (HWND_DESKTOP, hwnd, GoLnDlgProc,
  680.           757|                              0, IDD_GOLINE, NULL);
  681.           758|                     if (res == MBID_OK) {
  682.           759|                        if (sscanf (szLine, "%ld", &goline)) {
  683.           760|                           if (goline < 1)
  684.           761|                              goline = 1;
  685. edit.c                                                                  Page 17
  686.  
  687.           762|                           gochar = LONGFROMMR (WinSendMsg (hwndMLE, 
  688.           763|                                                    MLM_CHARFROMLINE, 
  689.           764|                                                    MPFROMLONG (--goline), 
  690.           765|                                                    (MPARAM) 0L));
  691.           766|                           WinSendMsg (hwndMLE, MLM_SETFIRSTCHAR, 
  692.           767|                              MPFROMLONG (gochar), (MPARAM) 0L);
  693.           768|                           ps.x = 0;   ps.y = cyClient - (2 * menuheight);
  694.           769|                           WinSendMsg (hwndMLE, WM_BUTTON1DOWN, 
  695.           770|                              MPFROM2SHORT (ps.x, ps.y), (MPARAM) 0L);
  696.           771|                           WinSendMsg (hwndMLE, WM_BUTTON1UP, 
  697.           772|                              MPFROM2SHORT (ps.x, ps.y), (MPARAM) 0L);
  698.           773|                        }
  699.           774|                     }
  700.           775|                  return 0;
  701.           776|   
  702.           777|               case IDM_HELPFORHELP:
  703.           778|                  if (hwndHelpInstance)
  704.           779|                     WinSendMsg( hwndHelpInstance, HM_DISPLAY_HELP, 0L, 0L);
  705.           780|                  break;
  706.           781|   
  707.           782|               case IDM_EXTENDEDHELP:
  708.           783|                  WinPostMsg (hwndFrame, WM_SYSCOMMAND,
  709.           784|                     MPFROM2SHORT (SC_HELPEXTENDED, 0), (MPARAM) 0L);
  710.           785|                  break;
  711.           786|                  
  712.           787|               case IDM_KEYSHELP:
  713.           788|                  WinPostMsg (hwndFrame, WM_SYSCOMMAND,
  714.           789|                     MPFROM2SHORT (SC_HELPKEYS, 0), (MPARAM) 0L);
  715.           790|                  break;
  716.           791|                  
  717.           792|               case IDM_HELPINDEX:
  718.           793|                  WinPostMsg (hwndFrame, WM_SYSCOMMAND,
  719.           794|                     MPFROM2SHORT (SC_HELPINDEX, 0), (MPARAM) 0L);
  720.           795|                  break;
  721.           796|                  
  722.           797|               case IDM_ABOUT:
  723.           798|                  WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc, 
  724.           799|                     0, IDD_ABOUT, NULL);
  725.           800|                  return 0;
  726.           801|                  
  727.           802|               default:
  728.           803|                  break;
  729.           804|            }
  730.           805|            break;
  731.           806|   
  732.           807|         case WM_SIZE:
  733.           808|            cxClient = SHORT1FROMMP (mp2);
  734.           809|            cyClient = SHORT2FROMMP (mp2);
  735.           810|            
  736.           811|            WinSetWindowPos (
  737.           812|               hwndMLE, 
  738.           813|               HWND_TOP, 
  739.           814|               0, 0, 
  740.           815|               cxClient, cyClient - menuheight, 
  741.           816|               SWP_MOVE | SWP_SIZE);
  742. edit.c                                                                  Page 18
  743.  
  744.           817|            WinSetFocus (HWND_DESKTOP, hwndMLE);
  745.           818|            return 0;
  746.           819|   
  747.           820|         case WM_PAINT:
  748.           821|            hps = WinBeginPaint (hwnd, NULL, NULL);
  749.           822|            sprintf (str, "  Line: %-5d   Col: %-5d", line + 1, column + 1);
  750.           823|            WinQueryWindowRect (hwnd, &rcl);
  751.           824|            rcl.yBottom = cyClient - menuheight;
  752.           825|            WinDrawText (hps, -1, str, &rcl, CLR_NEUTRAL, CLR_BACKGROUND,
  753.           826|               DT_LEFT | DT_VCENTER | DT_ERASERECT);
  754.           827|            WinEndPaint (hps);
  755.           828|            return 0;
  756.           829|      
  757.           830|         case HM_QUERY_KEYS_HELP:
  758.           831|            return ((MRESULT) IDH_KEYSHELP);
  759.           832|            break;
  760.           833|   
  761.           834|         case HM_ERROR:
  762.           835|            if ( (hwndHelpInstance && (ULONG) mp1) == HMERR_NO_MEMORY) {
  763.           836|               WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  764.           837|                  "Help Terminated Due to Error", "Help Error", 0,
  765.           838|                  MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE);
  766.           839|               WinDestroyHelpInstance(hwndHelpInstance);
  767.           840|            }
  768.           841|            else {
  769.           842|               WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  770.           843|                  "Help Error Occurred", "Help Error", 0,
  771.           844|                  MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE);
  772.           845|            }
  773.           846|            break;
  774.           847|            
  775.           848|         case WM_DESTROY:
  776.           849|            WinDestroyWindow (hwndMLE);
  777.           850|            return 0;
  778.           851|      }
  779.           852|      return WinDefWindowProc (hwnd, msg, mp1, mp2);
  780.           853|   }
  781.           854|   
  782.           855|   
  783.           856|   MRESULT EXPENTRY TabWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  784.           857|   {
  785.           858|      USHORT flags, vk;   /* WM_CHAR message parameters */
  786.           859|      long curpos;   /* current postion -- relative to top of document */
  787.           860|      int ln, col;   /* current position -- line/column */
  788.           861|      char str[TAB + 1];   /* insert string of spaces for tab */
  789.           862|      int i;   /* loop counter: will insert spaces for tab */
  790.           863|      int ts;   /* number of spaces to insert for tab */
  791.           864|   
  792.           865|      switch (msg) {
  793.           866|         case WM_CHAR:
  794.           867|            flags = SHORT1FROMMP (mp1);
  795.           868|            vk = SHORT2FROMMP (mp2);
  796.           869|            if (flags & KC_VIRTUALKEY && !(flags & KC_KEYUP) && vk == VK_TAB) {
  797.           870|               /* determine position of text cursor */
  798.           871|               curpos = LONGFROMMR (WinSendMsg (hwnd, MLM_QUERYSEL, 
  799. edit.c                                                                  Page 19
  800.  
  801.           872|                                       (MPARAM) MLFQS_MINSEL, (MPARAM) 0L));
  802.           873|               ln = (int) LONGFROMMR (WinSendMsg (hwnd, MLM_LINEFROMCHAR,
  803.           874|                                         MPFROMLONG (curpos), (MPARAM) 0L));
  804.           875|               col = (int) (curpos - LONGFROMMR (WinSendMsg (hwnd, 
  805.           876|                                                    MLM_CHARFROMLINE,
  806.           877|                                                    MPFROMLONG ((long) ln), 
  807.           878|                                                    (MPARAM) 0L)));
  808.           879|               ts = TAB - (col % TAB); 
  809.           880|               for (i = 0; i < ts; i++) 
  810.           881|                  str[i] = ' ';
  811.           882|               str[i] = '\0';
  812.           883|               
  813.           884|               WinSendMsg (hwnd, MLM_INSERT, MPFROMP (str), (MPARAM) 0L);
  814.           885|               return 0;
  815.           886|            }
  816.           887|            else
  817.           888|               break;
  818.           889|   
  819.           890|         default:
  820.           891|            break;
  821.           892|      }
  822.           893|      pfMLE (hwnd, msg, mp1, mp2);
  823.           894|   }
  824.           895|   
  825.           896|   
  826.           897|   VOID SetPtrArrow (VOID)
  827.           898|   {
  828.           899|      if (!WinQuerySysValue (HWND_DESKTOP, SV_MOUSEPRESENT))
  829.           900|         WinShowPointer (HWND_DESKTOP, FALSE);
  830.           901|   
  831.           902|      WinSetPointer (HWND_DESKTOP,
  832.           903|         WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, 0));
  833.           904|   }
  834.           905|   
  835.           906|   
  836.           907|   VOID SetPtrWait (VOID)
  837.           908|   {
  838.           909|      WinSetPointer (HWND_DESKTOP,
  839.           910|         WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, 0));
  840.           911|   
  841.           912|      if (!WinQuerySysValue (HWND_DESKTOP, SV_MOUSEPRESENT))
  842.           913|         WinShowPointer (HWND_DESKTOP, TRUE);
  843.           914|   }
  844.           915|   
  845.