home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / ed32eng1.zip / source / edit.c < prev    next >
C/C++ Source or Header  |  1994-09-26  |  43KB  |  1,030 lines

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