home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk12 / ted / ted.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-06  |  55.1 KB  |  1,866 lines

  1. /****************************************************************************
  2.    
  3.     TED.C - Tiny Editor: Sample application
  4.  
  5.     Created by Microsoft Corporation, IBM Corporation 1989
  6.  
  7. -----------------------------------------------------------------------------
  8.  
  9.     This module contains the main processing elements of the TED sample
  10.     application.  This application is a very simple editor which utilizies
  11.     an MLE to do all the text interaction with the user.  Full help support
  12.     is built in using Help Manager. The application is organized into the
  13.     following 15 files.
  14.  
  15.  
  16.         Ted.c     - Contains the main processing loop and all the MLE handler
  17.                     functions.
  18.  
  19.         Ted.h     - Contains the #define and function prototypes.
  20.  
  21.         Ted.rc    - Contains the Menu entries, the accelerator table and
  22.                     the string resources.
  23.  
  24.         Ted.ico   - The icon that appears when Ted is minimized and also
  25.                     in the about box.
  26.  
  27.         Ted.def   - Module definition file for Ted.
  28.  
  29.  
  30.         Tedmem.c  - Contains the memory allocation functions.
  31.  
  32.         Tedmem.h  - Contains the #define and the function prototypes for
  33.                     the memory allocation functions.
  34.  
  35.  
  36.         Tedhelp.c - Contains the help manager support functions.
  37.  
  38.         Tedhelp.h - Contains all the ID's for the Help Manager help panels
  39.  
  40.         Tedhelp.rc- Contains the Help Manager tables and sub-tables
  41.                     that associate each selectable item with a particular
  42.                     help panel in the Tedhp.itl file.
  43.  
  44.  
  45.         Tedhp.itl - Contains the Help Manager help panels.
  46.  
  47.         Tedhp.h   - Contains the #defines for the help panel id's
  48.  
  49.         Teddlg.dlg- Contains the Dialog templates for the Find and
  50.                     about dialog boxes.
  51.  
  52.         Teddlg.h  - Contains the #define ID's for the Find and about dialog
  53.                     boxes
  54.  
  55.  
  56.         MAKEFILE  - The makefile (nmake.exe) for the TED application.
  57.  
  58.  
  59.  
  60.  
  61.     DLL's used:
  62.  
  63.  
  64.         opendlg.dll - This dll is provided in the toolkit and it contains
  65.                       the open/save as dialog used for choosing files.
  66.                       The directory it resides in must be specified in
  67.                       the LIBPATH.
  68.  
  69.     Import libraries used:
  70.  
  71.  
  72.         opendlg.lib - This contains the functions used to interface
  73.                       to the open/save dialog DLL.
  74.  
  75.         opendlg.h   - This contains the functions prototypes etc
  76.                       used to interface to the open/save dialog DLL.
  77.  
  78.  
  79.     Help Libraries used:
  80.  
  81.  
  82.         tedhp.hlp   - This is the Help Manager help panel storage file
  83.                       It must be either in the directory specified by
  84.                       the HELP environment variable, in \OS2\HELP, or
  85.                       in the current directory.
  86.  
  87.  
  88.  
  89.         Modification History
  90.  
  91.             891005    James Bratsanos, Updated comment so help file (.hlp)
  92.                                        can now be in current directory.
  93.  
  94.             890911    James Bratsanos, Created
  95.  
  96.  
  97.  
  98. ****************************************************************************/
  99.  
  100.  
  101. /****************************************************************************
  102.  
  103.     Include Files, Macros, Defined Constants
  104.  
  105. ****************************************************************************/
  106.  
  107. #define INCL_WIN
  108. #define INCL_DOS
  109.  
  110. #include <os2.h>
  111.  
  112. #include <stdio.h>
  113. #include <opendlg.h>    /* Header file for toolkit open/save dialogs */
  114. #include <string.h>
  115.  
  116. #include "ted.h"
  117. #include "tedhelp.h"
  118. #include "teddlg.h"
  119. #include "tedmem.h"
  120.  
  121.  
  122.  
  123. /****************************************************************************
  124.  
  125.     Variables Used Globally in this module
  126.  
  127. ****************************************************************************/
  128.  
  129. HWND  hwndFrame   = NULL;   /* The window handle of the frame */
  130. HWND  hwndMenu    = NULL;   /* The window handle of our menu  */
  131. HWND  hwndMLE     = NULL;   /* The window handle of the MLE (Client of Frame*/
  132. HWND  hwndDlgFind = NULL;   /* The window handle of the FIND dialog box */
  133. HAB   hab         = NULL;   /* The anchor block handle for TED */
  134. PFNWP pfnwpold    = NULL;   /* A pointer to the old window procedure of */
  135.                             /* the Client (the MLE window proc )        */
  136.  
  137. HMQ   hmq ;                 /* Message queue handle */
  138.  
  139. PFNWP pfnwpoldframe = NULL; /* A pointer to the old window procedure of */
  140.                             /* the Frame */
  141.  
  142.  
  143. struct _TEDINFO {           /* Used to keep track of the file name and  */
  144.                             /* path currently being edited              */
  145.  
  146.     UCHAR uchFileName[ CCHMAXPATH ];         /* Just the file name */
  147.     UCHAR uchFullPathName[ CCHMAXPATH];      /* The full path      */
  148.     UCHAR uchPgmName[  CCHMAXPATH ];         /* Program name from title bar */
  149.  
  150. };
  151.  
  152. struct _TEDINFO tedinfo;
  153.  
  154.  
  155.  
  156. /****************************************************************************
  157.  
  158.     main - This is the main procedure of the ted application.  It does
  159.            any initialization that is required goes into the standard
  160.            get / dispatch message loop and, finally does any cleanup
  161.            that is required.
  162.  
  163. ****************************************************************************/
  164.  
  165. VOID main (VOID)
  166. {
  167.  
  168.  
  169.     static ULONG flFrameFlags = FCF_STANDARD;
  170.     QMSG         qmsg ;     /* Information used to dispatch msg's */
  171.  
  172.  
  173.     /********************************************************************
  174.         Create the anchor block (HAB) and the message queue for our
  175.         application.
  176.     ********************************************************************/
  177.  
  178.  
  179.  
  180.     hab = WinInitialize (0) ;
  181.     hmq = WinCreateMsgQueue (hab, 0) ;
  182.  
  183.  
  184.  
  185.     /********************************************************************
  186.         Create the frame window and specify that the client is an MLE
  187.         So this way the MLE will handle all the WM_SIZE, WM_PAINT msg
  188.         and we dont have to.
  189.     ********************************************************************/
  190.  
  191.  
  192.     hwndFrame = WinCreateStdWindow (HWND_DESKTOP,
  193.                          WS_VISIBLE | MLS_WORDWRAP |
  194.                                                  FS_ACCELTABLE,
  195.                         &flFrameFlags,
  196.                     WC_MLE ,
  197.                     NULL,
  198.                         WS_VISIBLE | MLS_HSCROLL | MLS_VSCROLL |
  199.                                    MLS_WORDWRAP ,
  200.                     (HMODULE) NULL,
  201.                     ID_RESOURCE,
  202.                     &hwndMLE ) ;
  203.  
  204.  
  205.     if ( hwndFrame == NULL || hwndMLE == NULL )
  206.     {
  207.         TEDDisplayErrorID( SID_UNABLE_TO_CREATE_FRAME  );
  208.  
  209.         TEDCleanupExit();      /* Cleanup and exit , NOTE: never returns!! */
  210.     }
  211.  
  212.  
  213.  
  214.     /*  Sub class the frame so we get the WM_CONTROL MSG's from the MLE */
  215.  
  216.  
  217.  
  218.     if ( ( pfnwpoldframe = WinSubclassWindow( hwndFrame, FrameWndProc ))
  219.                                   == (PFNWP) 0 )
  220.     {
  221.         TEDDisplayErrorID( SID_UNABLE_TO_SUB_FRAME );
  222.  
  223.         TEDCleanupExit();      /* Cleanup and exit , NOTE: never returns!! */
  224.     }
  225.  
  226.     /********************************************************************
  227.         Subclass the client window in order to receive the MSG's from
  228.         our menu.
  229.     ********************************************************************/
  230.  
  231.  
  232.     if ( (pfnwpold = WinSubclassWindow( hwndMLE , ClientWndProc ))
  233.                                        ==   (PFNWP) 0 )
  234.     {
  235.         TEDDisplayErrorID( SID_UNABLE_TO_SUB_CLIENT );
  236.  
  237.         TEDCleanupExit();      /* Cleanup and exit , NOTE: never returns!! */
  238.     }
  239.  
  240.  
  241.     /********************************************************************
  242.         Since the MLE sends messages to its owner and WinCreateStdWindow
  243.         does not assign an owner to its client then set the owner of the
  244.         MLE to be the frame (Since we subclassed the frame window
  245.         earlier we now receive the WM_CONTROL (notification messages)
  246.         from the MLE
  247.     ********************************************************************/
  248.  
  249.  
  250.     if ( !WinSetOwner( hwndMLE, hwndFrame ))
  251.     {
  252.         TEDDisplayErrorID( SID_UNABLE_TO_SET_FRAME_OWNER );
  253.  
  254.         TEDCleanupExit();      /* Cleanup and exit , NOTE: never returns!! */
  255.     }
  256.  
  257.  
  258.  
  259.     MLEInit ( hwndMLE );
  260.  
  261.  
  262.  
  263.     /*  Save off the id of our menu so we can send it msg's as required. */
  264.  
  265.  
  266.     hwndMenu = WinWindowFromID(hwndFrame, FID_MENU) ;
  267.  
  268.  
  269.  
  270.     /*  Set the initial state of the Word Wrap menu item on our menu */
  271.  
  272.  
  273.     MLESetWrap( hwndMLE, hwndMenu, FALSE );
  274.  
  275.     /*****************************************************************
  276.         Init the Help Manager. No need to check for success since TED
  277.         will function fine without help.
  278.     *****************************************************************/
  279.  
  280.  
  281.     TEDInitHelp( hwndFrame, hab );
  282.  
  283.  
  284.  
  285.     /* Get the name of the program so we can use it later in the title */
  286.  
  287.     WinQueryWindowText( hwndFrame ,
  288.                         sizeof(tedinfo.uchPgmName ),
  289.                         tedinfo.uchPgmName);
  290.  
  291.  
  292.  
  293.     /********************************************************************
  294.         Setup the path name portion of our program to be NULL and the
  295.         title to be Untitled
  296.     ********************************************************************/
  297.  
  298.  
  299.     TEDInitFileName();
  300.  
  301.  
  302.     TEDUpdateTitleBar( hwndFrame, tedinfo.uchPgmName, tedinfo.uchFileName );
  303.  
  304.  
  305.  
  306.     /********************************************************************
  307.         Stay in the standard Presentation manager processing loop
  308.         until a WM_QUIT is received. This causes WinGetMsg() to
  309.         return FALSE and thus the loop is exited.
  310.     ********************************************************************/
  311.  
  312.  
  313.     while(WinGetMsg (hab, &qmsg, NULL, 0, 0))
  314.     {
  315.         WinDispatchMsg (hab, &qmsg) ;
  316.     }
  317.  
  318.  
  319.  
  320.     /********************************************************************
  321.         Do any cleanup the help manager requires. We do not need
  322.         to cleanup the ABOUT dialog since it is modal and is destroyed
  323.         every time the user removes it.
  324.     ********************************************************************/
  325.  
  326.  
  327.     TEDTerminateHelp( hwndFrame );
  328.  
  329.  
  330.  
  331.     TEDCleanupExit();     /* Cleanup and exit , NOTE: never returns!! */
  332.  
  333.  
  334. }
  335.  
  336.  
  337.  
  338. /**********************************************************************
  339.  
  340.     TEDInitFileName - This function initalizes the full path of the
  341.                       current file to be NULL and the current file
  342.                       name to be "Untitled". This way the save dialog
  343.                       need only check if the full path is null and
  344.                       thus it will know that no file has been set.
  345.                       As soon as we do a OPEN or SAVE AS then the full
  346.                       path will be set to something other than NULL
  347.                       and thus the file will no longer be considered
  348.                       Untitled.
  349.  
  350.  
  351. **********************************************************************/
  352.  
  353.  
  354. VOID TEDInitFileName()
  355. {
  356.  
  357.  
  358.     /* Load the string that will signifiy an Untitled file name */
  359.  
  360.  
  361.     if ( WinLoadString( hab,
  362.                         (HMODULE) NULL,
  363.                         SID_TED_UNTITLED,
  364.                         sizeof( tedinfo.uchFileName),
  365.                         tedinfo.uchFileName )  == (SHORT) 0 )
  366.     {
  367.         MESSAGE("Cannot load untitled string ");
  368.     }
  369.  
  370.     tedinfo.uchFullPathName[0] = '\000';   /* Make the path empty */
  371.  
  372. }
  373.  
  374.  
  375.  
  376.  
  377. /**********************************************************************
  378.  
  379.     FrameWndProc - This window procedure is used to catch
  380.                    notification messages (WM_CONTROL) from the MLE
  381.                    and also Help Manager errors.  This procedure
  382.                    actually is subclassed on the frame and all
  383.                    non processed messages are passed through to the
  384.                    default frame proc.
  385.  
  386. **********************************************************************/
  387.  
  388. MRESULT EXPENTRY FrameWndProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  389. {
  390.  
  391.     MRESULT mresult;    /* Used to return Help Panel ID to Help Manager */
  392.  
  393.  
  394.     switch( msg )
  395.     {
  396.         case WM_CONTROL:                          /* Control Message      */
  397.  
  398.         switch( LOUSHORT( mp1 ) )             /* ID of control        */
  399.         {
  400.         case FID_CLIENT :                 /* Verify its from MLE  */
  401.  
  402.  
  403.             switch( HIUSHORT( mp1 ) )     /* Notification Message */
  404.             {
  405.  
  406.                     /******************************************************
  407.                         The MLE will send a MLN_CHANGE message when
  408.                         something in the MLE is modified. This could
  409.                         be used to do smart closing where TED would
  410.                         notify the user if an exit attempt was made
  411.                         when the MLE text had unsaved changes.
  412.                     ******************************************************/
  413.  
  414.             case MLN_CHANGE:
  415.  
  416.                         /* Just do the old frame procedure processing */
  417.  
  418.                 break;
  419.  
  420.                     /******************************************************
  421.                         The MLE will send a MLN_TEXTOVERFLOW message when
  422.                         a key stroke would cause the text in the MLE to
  423.                         exceed the TEXT_LIMIT set
  424.                     ******************************************************/
  425.  
  426.             case MLN_TEXTOVERFLOW:
  427.  
  428.                 TEDDisplayErrorID( SID_MLEMSG_TEXTOVERFLOW );
  429.  
  430.                             return FALSE; /* Tell MLE to not allow overflow */
  431.  
  432.                 break;
  433.  
  434.  
  435.                     /******************************************************
  436.                         The MLE will send a MLN_OVERFLOW message when
  437.                         an action other that a key stroke would cause
  438.                         the text in the MLE to exceed the allowable
  439.                         amount, or the format rectangle would have
  440.                         been inadequate to contain the text.
  441.  
  442.                         NOTE: mp2 is a pointer to a OVERFLOW structure
  443.                               containing detailed information as to
  444.                               what caused the overflow.
  445.                     ******************************************************/
  446.  
  447.  
  448.             case MLN_OVERFLOW:
  449.  
  450.                             TEDDisplayErrorID( SID_MLEMSG_MLN_OVERFLOW );
  451.  
  452.                 return FALSE; /* Tell MLE to not allow overflow */
  453.  
  454.                 break;
  455.  
  456.  
  457.             default:
  458.  
  459.                         /* Just do the old frame procedure processing */
  460.  
  461.                 break;
  462.  
  463.             } /* End switch( HIUSHORT( mp1 )) */
  464.             break;
  465.  
  466.         default :
  467.  
  468.                 /* Just do the old frame procedure processing */
  469.  
  470.             break;
  471.  
  472.  
  473.         }  /* End switch( LOUSHORT( mp1 ) ) */
  474.  
  475.  
  476.         /* Just do the old frame procedure processing */
  477.  
  478.         break;
  479.  
  480.  
  481.         default:
  482.  
  483.         /********************************************************************
  484.             Process any help messages that come through.
  485.             If TEDProcessHelpMsg() can handle any of the Help messages it
  486.             receives the TRUE is returned and we return whatever was
  487.             passed back. Other wise the code falls through to the default
  488.             window procedure.
  489.         ********************************************************************/
  490.  
  491.  
  492.             if ( TEDProcessHelpMsg( hwnd, msg, mp1, mp2, &mresult ) )
  493.             {
  494.                 return( mresult );
  495.             }
  496.  
  497.         break;
  498.  
  499.     }  /* End switch( msg ) */
  500.  
  501.  
  502.     return( (*pfnwpoldframe) (hwnd, msg, mp1, mp2)) ;
  503.  
  504.  
  505. }
  506.  
  507.  
  508.  
  509.  
  510.  
  511. /**********************************************************************
  512.  
  513.     ClientWndProc - This procedure is the window proc (subclassed) for
  514.                     the MLE. It handles any of the menu selections made
  515.                     in our menu and passes everything else through to
  516.                     the default window procedure (which is the MLE )
  517.  
  518. **********************************************************************/
  519.  
  520.  
  521.  
  522. MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  523. {
  524.     CHAR achtmp[50];  /* Used to format the string when the user chooses the */
  525.                       /* Query lines , menu choice to see how many lines     */
  526.                       /* there currently are in the MLE                      */
  527.  
  528.     LONG     lFileSize;       /* The amount of text in the MLE */
  529.     HFILE    hf;              /* File handle used for reading/writing */
  530.     USHORT   usAction;        /* Action field of DosOpen call */
  531.  
  532.  
  533.     switch (msg)
  534.     {
  535.  
  536.  
  537.         case WM_COMMAND:
  538.  
  539.             switch( LOUSHORT(mp1) )    /* Switch on Menu ID */
  540.             {
  541.  
  542.                   case IDM_NEWFILE :
  543.  
  544.                 /********************************************************
  545.                     If we disable the MLE then it wont try to keep the
  546.                     display current while were deleting its contents.
  547.                     This way the MLE pointer will turn to an hour glass,
  548.                     all its text will be deleted (by selecting all the
  549.                     text in the MLE and deleting it) then the hour glass
  550.                     will be changed back to the system pointer.  This
  551.                     way it appears better to the user since he does not
  552.                     visually see all the text in the mle get selected
  553.                     and then deleted.
  554.                 ********************************************************/
  555.  
  556.                     MLEDisable( hwndMLE );
  557.  
  558.                 MLEDeleteContents( hwndMLE );
  559.  
  560.                     MLEEnable( hwndMLE );
  561.  
  562.                     TEDInitFileName();
  563.  
  564.                     TEDUpdateTitleBar( hwndFrame,
  565.                                        tedinfo.uchPgmName,
  566.                                        tedinfo.uchFileName );
  567.  
  568.                     break ;
  569.  
  570.             case IDM_OPENFILE :
  571.  
  572.  
  573.                 MLEOpenFile( hwnd,
  574.                                  tedinfo.uchFileName,
  575.                                  tedinfo.uchFullPathName );
  576.  
  577.                     TEDUpdateTitleBar( hwndFrame,
  578.                                        tedinfo.uchPgmName,
  579.                                        tedinfo.uchFileName );
  580.  
  581.                     break ;
  582.  
  583.                 case IDM_SAVE:
  584.  
  585.                 /************************************************************
  586.                     If uchFullPathName is empty then the file name is
  587.                     Untitled so we cannot do a save (since we have no name)
  588.                     so send a message to ourselves as though the user had
  589.                     clicked on the Save as menu item. If the file name is
  590.                     not Untitled then open the current file and save the
  591.                     contents of the MLE.
  592.                 ************************************************************/
  593.  
  594.                     if ( tedinfo.uchFullPathName[0] == '\000' )
  595.                     {
  596.  
  597.                         return ( WinSendMsg( hwnd,
  598.                                              WM_COMMAND,
  599.                                              MPFROMSHORT( IDM_SAVEAS ),
  600.                                              mp2 ));
  601.  
  602.  
  603.                     }
  604.                     else
  605.                     {
  606.  
  607.  
  608.                         if ( DosOpen( tedinfo.uchFullPathName,
  609.                                       &hf,
  610.                                       &usAction,
  611.                                       (ULONG) 0,
  612.                                       (USHORT) 0,
  613.                                       FILE_OPEN,
  614.                                       OPEN_ACCESS_WRITEONLY |
  615.                                         OPEN_SHARE_DENYWRITE,
  616.                                       (ULONG) 0 ) )
  617.                         {
  618.  
  619.                             TEDDisplayErrorID( SID_CANT_OPEN_EX_FILE );
  620.  
  621.                         }
  622.                         else
  623.                         {
  624.  
  625.                             MLESaveToFile( hf );
  626.                             DosClose( hf );
  627.  
  628.                         }
  629.  
  630.                     }
  631.                     break;
  632.  
  633.                 case IDM_SAVEAS :
  634.  
  635.                 MLESaveFile( hwnd,
  636.                                  tedinfo.uchFileName,
  637.                                  tedinfo.uchFullPathName );
  638.  
  639.                     TEDUpdateTitleBar( hwndFrame,
  640.                                        tedinfo.uchPgmName,
  641.                                        tedinfo.uchFileName );
  642.  
  643.                     break ;
  644.  
  645.                 case IDM_FIND :
  646.  
  647.  
  648.  
  649.                 /**********************************************************
  650.                     If the handle to our Find dialog is not null then the
  651.                     Find dialog is loaded so we need only show the window
  652.                     and then give it the focus. If the handle is NULL then
  653.                     the Find dialog has never been loaded so we need to
  654.                     load it.  We use WinLoadDlg() because the Find dialog
  655.                     is modeless ie the user can switch between the find
  656.                     dialog and the mle without first having to terminate the
  657.                     find dialog
  658.                 **********************************************************/
  659.  
  660.                     if ( hwndDlgFind != NULL )
  661.                     {
  662.  
  663.                         WinShowWindow( hwndDlgFind, TRUE );
  664.                         WinSetFocus( HWND_DESKTOP, hwndDlgFind );
  665.  
  666.  
  667.                     }
  668.                     else
  669.                     {
  670.  
  671.                      if ( (hwndDlgFind = WinLoadDlg(HWND_DESKTOP,
  672.                                                        hwnd,
  673.                                                        FindDlgProc,
  674.                                                        (HMODULE) NULL,
  675.                                                        DLG_FIND,
  676.                                                        NULL )) == NULL )
  677.                         {
  678.  
  679.                             TEDDisplayErrorID( SID_DLG_CANT_LOAD_FIND );
  680.  
  681.                         }
  682.                     }
  683.                     break ;
  684.  
  685.             /***********************************************************
  686.                 Since the MLE supports the CUT, COPY PASTE and UNDO we
  687.                 need only send the apropriate msg to the MLE and let it
  688.                 do all the work
  689.             ***********************************************************/
  690.  
  691.             case IDM_CUT      :
  692.  
  693.                 WinSendMsg( hwndMLE, MLM_CUT, NULL, NULL );
  694.                 break ;
  695.  
  696.             case IDM_COPY      :
  697.  
  698.                 WinSendMsg( hwndMLE, MLM_COPY, NULL, NULL );
  699.                     break;
  700.  
  701.                 case IDM_PASTE   :
  702.  
  703.                 WinSendMsg( hwndMLE, MLM_PASTE, NULL, NULL ) ;
  704.                     break ;
  705.  
  706.             case IDM_UNDO      :
  707.  
  708.                 WinSendMsg( hwndMLE, MLM_UNDO, NULL, NULL );
  709.                     break ;
  710.  
  711.                 case IDM_SELECT_ALL :
  712.  
  713.                 /**********************************************************
  714.                     In order to Select all the text in the MLE we need to
  715.                     first query the mle as to the amount of text that is
  716.                     currently in it. Then we send a message to the mle
  717.                     to select the text from the beggining of the mle (IPT 0)
  718.                     to the amount of text the mle told us it had in it.
  719.                 **********************************************************/
  720.  
  721.                     lFileSize= (LONG) WinSendMsg( hwndMLE ,
  722.                                MLM_QUERYTEXTLENGTH,
  723.                                    NULL,
  724.                               NULL );
  725.  
  726.                 WinSendMsg(hwndMLE,
  727.                                MLM_SETSEL,
  728.                                (MPARAM) 0L,
  729.                                (MPARAM) lFileSize);
  730.  
  731.                 break;
  732.  
  733.  
  734.                 case IDM_QUERYLINES:
  735.  
  736.                 /* achtmp can only hold a message that is 50 bytes long */
  737.  
  738.                 sprintf( achtmp, "%ld Lines in Window",
  739.                                (LONG) WinSendMsg( hwndMLE,
  740.                                     MLM_QUERYLINECOUNT,
  741.                                 NULL,
  742.                                 NULL )) ;
  743.  
  744.                  MESSAGE( achtmp );
  745.                 break;
  746.  
  747.  
  748.             case IDM_SETWRAP :
  749.  
  750.                     MLESetWrap( hwndMLE, hwndMenu, TRUE );
  751.                 break ;
  752.  
  753.  
  754.             case IDM_DISPLAY_HELP:
  755.  
  756.                     TEDSendHelpMsg( HM_DISPLAY_HELP );
  757.                 break;
  758.  
  759.  
  760.             case IDM_EXT_HELP:
  761.  
  762.                 TEDSendHelpMsg( HM_EXT_HELP );
  763.                 break;
  764.  
  765.             case IDM_INDEX_HELP:
  766.  
  767.                 TEDSendHelpMsg( HM_HELP_INDEX );
  768.                 break;
  769.  
  770.  
  771.             case IDM_KEYS_HELP:
  772.  
  773.                 TEDSendHelpMsg( HM_KEYS_HELP );
  774.                 break;
  775.  
  776.                 case IDM_ABOUT   :      /* About TED dialog */
  777.  
  778.                 if ( WinDlgBox( HWND_DESKTOP,
  779.                             hwndMLE,
  780.                             AboutDlgProc,
  781.                             (HMODULE) NULL,
  782.                             DLG_ABOUT,
  783.                             NULL )  == DID_ERROR )
  784.                     {
  785.  
  786.                         TEDDisplayErrorID( SID_DLG_CANT_LOAD_ABOUT );
  787.  
  788.                     }
  789.                 break ;
  790.  
  791.                 default:
  792.  
  793.             /* Fall through to old procedure processing */
  794.  
  795.                 break;
  796.  
  797.  
  798.             }  /* End switch ( LOUSHORT( mp1 )) */
  799.  
  800.             break ;
  801.  
  802.         default:
  803.  
  804.         /* Fall through to old procedure processing */
  805.  
  806.             break;
  807.  
  808.  
  809.  
  810.     }  /* End switch ( msg ) */
  811.  
  812.     return( (*pfnwpold) (hwnd, msg, mp1, mp2)) ;
  813. }
  814.  
  815.  
  816.  
  817.  
  818. /**********************************************************************
  819.  
  820.     AboutDlgProc - This procedure is the dialog procedure for the
  821.                    About box.
  822.  
  823. **********************************************************************/
  824.  
  825.  
  826. MRESULT EXPENTRY AboutDlgProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  827. {
  828.  
  829.  
  830.     switch( msg )
  831.     {
  832.  
  833.         case WM_INITDLG:
  834.  
  835.             TEDInitDlgSysMenu( hwnd );    /* setup the system menu */
  836.  
  837.             break;
  838.  
  839.         case WM_CLOSE:
  840.  
  841.             if ( !WinDismissDlg(hwnd, TRUE))
  842.             {
  843.                 TEDDisplayErrorID( SID_DLG_FIND_CANT_DISMISS );
  844.  
  845.                 TEDCleanupExit(); /* Cleanup and exit , NOTE: never returns!! */
  846.             }
  847.  
  848.  
  849.             return((MRESULT)TRUE);
  850.  
  851.             break;
  852.  
  853.  
  854.         case WM_COMMAND:                        /* Process the Buttons  */
  855.  
  856.  
  857.             switch (LOUSHORT(mp1))
  858.             {
  859.  
  860.                 case DID_OK:                    /* OK */
  861.  
  862.                     if ( !WinDismissDlg( hwnd, TRUE ))
  863.                     {
  864.                         TEDDisplayErrorID( SID_DLG_FIND_CANT_DISMISS );
  865.                     }
  866.  
  867.                     return(MRESULT) TRUE;
  868.  
  869.                     break;
  870.  
  871.                 default:
  872.  
  873.                     return(MRESULT) TRUE;
  874.                     break;
  875.             }
  876.  
  877.         default:
  878.  
  879.             return( WinDefDlgProc( hwnd, msg, mp1, mp2 ) );
  880.  
  881.             break;
  882.  
  883.     }
  884.     return (MRESULT) FALSE;
  885. }
  886.  
  887.  
  888.  
  889. /**********************************************************************
  890.  
  891.     FindDlgProc - This procedure is the dialog procedure for the
  892.                   Find dialog box.  It is modeless so the user
  893.                   is allowed to switch between the Find dialog box
  894.                   and the MLE.
  895.  
  896. **********************************************************************/
  897.  
  898.  
  899.  
  900. MRESULT EXPENTRY FindDlgProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  901. {
  902.     UCHAR   auchFindText[MAX_STRING_SIZE];  /* The find text from the     */
  903.                                             /* FIND dialog box            */
  904.  
  905.     UCHAR   auchChangeText[MAX_STRING_SIZE];/* The change to text from    */
  906.                                             /* the FIND dialog box        */
  907.  
  908.     ULONG   ulSearchFlags;                  /* Search flags passed to MLE */
  909.  
  910.  
  911.     MLE_SEARCHDATA seMLESearchData;         /* The MLE search structure   */
  912.  
  913.  
  914.     switch (msg)
  915.     {
  916.  
  917.         case WM_INITDLG:
  918.  
  919.  
  920.         /*******************************************************************
  921.             Send a msg to each of the entry fields which contain the
  922.             FIND and CHANGE TO text in order to limit the size to the
  923.             buffer we have allocated to receive that text.
  924.         *******************************************************************/
  925.  
  926.             WinSendMsg( WinWindowFromID( hwnd, DID_FIND_TEXT),
  927.                         EM_SETTEXTLIMIT,
  928.                         MPFROMSHORT( MAX_STRING_SIZE),
  929.                         NULL );
  930.  
  931.  
  932.             WinSendMsg( WinWindowFromID( hwnd, DID_CHANGE_TEXT),
  933.                         EM_SETTEXTLIMIT,
  934.                         MPFROMSHORT( MAX_STRING_SIZE),
  935.                         NULL );
  936.  
  937.  
  938.             TEDInitDlgSysMenu( hwnd );
  939.  
  940.  
  941.             break;
  942.  
  943.  
  944.         case WM_COMMAND:
  945.  
  946.  
  947.             switch (SHORT1FROMMP(mp1))
  948.             {
  949.  
  950.                 case DID_FIND_CHANGE_ALL:
  951.  
  952.  
  953.                 /* Get the FIND and CHANGE TO text the user entered */
  954.  
  955.                     WinQueryWindowText( WinWindowFromID( hwnd, DID_FIND_TEXT),
  956.                                         MAX_FNAME_LEN,
  957.                                         auchFindText );
  958.  
  959.  
  960.                     WinQueryWindowText( WinWindowFromID( hwnd, DID_CHANGE_TEXT),
  961.                                         MAX_FNAME_LEN,
  962.                                         auchChangeText );
  963.  
  964.  
  965.                     ulSearchFlags = MLFSEARCH_CHANGEALL;
  966.  
  967.                     if ( WinSendMsg( WinWindowFromID(hwnd,DID_SENSITIVE),
  968.                                      BM_QUERYCHECK,
  969.                                      NULL,
  970.                                      NULL))
  971.                     {
  972.  
  973.                         ulSearchFlags |= MLFSEARCH_CASESENSITIVE;
  974.                     }
  975.  
  976.  
  977.                 /* Fill the MLE search structure with the search/change data */
  978.  
  979.                     seMLESearchData.cb         = sizeof( seMLESearchData );
  980.  
  981.                     seMLESearchData.pchFind    = auchFindText;
  982.                     seMLESearchData.cchFind    = strlen( auchFindText );
  983.  
  984.                     seMLESearchData.pchReplace = auchChangeText;
  985.                     seMLESearchData.cchReplace = strlen( auchChangeText );
  986.  
  987.                     seMLESearchData.iptStart   =  0; /* Start at cursor IPT  */
  988.                     seMLESearchData.iptStop    = -1; /* Search to end of MLE */
  989.  
  990.  
  991.  
  992.                     if ( seMLESearchData.cchFind ) /* Non-empty string to    */
  993.                     {                              /* to search for          */
  994.  
  995.  
  996.  
  997.                         if ( !WinSendMsg( hwndMLE,
  998.                                           MLM_SEARCH,
  999.                                           (MPARAM) ulSearchFlags,
  1000.                                           (MPARAM) &seMLESearchData ) )
  1001.                         {
  1002.  
  1003.                             TEDDisplayErrorID( SID_CANT_FIND );
  1004.  
  1005.                         }
  1006.                         else
  1007.                         {
  1008.  
  1009.                             WinSetFocus( HWND_DESKTOP, hwndMLE );
  1010.  
  1011.                         }
  1012.  
  1013.                     }
  1014.                     break;
  1015.  
  1016.  
  1017.  
  1018.                 case DID_FIND:
  1019.  
  1020.  
  1021.                     WinQueryWindowText( WinWindowFromID( hwnd, DID_FIND_TEXT),
  1022.                                         MAX_FNAME_LEN,
  1023.                                         auchFindText );
  1024.  
  1025.  
  1026.                     ulSearchFlags = MLFSEARCH_SELECTMATCH;
  1027.  
  1028.                     if ( WinSendMsg( WinWindowFromID(hwnd,DID_SENSITIVE),
  1029.                                      BM_QUERYCHECK,
  1030.                                      NULL,
  1031.                                      NULL))
  1032.                     {
  1033.  
  1034.                         ulSearchFlags |= MLFSEARCH_CASESENSITIVE;
  1035.                     }
  1036.  
  1037.  
  1038.                     seMLESearchData.cb       = sizeof( seMLESearchData );
  1039.  
  1040.                     seMLESearchData.pchFind  = auchFindText;
  1041.                     seMLESearchData.cchFind  = strlen( auchFindText );
  1042.  
  1043.  
  1044.                 /*************************************************************
  1045.                     The search always starts at the cursor point and
  1046.                     continues to the end of the MLE.  It would be better
  1047.                     to put a WRAP box in the Find dialog box so the search
  1048.                     would wrap around to the beginning if the user so desired.
  1049.                     Currently the user has to <ctrl> HOME to get to the top
  1050.                     of the MLE before doing a find/Change all once the
  1051.                     cursor is at the bottom of the MLE.
  1052.                 *************************************************************/
  1053.  
  1054.  
  1055.                     seMLESearchData.iptStart = -1;   /* Start at cursor IPT  */
  1056.                     seMLESearchData.iptStop  = -1;   /* Search to end of MLE */
  1057.  
  1058.  
  1059.                 /* Is there some text to search for ? */
  1060.  
  1061.                     if ( seMLESearchData.cchFind )
  1062.                     {
  1063.  
  1064.                     /**********************************************************
  1065.                         Since a WinSendMsg is done here instead of a WinPost
  1066.                         then the search will be synchronous.  The
  1067.                         application will wait until the search is complete
  1068.                         before continuing.  This is ok in this application
  1069.                         since we are limiting the search.  The MLE sends
  1070.                         notification messages occasionally when it is searching
  1071.                         so the the user can have the option of aborting the
  1072.                         search.
  1073.                     **********************************************************/
  1074.  
  1075.  
  1076.                         if ( !WinSendMsg( hwndMLE,
  1077.                                           MLM_SEARCH,
  1078.                                           (MPARAM) ulSearchFlags,
  1079.                                           (MPARAM) &seMLESearchData ) )
  1080.                         {
  1081.  
  1082.                             TEDDisplayErrorID( SID_CANT_FIND );
  1083.  
  1084.                         }
  1085.                         else
  1086.                         {
  1087.  
  1088.                             WinSetFocus( HWND_DESKTOP, hwndMLE );
  1089.  
  1090.                         }
  1091.  
  1092.                     }
  1093.  
  1094.                     break;
  1095.  
  1096.                  case MBID_CANCEL:   /* modeless so don't no need to dismiss */
  1097.  
  1098.                     WinPostMsg( hwnd, WM_CLOSE, NULL, NULL );
  1099.                     break;
  1100.  
  1101.                  default:
  1102.  
  1103.                     return( WinDefDlgProc( hwnd, msg, mp1, mp2 ));
  1104.                     break;
  1105.  
  1106.             } /* End switch (SHORT1FROMMP(mp1)) */
  1107.             break;
  1108.  
  1109.             return (MRESULT) FALSE;
  1110.  
  1111.         default:
  1112.             return( WinDefDlgProc( hwnd, msg, mp1, mp2 ));
  1113.         break;
  1114.  
  1115.     } /* End switch ( msg ) */
  1116.  
  1117.     return (MRESULT) FALSE ;
  1118.  
  1119. }
  1120.  
  1121.  
  1122.  
  1123.  
  1124. /**********************************************************************
  1125.  
  1126.     MLESaveFile - This procedure enables the save file dialog, lets
  1127.                   the user choose a file, then saves the contents of
  1128.                   the MLE to that file.
  1129.  
  1130. **********************************************************************/
  1131.  
  1132.  
  1133.  
  1134. VOID MLESaveFile( HWND hwnd, PSZ pszFname, PSZ pszFullName )
  1135. {
  1136.  
  1137.     BOOL    fSuccess = TRUE;     /* Flag if user want to save               */
  1138.     DLF        dlf;                 /* Data structure for save dialog          */
  1139.     HFILE   hf;                  /* File handle of file to save MLE in      */
  1140.  
  1141.  
  1142. /*****************************************************************************
  1143.     Initialize the data structure used by the save as toolkit dialog.
  1144.     Call DlgFile which will put up the save as dialog and return back
  1145.     a handle to the opened file.
  1146. *****************************************************************************/
  1147.  
  1148.  
  1149.     SetupDLF( &dlf,                      /* Pointer to dialog data structure */
  1150.               DLG_SAVEDLG | DLG_HELP,    /* Type of dialog to bring up       */
  1151.               &hf,                       /* Pointer to file handle           */
  1152.               "\\*.DOC",                 /* Mask of files to bring up        */
  1153.               "Dialog Error",            /* Msgbox title if Error            */
  1154.               "Save as",                 /* Title of Save as dialog window   */
  1155.               "No Help Available");      /* Help message                     */
  1156.  
  1157.  
  1158.     dlf.szFileName[0] = dlf.szOpenFile[0] = '\000' ;
  1159.  
  1160.  
  1161.  
  1162.     switch( DlgFile( hwnd, &dlf ))
  1163.     {
  1164.  
  1165.     case TDF_ERRMEM:
  1166.     case TDF_INVALID:
  1167.         case TDF_NOOPEN:
  1168.  
  1169.         fSuccess = FALSE;
  1170.         break;
  1171.  
  1172.     case TDF_NOSAVE:
  1173.  
  1174.         fSuccess = FALSE;
  1175.         break;
  1176.  
  1177.     default:
  1178.  
  1179.         break;
  1180.  
  1181.     }
  1182.  
  1183. /*****************************************************************************
  1184.     If fSuccess is TRUE then the user chose a file and we have the handle
  1185.     to it.  So we save the contents of the MLE to that file handle and update
  1186.     the file name information.
  1187. *****************************************************************************/
  1188.  
  1189.  
  1190.     if ( fSuccess )
  1191.     {
  1192.  
  1193.         if ( MLESaveToFile( hf ))
  1194.         {
  1195.  
  1196.         /* Copy the file info into the correct place */
  1197.  
  1198.             strcpy( pszFname, dlf.szFileName );
  1199.             strcpy( pszFullName, dlf.szOpenFile );
  1200.  
  1201.         }
  1202.  
  1203.         DosClose( hf );
  1204.  
  1205.  
  1206.     }
  1207.  
  1208. }
  1209.  
  1210. /*****************************************************************************
  1211.  
  1212.     MLESaveToFile - This procedure takes a passed file handle and writes
  1213.                     the contents of the MLE to it.
  1214.  
  1215.           Returns - True if the MLE was written to the file handle
  1216.                     succesfully otherwise FALSE is returned.
  1217.  
  1218. *****************************************************************************/
  1219.  
  1220. BOOL MLESaveToFile( HFILE hf )
  1221. {
  1222.  
  1223.     PCHAR   pvBuff;              /* Pointer to buffer with exported MLE data*/
  1224.     IPT        iptFormatedTextSize; /* The number of bytes of FORMATTED data   */
  1225.     IPT     iptTextSize;         /* The number of bytes in the MLE          */
  1226.                                  /* NOTE!!! not equal to iptFormatedTextSize*/
  1227.  
  1228.     IPT        iptData;             /* Temp used to hold IPT data              */
  1229.     USHORT  cbBytesWritten;      /* Number of bytes written from DosWrite   */
  1230.     BOOL    bRetVal = TRUE;      /* Default to OK                           */
  1231.  
  1232.  
  1233.     /*************************************************************************
  1234.         First we query the MLE to find out how much data is it. The
  1235.         reason we ask for it with the QUERYFORMATTEXTLENGTH is because
  1236.         the MLE stores the text in a different format than it exports it.
  1237.         Mainly because it stores hard returns as one byte (LF) although
  1238.         based on the formatting currently enabled it may export the LF as
  1239.         a CR/LF in which case asking the MLE how much data it has with the
  1240.         QUERYTEXTLENGTH message would yield a number too small.
  1241.  
  1242.         In essence we are asking the MLE :
  1243.  
  1244.              "If the data were exported at this time how many bytes would
  1245.               be required to store it??"
  1246.     *************************************************************************/
  1247.  
  1248.  
  1249.         iptFormatedTextSize = (IPT) WinSendMsg( hwndMLE,
  1250.                                                 MLM_QUERYFORMATTEXTLENGTH,
  1251.                                                 (MPARAM) (IPT) 0L,  /*beg MLE*/
  1252.                                                 (MPARAM) (IPT) -1 );/*end MLE*/
  1253.  
  1254.  
  1255.  
  1256.     /* Now Query MLE to find out how much data there is (IPT format) */
  1257.  
  1258.         iptTextSize = (IPT) WinSendMsg( hwndMLE,
  1259.                                         MLM_QUERYTEXTLENGTH,
  1260.                                         NULL,
  1261.                                         NULL );
  1262.  
  1263.  
  1264.     /* Allocate a buffer based on the formated size */
  1265.  
  1266.     /*********************************************************************
  1267.        The "+ (IPT) 1" is due to a bug in the MLE that should have been
  1268.        corrected.  This plus one will not effect the sample app once
  1269.        the bug is fixed
  1270.     *********************************************************************/
  1271.  
  1272.  
  1273.         if ( MyAllocMem( &pvBuff, iptFormatedTextSize + (IPT) 1, 0 ) ) {
  1274.  
  1275.  
  1276.         TEDDisplayErrorID( SID_CANT_ALLOCATE_MEMORY );
  1277.  
  1278.             bRetVal = FALSE;
  1279.  
  1280.         }
  1281.         else
  1282.         {
  1283.  
  1284.     /* Set up IMPORT/EXPORT transfer location */
  1285.  
  1286.         WinSendMsg( hwndMLE,
  1287.                         MLM_SETIMPORTEXPORT,
  1288.             (MPARAM) pvBuff,                 /* Pointer to buff */
  1289.             (MPARAM) iptFormatedTextSize );  /* Size of buff    */
  1290.  
  1291.  
  1292.  
  1293.         /* Now do the Export into the allocated BUFFER */
  1294.  
  1295.  
  1296.         iptData = 0L;
  1297.  
  1298.         WinSendMsg( hwndMLE,
  1299.                         MLM_EXPORT,                /* EXPORT TYPE             */
  1300.                         (MPARAM) &iptData,         /* IPT start for EXPORT    */
  1301.                         (MPARAM) &iptTextSize ) ;  /* Amount to EXPORT (bytes)*/
  1302.  
  1303.  
  1304.         /**********************************************************************
  1305.             iptTextSize is decremented by the MLE based on how many bytes
  1306.             were actually exported.  If this number is not 0 then an incorrect
  1307.             amount of data was exported.
  1308.         **********************************************************************/
  1309.  
  1310.  
  1311.             if ( iptTextSize != (IPT) 0L )
  1312.             {
  1313.                 TEDDisplayErrorID( SID_UNABLE_TO_EXPORT );
  1314.                 bRetVal = FALSE;
  1315.             }
  1316.  
  1317.  
  1318.         /**********************************************************************
  1319.             Since we might of been shrinking the size of the file we need to
  1320.             reset the size of the file to 0. This way the size of the file
  1321.             becomes the number of bytes that we will write to it.
  1322.         **********************************************************************/
  1323.  
  1324.         if ( bRetVal && DosNewSize( hf, 0L ) )
  1325.             {
  1326.                 TEDDisplayErrorID( SID_UNABLE_TO_SET_NEWSIZE );
  1327.                 bRetVal = FALSE;
  1328.         }
  1329.  
  1330.  
  1331.         /**********************************************************************
  1332.            Note iptFormatedTextSize is not checked since we limit the
  1333.            size of the MLE to something that will fit in a USHORT.
  1334.         **********************************************************************/
  1335.  
  1336.           if ( bRetVal && DosWrite( hf,
  1337.                                       (PVOID) pvBuff,
  1338.                                       (USHORT) iptFormatedTextSize,
  1339.                                       &cbBytesWritten ) )
  1340.             {
  1341.  
  1342.                 TEDDisplayErrorID( SID_DOSWRITE_FAILED );
  1343.                 bRetVal = FALSE;
  1344.  
  1345.             }
  1346.  
  1347.         /* Free the buffer we used for the transfer */
  1348.  
  1349.             MyFreeMem( pvBuff );
  1350.  
  1351.  
  1352.            if ( bRetVal && ( iptFormatedTextSize != (IPT) cbBytesWritten ))
  1353.         {
  1354.             TEDDisplayErrorID( SID_WRONG_BYTE_COUNT );
  1355.                 bRetVal = FALSE;
  1356.         }
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362.         } /* End if Buffer available */
  1363.  
  1364.     return ( bRetVal );   /* return success flag */
  1365.  
  1366. }
  1367.  
  1368.  
  1369. /*****************************************************************************
  1370.  
  1371.     MLEOpenFile - This procedure prompts the user for a file name to edit
  1372.                   using the open file dialog supplied with the toolkit.
  1373.                   If a user chooses a file to open then the file name and
  1374.                   fully qualified path are copied into the passed parameters.
  1375.  
  1376. *****************************************************************************/
  1377.  
  1378. VOID MLEOpenFile( HWND hwnd, PSZ pszFname, PSZ pszFullName )
  1379. {
  1380.  
  1381.     BOOL       fSuccess = TRUE;  /* Success flag for file chosen by user */
  1382.     DLF           dlf;              /* Data structure for Open dialog       */
  1383.     HFILE      hf;               /* File handle of file chosen by user   */
  1384.     PCHAR      pvBuff;           /* Buffer user to import file into MLE  */
  1385.     USHORT     cbBytesRead;      /* Number of bytes read by DosRead      */
  1386.     FILESTATUS stsInfo;          /* Information about the file           */
  1387.     IPT           iptData;          /* Position in MLE to import file       */
  1388.  
  1389.  
  1390.     SetupDLF( &dlf,
  1391.               DLG_OPENDLG | DLG_HELP,
  1392.               &hf,
  1393.               "\\*.DOC",
  1394.               "Dialog Error",            /* Msgbox title if Error            */
  1395.               "Open",
  1396.               "No help available");
  1397.  
  1398.  
  1399.     dlf.szFileName[0] = dlf.szOpenFile[0] = '\0' ;
  1400.  
  1401.  
  1402.  
  1403.     switch( DlgFile( hwnd, &dlf ))
  1404.     {
  1405.  
  1406.     case TDF_ERRMEM:
  1407.     case TDF_INVALID:
  1408.  
  1409.        fSuccess = FALSE;
  1410.        break;
  1411.  
  1412.     case TDF_NOOPEN:
  1413.  
  1414.        fSuccess = FALSE;
  1415.        break;
  1416.  
  1417.     default:
  1418.  
  1419.        break;
  1420.     }
  1421.  
  1422.  
  1423.  
  1424.     if ( fSuccess ) {
  1425.  
  1426.  
  1427.     /* Find out the size of the file */
  1428.  
  1429.         if ( DosQFileInfo( hf,
  1430.                            FIL_STANDARD,
  1431.                    (PBYTE) &stsInfo,
  1432.                    (USHORT) sizeof( FILESTATUS )))
  1433.         {
  1434.  
  1435.         TEDDisplayErrorID( SID_DOSQFILEINFO_FAILED );
  1436.  
  1437.         }
  1438.  
  1439.  
  1440.     /* If file is too large then truncate it */
  1441.  
  1442.         if ( stsInfo.cbFile > (LONG) TXT_LIMIT )
  1443.         {
  1444.  
  1445.             TEDDisplayErrorID( SID_FILE_TOO_LARGE );
  1446.  
  1447.             stsInfo.cbFile = (LONG) TXT_LIMIT;
  1448.  
  1449.         }
  1450.  
  1451.  
  1452.     /* Allocate a buffer to do the IMPORT */
  1453.  
  1454.         if (  MyAllocMem( (PVOID *) &pvBuff,
  1455.                           (LONG) stsInfo.cbFile,
  1456.                           0    ))
  1457.         {
  1458.  
  1459.             TEDDisplayErrorID( SID_CANT_ALLOCATE_MEMORY );
  1460.  
  1461.         }
  1462.         else
  1463.         {
  1464.  
  1465.  
  1466.         /*****************************************************************
  1467.            stsInfo.cbFile is always truncated to TXT_LIMIT so it will
  1468.            always fit in a short.
  1469.         *****************************************************************/
  1470.  
  1471.         if ( !DosRead( hf,
  1472.                      (PVOID) pvBuff ,
  1473.                (USHORT) stsInfo.cbFile,
  1474.                &cbBytesRead )) {
  1475.  
  1476.  
  1477.             MLEDisable( hwndMLE );
  1478.  
  1479.  
  1480.  
  1481.         /* Delete whatever is in MLE right now */
  1482.  
  1483.  
  1484.             MLEDeleteContents( hwndMLE );
  1485.  
  1486.  
  1487.         /* Reset the undo since a new file was imported into the MLE */
  1488.  
  1489.             WinSendMsg( hwndMLE, MLM_RESETUNDO, NULL, NULL );
  1490.  
  1491.  
  1492.  
  1493.         /* Read the data succesfully, now import to MLE */
  1494.  
  1495.             WinSendMsg( hwndMLE,
  1496.                             MLM_SETIMPORTEXPORT,
  1497.                 (MPARAM) pvBuff,
  1498.                 (MPARAM) cbBytesRead );
  1499.  
  1500.             iptData = 0L;
  1501.  
  1502.                WinSendMsg( hwndMLE,
  1503.                             MLM_IMPORT,
  1504.                             (MPARAM) &iptData,
  1505.                     (MPARAM) cbBytesRead );
  1506.  
  1507.             /****************************************************************
  1508.                 Here we should check to see if the number of bytes imported
  1509.                 matches the number of bytes we told the MLE to import.
  1510.             *****************************************************************
  1511.  
  1512.  
  1513.         /* Release memory */
  1514.  
  1515.             MyFreeMem( pvBuff );
  1516.  
  1517.  
  1518.             /* Copy the file name info into the correct place */
  1519.  
  1520.                 strcpy( pszFname, dlf.szFileName );
  1521.                 strcpy( pszFullName, dlf.szOpenFile );
  1522.  
  1523.  
  1524.                 MLEEnable( hwndMLE );
  1525.  
  1526.  
  1527.         }
  1528.             else
  1529.             {
  1530.             TEDDisplayErrorID( SID_DOS_READ_FAILED );
  1531.  
  1532.         }
  1533.  
  1534.         }
  1535.  
  1536.         DosClose( hf );
  1537.  
  1538.     }
  1539.  
  1540. }
  1541.  
  1542.  
  1543.  
  1544. /****************************************************************************
  1545.  
  1546.     MLEInit - This procedure initializes certain MLE parameters to a known
  1547.               state.
  1548.  
  1549. ****************************************************************************/
  1550.  
  1551.  
  1552. VOID MLEInit( HWND hwnd )
  1553. {
  1554.  
  1555.     /*************************************************************************
  1556.         Set the text limit of the MLE to TXT_LIMIT. Any attempt to exceed
  1557.         this limit will result in a WM_CONTROL message (notification)
  1558.         to the MLE.
  1559.     *************************************************************************/
  1560.  
  1561.         WinSendMsg( hwnd,
  1562.                     MLM_SETTEXTLIMIT,
  1563.                     (MPARAM) ( (LONG) TXT_LIMIT),
  1564.                     NULL );
  1565.  
  1566.  
  1567.     /*************************************************************************
  1568.         Set the MLE format to MLFIE_CFTEXT which is the Cliboard text format.
  1569.         This format uses CR/LF for line delineation on export and recognizes
  1570.         either LF, CR/LF, or LF/CR as a line delineation on import.
  1571.     *************************************************************************/
  1572.  
  1573.         WinSendMsg( hwnd,
  1574.                     MLM_FORMAT,
  1575.                     (MPARAM) (USHORT) MLFIE_CFTEXT,
  1576.                     NULL );
  1577.  
  1578.  
  1579. }
  1580.  
  1581.  
  1582. /*****************************************************************************
  1583.  
  1584.     MLESetWrap - This procedure determines the current set of the WRAP state
  1585.                  in the MLE and optionally (fToggle TRUE ) toggles it. In
  1586.                  either case the Menu item Word wrap is checked or unchecked
  1587.                  in order to display the correct wrap state of the MLE.
  1588.  
  1589. *****************************************************************************/
  1590.  
  1591.  
  1592.  
  1593. VOID MLESetWrap( HWND hwnd, HWND hwndMenuWrap, BOOL fToggle )
  1594. {
  1595.     BOOL fWrap;         /* The wrap state of the MLE */
  1596.  
  1597.  
  1598.     /* First query the wrap from the MLE */
  1599.  
  1600.     fWrap = (BOOL)SHORT1FROMMR( WinSendMsg( hwnd, MLM_QUERYWRAP, NULL, NULL ));
  1601.  
  1602.  
  1603.     if ( fToggle )
  1604.     {
  1605.  
  1606.         fWrap = !fWrap;
  1607.  
  1608.         if ( !WinSendMsg( hwnd, MLM_SETWRAP, (MPARAM) fWrap, NULL ) )
  1609.         {
  1610.         TEDDisplayErrorID( SID_CANT_SET_WRAP );
  1611.  
  1612.         return;
  1613.         }
  1614.  
  1615.     }
  1616.  
  1617.  
  1618.     /* Show the checked state on the menu item */
  1619.  
  1620.     WinSendMsg(hwndMenuWrap,
  1621.                MM_SETITEMATTR,
  1622.            MPFROM2SHORT(IDM_SETWRAP, TRUE),
  1623.            MPFROM2SHORT(MIA_CHECKED,
  1624.            fWrap ? MIA_CHECKED : FALSE) ) ;
  1625.  
  1626.  
  1627. }
  1628.  
  1629.  
  1630.  
  1631.  
  1632. /*****************************************************************************
  1633.  
  1634.     MLEEnable - This procedure Enables the MLE so it will take input from the
  1635.                 user and update itself to correctly track what is in the
  1636.                 MLE buffer.
  1637.  
  1638. *****************************************************************************/
  1639.  
  1640. VOID MLEEnable( HWND hwnd )
  1641. {
  1642.     WinSendMsg( hwnd, MLM_ENABLEREFRESH, NULL, NULL );
  1643. }
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650. /*****************************************************************************
  1651.  
  1652.     MLEDisable - This procedure disables the MLE so it will not take input
  1653.                  from the user, change its pointer to the system wait icon
  1654.                  and not update itself.
  1655.  
  1656. *****************************************************************************/
  1657.  
  1658. VOID MLEDisable( HWND hwnd )
  1659. {
  1660.     WinSendMsg( hwnd, MLM_DISABLEREFRESH, NULL, NULL );
  1661. }
  1662.  
  1663.  
  1664.  
  1665.  
  1666. /*****************************************************************************
  1667.  
  1668.     MLEDeleteContents - This procedure deletes all the text in the MLE.
  1669.  
  1670.       Returns - TRUE if succesfull.
  1671.  
  1672. *****************************************************************************/
  1673.  
  1674.  
  1675. BOOL MLEDeleteContents( HWND hwnd )
  1676. {
  1677.  
  1678.     IPT iptTextLength;      /* Length of the text currently in the MLE */
  1679.  
  1680.  
  1681.  
  1682.     iptTextLength = (IPT) WinSendMsg( hwnd, MLM_QUERYTEXTLENGTH, NULL, NULL );
  1683.  
  1684.  
  1685. /* Now delete all the text in the MLE */
  1686.  
  1687.     return (  (IPT) WinSendMsg( hwnd,
  1688.                                 MLM_DELETE,       /* Delete MSG */
  1689.                                 (MPARAM) 0,       /* Start IPT location */
  1690.                                 (MPARAM) iptTextLength ) == iptTextLength );
  1691.  
  1692.  
  1693.  
  1694. }
  1695.  
  1696. /*****************************************************************************
  1697.  
  1698.     TEDDisplayErrorID - This procedure loads the text associated with the
  1699.                         passed in resource identifier and displays it to
  1700.                         the user in the form of a message box.
  1701.  
  1702.               Returns - TRUE if the user clicked on okay
  1703.  
  1704. *****************************************************************************/
  1705.  
  1706.  
  1707. BOOL TEDDisplayErrorID( USHORT usid )
  1708. {
  1709.  
  1710.     UCHAR  uchTempBuff[ MAX_STRING_SIZE ]; /* Temp used to load string into*/
  1711.     USHORT usRetVal;                       /* Return val */
  1712.  
  1713.  
  1714.     if ( WinLoadString( hab, (HMODULE) NULL, usid, sizeof( uchTempBuff ), uchTempBuff ))
  1715.     {
  1716.  
  1717.        usRetVal = MESSAGE( uchTempBuff );
  1718.  
  1719.     }
  1720.     else
  1721.     {
  1722.  
  1723.        usRetVal = MESSAGE("Cannot load resource string");
  1724.  
  1725.     }
  1726.  
  1727.     return( usRetVal == MBID_OK );
  1728. }
  1729.  
  1730.  
  1731. /*****************************************************************************
  1732.  
  1733.     TEDInitDlgSysMenu - This procedure takes the system menu from the passed
  1734.                         window handle and deletes the :
  1735.  
  1736.                                 MINIMIZE
  1737.                                 MAXIMIZE
  1738.                                 SIZE
  1739.                                 RESTORE
  1740.                                 TASKMANAGER
  1741.  
  1742.                         entries from the system menu.
  1743.  
  1744. *****************************************************************************/
  1745.  
  1746.  
  1747. VOID TEDInitDlgSysMenu( HWND hDlg )
  1748. {
  1749.     HWND hSysMenu;      /* Window handle of the system menu attached to the */
  1750.                         /* passed dialog handle                             */
  1751.  
  1752.  
  1753.  
  1754.  
  1755.     hSysMenu=WinWindowFromID(hDlg, FID_SYSMENU);
  1756.  
  1757.     WinSendMsg(hSysMenu,
  1758.                MM_DELETEITEM,
  1759.                MPFROM2SHORT(SC_MINIMIZE,TRUE),
  1760.                MPFROMSHORT(NULL));
  1761.  
  1762.     WinSendMsg(hSysMenu,
  1763.                MM_DELETEITEM,
  1764.                MPFROM2SHORT(SC_MAXIMIZE,TRUE),
  1765.                MPFROMSHORT(NULL));
  1766.  
  1767.     WinSendMsg(hSysMenu,
  1768.                MM_DELETEITEM,
  1769.                MPFROM2SHORT(SC_SIZE,TRUE),
  1770.                MPFROMSHORT(NULL));
  1771.  
  1772.     WinSendMsg(hSysMenu,
  1773.                MM_DELETEITEM,
  1774.                MPFROM2SHORT(SC_RESTORE,TRUE),
  1775.                MPFROMSHORT(NULL));
  1776.  
  1777.     WinSendMsg(hSysMenu,
  1778.                MM_DELETEITEM,
  1779.                MPFROM2SHORT(SC_TASKMANAGER,TRUE),
  1780.                MPFROMSHORT(NULL));
  1781.  
  1782.  
  1783. }
  1784.  
  1785.  
  1786. /***************************************************************************
  1787.  
  1788.     TEDCleanupExit - This procedure cleans up by determining if valid
  1789.                      handles existed and then destroying them.
  1790.  
  1791.                      NOTE!! This procedure calls DosExit and thus never
  1792.                             returns.
  1793.  
  1794. ***************************************************************************/
  1795.  
  1796.  
  1797. VOID TEDCleanupExit(VOID)
  1798. {
  1799.  
  1800.  
  1801. /* If the find dialog was ever used then destroy it */
  1802.  
  1803.     if ( hwndDlgFind != (HWND) NULL )
  1804.     {
  1805.         WinDestroyWindow( hwndDlgFind );
  1806.     }
  1807.  
  1808.  
  1809.  
  1810.  
  1811. /*  Standard Presentation Manager Application exit sequence. */
  1812.  
  1813.  
  1814.     if ( hwndFrame != (HWND) NULL )
  1815.     {
  1816.         WinDestroyWindow (hwndFrame ) ;
  1817.     }
  1818.  
  1819.  
  1820.     if ( hmq != (HMQ) NULL )
  1821.     {
  1822.         WinDestroyMsgQueue (hmq) ;
  1823.     }
  1824.  
  1825.  
  1826.     if ( hab != (HAB) NULL )
  1827.     {
  1828.         WinTerminate (hab) ;
  1829.     }
  1830.  
  1831.  
  1832.     DosExit( EXIT_PROCESS, 0 );
  1833.  
  1834.  
  1835. }
  1836.  
  1837.  
  1838. /*****************************************************************************
  1839.  
  1840.     TEDUpdateTitleBar - This function updates the title (FID_TITLEBAR) of the
  1841.                         passed in hwnd with the two passed in string.
  1842.                         The strings are format as  <STRING> - <STRING>.
  1843.                         This is used to display the program name and file
  1844.                         currently being edited.
  1845.  
  1846. *****************************************************************************/
  1847.  
  1848.  
  1849.  
  1850. VOID TEDUpdateTitleBar( HWND hwnd, PSZ pszPgmName, PSZ pszFileName )
  1851. {
  1852.  
  1853.     UCHAR auchTemp [ 2 * CCHMAXPATH ];
  1854.     HWND hwndTitle;
  1855.  
  1856.  
  1857.     hwndTitle = WinWindowFromID( hwnd , FID_TITLEBAR);
  1858.  
  1859.  
  1860.     sprintf( auchTemp, "%s - %s", pszPgmName, pszFileName );
  1861.  
  1862.     WinSetWindowText(hwndTitle, auchTemp );
  1863.  
  1864.  
  1865. }
  1866.