home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mlelib.zip / mlelib / mle.cpp < prev    next >
C/C++ Source or Header  |  1993-06-07  |  22KB  |  882 lines

  1. /*************************************************************************
  2. *
  3. * filename        : mle.cpp    (implementation of class MLE)
  4. *
  5. * description    : manage a Multi-Line Entryfield
  6. *
  7. * methods        : MLE::Open
  8. *                  MLE::SaveFile
  9. *                  MLE::Close
  10. *                  MLE::SaveFileAs
  11. *                  MLE::SetSizeAndPosition
  12. *                  MLE::Touched
  13. *                  MLE::Cut, Copy, Paste, Clear
  14. *                  MLE::SetColor
  15. *                  MLE::GetText
  16. *                  MLE::Show
  17. *
  18. * functions        : CreateMLE            - create frame- and client-window
  19. *                  ProcMLE            - MLE message processing
  20. *                  FatalError        - display message and terminate
  21. *
  22. * APIs            : WinMessageBox                WinDestroyWindow
  23. *                   WinSetPointer                WinQuerySysPointer
  24. *                    WinInitialize                WinCreateMsgQueue
  25. *                    WinRegisterClass            WinDestroyMsgQueue
  26. *                    WinTerminate                WinCreateStdWindow
  27. *                    WinQueryWindowPos            WinSetWindowPos
  28. *                    WinShowWindow             DosPostEventSem
  29. *                    WinGetMsg                    WinDispatchMsg
  30. *                    DosEnterCritSec            DosExitCritSec
  31. *                   _beginthread                WinFileDlg
  32. *                   WinSendMsg                WinDefWindowProc
  33. *                      WinQueryWindowRect        WinSetFocus
  34. *                    WinSetWindowULong            WinQueryWindowULong
  35. *                    WinQueryWindowPtr            WinBeginPaint
  36. *                    WinFillRect                WinEndPaint
  37. *                    WinPostMsg
  38. *
  39. * Used Classes    : [none]
  40. *
  41. * copyright (C) 1993 Jörg Caumanns (caumanns@cs.tu-berlin.de)
  42. *
  43. *************************************************************************/#define INCL_WINWINDOWMGR
  44. #define INCL_WINMESSAGEMGR
  45. #define INCL_WINFRAMEMGR
  46. #define INCL_WINSYS
  47. #define INCL_WINMESSAGES
  48. #define INCL_WINPOINTERS
  49. #define INCL_WINMLE
  50. #define INCL_WININPUT
  51. #define INCL_WINSTDFILE
  52. #define INCL_WINACCELERATORS
  53. #define INCL_DOSPROCESS
  54. #define INCL_DOSSEMAPHORES
  55. #include <os2.h>
  56. #include <stdio.h>
  57. #include <string.h>
  58. #include <process.h>
  59. #include <stdarg.h>
  60. #include <mem.h>
  61.  
  62. #include "mle.h"
  63.  
  64. /*
  65. * offsets of window-instance data
  66. */
  67. #define QWL_FILE        0
  68. #define QWL_HWNDMLE        4
  69. #define QWL_THIS        8
  70.  
  71. /*
  72. * user-defined window messages
  73. */
  74. #define SM_SETFOCUS        WM_USER +1
  75. #define SM_SETCOLOR     WM_USER +2
  76. #define SM_LOADFILE     WM_USER +3
  77. #define SM_SAVEFILE     WM_USER +4
  78. #define SM_SAVEFILEAS     WM_USER +5
  79. #define SM_TOUCHED        WM_USER +6
  80. #define SM_MESSAGE        WM_USER +7
  81. #define SM_COPY            WM_USER +8
  82.  
  83. /*
  84. * global variables
  85. */
  86. static BOOL fRegistered = FALSE;    // register the windowclass only once
  87. static LONG cDiagonal    = 0;        // simulate FCF_SHELLPOSITION
  88.  
  89. /*
  90. * parameters needed for the window-creation
  91. */
  92. struct THREADPARAM    {
  93.     HWND    *phwnd;
  94.     HWND    *phwndClient;
  95.     CHAR    *pszFile;
  96.     ULONG    ulFlags;
  97.     HEV        hev;
  98.     MLE        *pMLE;
  99.     BOOL    *pfCreated;
  100.     };
  101.  
  102. /*
  103. * forward declarations
  104. */
  105. MRESULT    EXPENTRY procMLE(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  106. VOID FatalError(HWND hwnd, CHAR *msg);
  107. extern BOOL LoadFile(HWND hwnd, HWND hwndMLE, CHAR *pszFile);
  108. extern BOOL SaveFile(HWND hwnd, HWND hwndMLE, CHAR *pszFile);
  109. extern BOOL ValidateFilename(HWND hwnd, CHAR *pszFile);
  110. extern BOOL CopyTextToBuffer(HWND hwnd, HWND hwndMLE, CHAR **ppszBuffer);
  111.  
  112. /*
  113. * pointer to the active MLE
  114. */
  115. MLE *MLE::pmleActive = (MLE*)0;
  116.  
  117. /*************************************************************************
  118. *
  119. * Name    : FatalError
  120. *
  121. * Descr.: Display an error-message and terminate the window
  122. *
  123. * APIs    : WinMessageBox                WinDestroyWindow
  124. *
  125. * Param.: HWND    hwnd - Window to be destroyed
  126. *          CHAR    *msg - message
  127. *
  128. * Return: -
  129. *
  130. *************************************************************************/
  131. VOID FatalError(HWND hwnd, CHAR *msg)    {
  132.  
  133.     WinMessageBox(HWND_DESKTOP, hwnd, msg, "Fatal Error", 0, MB_CANCEL|MB_ERROR);
  134.     WinDestroyWindow(hwnd);
  135.     }
  136.  
  137. /*************************************************************************
  138. *
  139. * Name    : CreateMLE
  140. *
  141. * Descr.: create a window where the MLE will be mapped on
  142. *
  143. * APIs    : WinSetPointer                WinQuerySysPointer
  144. *          WinInitialize                WinCreateMsgQueue
  145. *          WinRegisterClass            WinDestroyMsgQueue
  146. *          WinTerminate                WinCreateStdWindow
  147. *          WinQueryWindowPos            WinSetWindowPos
  148. *          WinShowWindow             DosPostEventSem
  149. *          WinGetMsg                    WinDispatchMsg
  150. *          DosEnterCritSec            DosExitCritSec
  151. *
  152. * Param.: HWND *ptp->phwnd            new created window
  153. *          HWND *ptp->phwndClient    new window's client handle
  154. *          CHAR *ptp->pszFile        file to be loaded
  155. *          ULONG    ptp->ulFlags        flags
  156. *           HEV    ptp->hev            semaphore to restart main thread
  157. *          MLE  *ptp->pMLE            'this'
  158. *          BOOL *ptp->pfCreated        TRUE if window was created
  159. *
  160. * Return: -
  161. *
  162. *************************************************************************/
  163. VOID CreateMLE(THREADPARAM *ptp)    {
  164.     HAB   hab;
  165.     HMQ      hmq;
  166.     CHAR  szClassName[] = "EDITWIN";
  167.     ULONG fctlFrame = FCF_SIZEBORDER | FCF_MINMAX | FCF_TITLEBAR |
  168.                       FCF_TASKLIST | FCF_SYSMENU;
  169.     SWP   swp;
  170.  
  171.     /*
  172.     * change icon to clock
  173.     */
  174.     WinSetPointer(HWND_DESKTOP,
  175.                     WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
  176.     *ptp->pfCreated = FALSE;
  177.  
  178.     /*
  179.     * create message queue
  180.     */
  181.     if((hab = WinInitialize(0)) == NULLHANDLE)    {
  182.         DosPostEventSem(ptp->hev);
  183.         return;
  184.         }
  185.  
  186.     if((hmq = WinCreateMsgQueue(hab, 0)) == NULLHANDLE)    {
  187.         DosPostEventSem(ptp->hev);
  188.         return;
  189.         }
  190.  
  191.     /*
  192.     * register window class (only if not registered)
  193.     */
  194.     DosEnterCritSec();
  195.     if(!fRegistered)    {
  196.         fRegistered = TRUE;
  197.         DosExitCritSec();
  198.         if(!WinRegisterClass(hab,
  199.                              szClassName,
  200.                              (PFNWP)procMLE,
  201.                              CS_SIZEREDRAW,
  202.                              32L))    {
  203.             WinDestroyMsgQueue(hmq);
  204.             WinTerminate(hab);
  205.             DosPostEventSem(ptp->hev);
  206.             return;
  207.             }
  208.         }
  209.     else
  210.         DosExitCritSec();
  211.  
  212.     /*
  213.     * create frame window
  214.     */
  215.     CHAR *pszTitle = (ptp->pszFile)? ptp->pszFile : "Untitled";
  216.  
  217.     HWND hwndFrame;
  218.     FRAMECDATA fcdata;
  219.     fcdata.cb            = sizeof(FRAMECDATA);
  220.     fcdata.flCreateFlags = fctlFrame;
  221.     fcdata.hmodResources = (HMODULE)NULL;
  222.     fcdata.idResources   = 0;
  223.     if((*ptp->phwnd = (HWND)WinCreateWindow(HWND_DESKTOP,
  224.                                           WC_FRAME,
  225.                                           pszTitle,
  226.                                           0,
  227.                                           0, 0, 0, 0,
  228.                                           NULLHANDLE,
  229.                                           HWND_TOP,
  230.                                           1,
  231.                                           &fcdata,
  232.                                           NULL)) == NULLHANDLE)    {
  233.  
  234.         WinDestroyMsgQueue(hmq);
  235.         WinTerminate(hab);
  236.         DosPostEventSem(ptp->hev);
  237.         return;
  238.         }
  239.  
  240.     /*
  241.     * create client window
  242.     */
  243.     if((*ptp->phwndClient = (HWND)WinCreateWindow(*ptp->phwnd,
  244.                                           szClassName,
  245.                                           "",
  246.                                           0,
  247.                                           0, 0, 0, 0,
  248.                                           *ptp->phwnd,
  249.                                           HWND_BOTTOM,
  250.                                           FID_CLIENT,
  251.                                           (VOID*)ptp->pMLE,
  252.                                           NULL)) == NULLHANDLE)    {
  253.  
  254.         WinDestroyMsgQueue(hmq);
  255.         WinTerminate(hab);
  256.         DosPostEventSem(ptp->hev);
  257.         return;
  258.         }
  259.  
  260.     /*
  261.     * post semaphore to free main-thread
  262.     */
  263.     *ptp->pfCreated = TRUE;
  264.     DosPostEventSem(ptp->hev);
  265.  
  266.     /*
  267.     * show windows
  268.     */
  269.     ULONG fl = SWP_SIZE | SWP_MOVE;
  270.     if(ptp->ulFlags & MLE_MAXIMIZE)
  271.         fl |= SWP_MAXIMIZE;
  272.     if(ptp->ulFlags & MLE_MINIMIZE)
  273.         fl |= SWP_MINIMIZE;
  274.     WinQueryWindowPos(HWND_DESKTOP, &swp);
  275.     if(((cDiagonal * MLE_DISTANCE) > (swp.x + swp.cx * MLE_XSIZE / 100)) ||
  276.        ((cDiagonal * MLE_DISTANCE) > (swp.y + swp.cy * MLE_YSIZE / 100)))
  277.          cDiagonal = 0;
  278.     WinSetWindowPos(*ptp->phwnd,
  279.                     HWND_TOP,
  280.                     cDiagonal * MLE_DISTANCE,
  281.                     swp.cy - cDiagonal * MLE_DISTANCE - swp.cy *MLE_YSIZE / 100,
  282.                     swp.cx * MLE_XSIZE / 100,
  283.                     swp.cy * MLE_YSIZE / 100,
  284.                     fl);
  285.     cDiagonal++;
  286.     WinQueryWindowPos(*ptp->phwnd, &swp);
  287.     WinSetWindowPos(*ptp->phwndClient, HWND_TOP,
  288.                     WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER),
  289.                     WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER) -1,
  290.                     swp.cx - WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER)*2,
  291.                     swp.cy - WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)-21,
  292.                     SWP_MOVE | SWP_SIZE);
  293.     if(!(ptp->ulFlags & MLE_HIDE))    {
  294.         WinShowWindow(*ptp->phwnd, TRUE);
  295.         WinShowWindow(*ptp->phwndClient, TRUE);
  296.         }
  297.  
  298.     /*
  299.     * Message-Loop
  300.     */
  301.     QMSG  qmsg;
  302.     while(WinGetMsg(hmq, (PQMSG)&qmsg, NULLHANDLE, 0, 0))
  303.         WinDispatchMsg(hmq, (PQMSG)&qmsg);
  304.  
  305.     /*
  306.     * Termination
  307.     */
  308.     delete ptp;
  309.     WinDestroyMsgQueue(hmq);
  310.     WinTerminate(hab);
  311.     return;
  312.     }
  313.  
  314.  
  315. /*************************************************************************
  316. *
  317. * Name    : MLE::Open
  318. *
  319. * Descr.: create an MLE-window and load a file to it.
  320. *
  321. * APIs    : _beginthread            WinFileDlg
  322. *
  323. * Param.: CHAR  *pszFile        file to be loaded;
  324. *                                if NULL: flags & MLE_NEWFILE -> empty MLE
  325. *                                         otherwise -> "open"-dialogbox
  326. *          ULONG    ulFlags            flags:
  327. *                                  MLE_HIDE       : create MLE invisible
  328. *                                 MLE_MAXIMIZE : create with max. size
  329. *                                  MLE_MINIMIZE : create with min. size
  330. *                                  MLE_NEWFILE  : see above
  331. *
  332. * Return: TRUE if window has been created
  333. *
  334. *************************************************************************/
  335. BOOL MLE::OpenFile(CHAR *pszFile, ULONG ulf)    {
  336.     THREADPARAM *ptp = new THREADPARAM;
  337.     BOOL fCreated;
  338.  
  339.     /*
  340.     * set instance variables
  341.     */
  342.     if(pszFile != NULL)    {
  343.         pszLoadedFile = new(CHAR[strlen(pszFile)+1]);
  344.         strcpy(pszLoadedFile, pszFile);
  345.         }
  346.     ulFlags = ulf;
  347.  
  348.     /*
  349.     * "open"-dialogbox, if no filename given and MLE_NEWFILE not set
  350.     */
  351.     FILEDLG    fdFiledlg;
  352.     if(!pszFile && !(ulf & MLE_NEWFILE)) {
  353.         memset(&fdFiledlg, 0, sizeof(FILEDLG));
  354.         fdFiledlg.cbSize    = sizeof(FILEDLG);
  355.         fdFiledlg.fl        = FDS_HELPBUTTON | FDS_OPEN_DIALOG;
  356.         fdFiledlg.pszTitle    = "Open File";
  357.         strcpy(fdFiledlg.szFullFile, "*.*");
  358.         WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fdFiledlg);
  359.         if(fdFiledlg.lReturn == DID_OK)    {
  360.             pszLoadedFile = new(CHAR[strlen(fdFiledlg.szFullFile)+1]);
  361.             strcpy(pszLoadedFile, fdFiledlg.szFullFile);
  362.             }
  363.         else
  364.             return FALSE;
  365.         }
  366.  
  367.     /*
  368.     * Create event semaphore that will be posted by the create-thread
  369.     */
  370.     HEV hev;
  371.     if(DosCreateEventSem(NULL, &hev, 0, 0))
  372.         return FALSE;
  373.  
  374.     /*
  375.     * set thread parameters and start create-thread
  376.     */
  377.     ptp->phwnd        = &hwnd;
  378.     ptp->phwndClient= &hwndClient;
  379.     ptp->pszFile    = pszLoadedFile;
  380.     ptp->ulFlags    = ulf;
  381.     ptp->hev        = hev;
  382.     ptp->pMLE        = this;
  383.     ptp->pfCreated    = &fCreated;
  384.  
  385.     _beginthread((void(*)(void*))CreateMLE, 8192, (void *)ptp);
  386.  
  387.     /*
  388.     * wait till end of MLE-creation
  389.     */
  390.     DosWaitEventSem(hev, 120000);
  391.  
  392.     return fCreated;
  393.     }
  394.  
  395.  
  396. /*************************************************************************
  397. *
  398. * Name    : MLE::Close
  399. *
  400. * Descr.: close the MLE. If the contents have changed ask the user if
  401. *          these changes should be copied back to the file.
  402. *
  403. * APIs    : WinPostMsg
  404. *
  405. * Param.: [none]
  406. *
  407. * Return: fSuccess
  408. *
  409. *************************************************************************/
  410. BOOL MLE::CloseFile(VOID)    {
  411.     if(fAlive)
  412.         WinSendMsg(hwndClient, WM_CLOSE, MPVOID, MPVOID);
  413.     return TRUE;
  414.     }
  415.  
  416.  
  417. /*************************************************************************
  418. *
  419. * Name    : MLE::SaveFile
  420. *
  421. * Descr.: save the contents of the MLE to the file that was loaded to
  422. *          the MLE.
  423. *
  424. * APIs    : WinPostMsg
  425. *
  426. * Param.: [none]
  427. *
  428. * Return: fSuccess
  429. *
  430. *************************************************************************/
  431. BOOL MLE::SaveFile(VOID)    {
  432.     if(!fAlive)
  433.         return TRUE;
  434.  
  435.     return (BOOL)WinSendMsg(hwndClient, SM_SAVEFILE, MPVOID, MPVOID);
  436.     }
  437.  
  438.  
  439. /*************************************************************************
  440. *
  441. * Name    : MLE::SaveFileAs
  442. *
  443. * Descr.: save the contents of the MLE to another file than it was
  444. *          loaded from.
  445. *
  446. * APIs    : WinPostMsg
  447. *
  448. * Param.: [none]
  449. *
  450. * Return: fSuccess
  451. *
  452. *************************************************************************/
  453. BOOL MLE::SaveFileAs(VOID)    {
  454.     if(!fAlive)
  455.         return TRUE;
  456.  
  457.     return (BOOL)WinSendMsg(hwndClient, SM_SAVEFILEAS, MPVOID, MPVOID);
  458.     }
  459.  
  460. /*************************************************************************
  461. *
  462. * Name    : MLE::Resize
  463. *
  464. * Descr.: change size and/or position of the MLE-window
  465. *
  466. * APIs    : WinSetWindowPos
  467. *
  468. * Param.: INT    x, y    - lower left corner
  469. *         INT    cx, cy    - size
  470. *          ULONG fl        - change flag
  471. *
  472. * Return: fSuccess
  473. *
  474. *************************************************************************/
  475. VOID MLE::SetSizeAndPosition(INT x, INT y, INT cx, INT cy, ULONG fl)    {
  476.     ULONG flag = SWP_SHOW;
  477.  
  478.     if(fAlive)    {
  479.         if(fl & MLE_SIZEPOS_SIZE)
  480.             flag |= SWP_SIZE;
  481.         if(fl & MLE_SIZEPOS_POS)
  482.             flag |= SWP_MOVE;
  483.         if(fl & MLE_SIZEPOS_MAX)
  484.             flag |= SWP_MAXIMIZE;
  485.         if(fl & MLE_SIZEPOS_MIN)
  486.             flag |= SWP_MINIMIZE;
  487.  
  488.         WinSetWindowPos(hwnd, HWND_TOP, x, y, cx, cy, flag);
  489.         }
  490.     }
  491.  
  492. /*************************************************************************
  493. *
  494. * Name    : MLE::SetColor
  495. *
  496. * Descr.: change forground and background color of an MLE-window
  497. *
  498. * APIs    : WinPostMsg
  499. *
  500. * Param.: LONG  clrForground
  501. *          LONG    clrBackground
  502. *
  503. * Return: fSuccess
  504. *
  505. *************************************************************************/
  506. VOID MLE::SetColor(LONG clrF, LONG clrB)    {
  507.  
  508.     if(fAlive)    {
  509.         clrForeground = clrF;
  510.         clrBackground = clrB;
  511.         WinPostMsg(hwndClient, SM_SETCOLOR, MPFROMLONG(clrF), MPFROMLONG(clrB));
  512.         }
  513.     }
  514.  
  515. /*************************************************************************
  516. *
  517. * Name    : MLE::Touched
  518. *
  519. * Descr.: Check if window was touched
  520. *
  521. * APIs    : WinSendMsg
  522. *
  523. * Param.: [none]
  524. *
  525. * Return: fTouched
  526. *
  527. *************************************************************************/
  528. BOOL MLE::Touched(VOID)    {
  529.     if(!fAlive)
  530.         return FALSE;
  531.  
  532.     if(fTouched)
  533.         return TRUE;
  534.  
  535.     return (BOOL)WinSendMsg(hwndClient, SM_TOUCHED, MPVOID, MPVOID);
  536.     }
  537.  
  538.  
  539. /*************************************************************************
  540. *
  541. * Names    : MLE::Cut, MLE::Copy, MLE::Paste, MLE::Clear
  542. *
  543. * Descr.: Move text between MLE and clipboard
  544. *
  545. * APIs    : WinSendMsg
  546. *
  547. * Param.: [none]
  548. *
  549. * Return: -
  550. *
  551. *************************************************************************/
  552. VOID MLE::Cut(VOID)    {
  553.     WinSendMsg(hwndClient, SM_MESSAGE, MPFROMLONG(MLM_CUT),   MPVOID);
  554.     }
  555.  
  556. VOID MLE::Copy(VOID)    {
  557.     WinSendMsg(hwndClient, SM_MESSAGE, MPFROMLONG(MLM_COPY),  MPVOID);
  558.     }
  559.  
  560. VOID MLE::Paste(VOID)    {
  561.     WinSendMsg(hwndClient, SM_MESSAGE, MPFROMLONG(MLM_PASTE), MPVOID);
  562.     }
  563.  
  564. VOID MLE::Clear(VOID)    {
  565.     WinSendMsg(hwndClient, SM_MESSAGE, MPFROMLONG(MLM_CLEAR), MPVOID);
  566.     }
  567.  
  568.  
  569. /*************************************************************************
  570. *
  571. * Name    : MLE::GetText
  572. *
  573. * Descr.: Copy the contents of the MLE to a buffer
  574. *
  575. * APIs    : WinSendMsg
  576. *
  577. * Param.: CHAR **ppszBuffer    - pointer to buffer (buffer will be allocated
  578. *                              by this method)
  579. *
  580. * Return: fSuccess
  581. *
  582. *************************************************************************/
  583. BOOL MLE::GetText(CHAR **ppszBuffer)    {
  584.     if(!fAlive)
  585.         return TRUE;
  586.  
  587.     return (BOOL)WinSendMsg(hwndClient,
  588.                             SM_COPY,
  589.                             MPFROMP((VOID*)ppszBuffer),
  590.                             MPVOID);
  591.     }
  592.  
  593.  
  594.  
  595. /*************************************************************************
  596. *
  597. * Name    : MLE::Print
  598. *
  599. * Descr.: Insert text at the current cursor position
  600. *
  601. * APIs    : WinSendMsg
  602. *
  603. * Param.: see 'printf()'
  604. *
  605. * Return: -
  606. *
  607. *************************************************************************/
  608. VOID MLE::Print(CHAR *pszMask, ...)    {
  609.     CHAR szText[2048];
  610.  
  611.     /*
  612.     * evaluate argument list
  613.     */
  614.     va_list ap;
  615.     va_start(ap, pszMask);
  616.     vsprintf(szText, pszMask, ap);
  617.     va_end(ap);
  618.  
  619.     /*
  620.     * print text
  621.     */
  622.     WinSendMsg(hwndClient, SM_MESSAGE, MPFROMLONG(MLM_INSERT),
  623.                                                     MPFROMP((VOID*)szText));
  624.     }
  625.  
  626.  
  627. /*************************************************************************
  628. *
  629. * Name    : MLE::Show
  630. *
  631. * Descr.: Show/Hide the MLE
  632. *
  633. * APIs    : WinShowWindow
  634. *
  635. * Param.: BOOL f    - TRUE  -> show MLE
  636. *                      FALSE -> hide MLE
  637. *
  638. * Return: -
  639. *
  640. *************************************************************************/
  641. VOID MLE::Show(BOOL f)    {
  642.  
  643.     WinShowWindow(hwnd, f);
  644.     WinShowWindow(hwndClient, f);
  645.     }
  646.  
  647.  
  648. /*************************************************************************
  649. *
  650. * Name    : MRESULT EXPENTRY procMLE()
  651. *
  652. * Descr.: MLE message processing
  653. *
  654. * APIs    : WinSendMsg                WinDefWindowProc
  655. *            WinCreateWindow            WinQueryWindowRect
  656. *          WinSetWindowULong            WinQueryWindowULong
  657. *          WinQueryWindowPtr            WinBeginPaint
  658. *          WinFillRect                WinEndPaint
  659. *          WinSetWindowPos            WinSetFocus
  660. *          WinPostMsg                WinFileDlg
  661. *          WinSetWindowPtr            WinMessageBox
  662. *
  663. * Param.: HWND     hwnd        - window handle
  664. *          ULONG  msg        - message identifier
  665. *          MPARAM mp1, mp2   - message parameters
  666. *
  667. * Return: fQuit
  668. *
  669. *************************************************************************/
  670. MRESULT    EXPENTRY procMLE(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)    {
  671.     HPS   hps;
  672.     RECTL rcl;
  673.     HWND  hwndMLE;
  674.     CHAR  *pszFile;
  675.     MLE   *pmle;
  676.     SHORT sResponce;
  677.     CHAR  szQuery[256];
  678.     LONG  clrF, clrB;
  679.  
  680.     switch(msg)    {
  681.  
  682.         /*
  683.         * put an MLE on top of the client area
  684.         */
  685.         case WM_CREATE:    /* Fenster-Initialisierung */
  686.             WinQueryWindowRect(hwnd, (PRECTL)&rcl);
  687.             hwndMLE = WinCreateWindow(hwnd, WC_MLE, (PSZ)NULL,
  688.                               MLS_HSCROLL | MLS_VSCROLL | WS_VISIBLE,
  689.                               (SHORT)rcl.xLeft, (SHORT)rcl.yBottom,
  690.                               (SHORT)rcl.xRight, (SHORT)rcl.yTop,
  691.                               hwnd, HWND_TOP, 0, NULL, NULL);
  692.             if(!hwndMLE)
  693.                 return (MRESULT)TRUE;    /* Programm-Abbruch */
  694.  
  695.             WinSetWindowULong(hwnd, QWL_HWNDMLE, (ULONG)hwndMLE);
  696.  
  697.             /*
  698.             * initialize MLE
  699.             */
  700.             pmle = (MLE*)mp1;
  701.             WinSetWindowPtr(hwnd, QWL_THIS, (VOID *)pmle);
  702.             pszFile = pmle->LoadedFile();
  703.             WinSetWindowPtr(hwnd, QWL_FILE, (VOID *)pszFile);
  704.             pmle->GetColor(&clrF, &clrB);
  705.             WinSendMsg(hwndMLE, MLM_SETTEXTCOLOR,
  706.                                             MPFROMLONG(clrF), NULL);
  707.             WinSendMsg(hwndMLE, MLM_SETBACKCOLOR,
  708.                                             MPFROMLONG(clrB), NULL);
  709.             WinSendMsg(hwndMLE, MLM_RESETUNDO, NULL, NULL);
  710.  
  711.             WinPostMsg(hwnd, SM_SETFOCUS, MPVOID, MPVOID);
  712.             WinPostMsg(hwnd, SM_LOADFILE, MPVOID, MPVOID);
  713.             break;
  714.  
  715.         /*
  716.         * repaint the client area
  717.         */
  718.         case WM_PAINT:
  719.             hps = WinBeginPaint(hwnd, (HPS)NULL, &rcl);
  720.             WinFillRect(hps, &rcl, CLR_BACKGROUND);
  721.             WinEndPaint(hps);
  722.             break;
  723.  
  724.         /*
  725.         * resize the MLE
  726.         */
  727.         case WM_SIZE:
  728.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  729.             WinSetWindowPos(hwndMLE, HWND_TOP, 0, 0, SHORT1FROMMP(mp2),
  730.                                             SHORT2FROMMP(mp2), SWP_SIZE);
  731.             break;
  732.  
  733.         /*
  734.         * MLE got the focus
  735.         */
  736.         case WM_ACTIVATE:
  737.             if(SHORT1FROMMP(mp1))    {
  738.                 pmle = (MLE*)WinQueryWindowPtr(hwnd, QWL_THIS);
  739.                 pmle->Activate();
  740.                 }
  741.             break;
  742.  
  743.         case WM_SETFOCUS:
  744.             if(SHORT1FROMMP(mp1))    {
  745.                 hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  746.                 WinPostMsg(hwnd, SM_SETFOCUS, NULL, NULL);
  747.                 }
  748.             break;
  749.  
  750.         case SM_SETFOCUS:
  751.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  752.             WinSetFocus(HWND_DESKTOP, hwndMLE);
  753.             break;
  754.  
  755.         /*
  756.         * Send a message to the MLE
  757.         *   mp1        : message-ID
  758.         *   mp2        : first message parameter
  759.         *    return  : message result
  760.         */
  761.         case SM_MESSAGE:
  762.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  763.             return WinSendMsg(hwndMLE, (ULONG)LONGFROMMP(mp1), mp2, MPVOID);
  764.  
  765.         /*
  766.         * change foreground and background color
  767.         *   mp1        : foreground color
  768.         *    mp2        : background color
  769.         *    return    : -
  770.         */
  771.         case SM_SETCOLOR:
  772.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  773.             WinSendMsg(hwndMLE, MLM_SETTEXTCOLOR, mp1, MPVOID);
  774.             WinSendMsg(hwndMLE, MLM_SETBACKCOLOR, mp2, MPVOID);
  775.             break;
  776.  
  777.         /*
  778.         * check if window contents changed
  779.         *    return    : TRUE if contents changed, else FALSE
  780.         */
  781.         case SM_TOUCHED:
  782.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  783.             return WinSendMsg(hwndMLE, MLM_QUERYCHANGED, MPVOID, MPVOID);
  784.  
  785.         /*
  786.         * copy MLE-contents to a buffer
  787.         *    mp1        : buffer address
  788.         *    mp2        : -
  789.         *    return    : TRUE if text was copied
  790.         */
  791.         case SM_COPY:
  792.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  793.             return (MRESULT)CopyTextToBuffer(hwnd, hwndMLE, (CHAR**)(mp1));
  794.  
  795.         /*
  796.         * load a file to the MLE
  797.         */
  798.         case SM_LOADFILE:
  799.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  800.             pszFile = (CHAR*)WinQueryWindowPtr(hwnd, QWL_FILE);
  801.             if(pszFile)
  802.                 LoadFile(WinQueryWindow(hwnd, QW_PARENT), hwndMLE, pszFile);
  803.             break;
  804.  
  805.         /*
  806.         * save MLE contents (if it changed)
  807.         * if no filename was given, SM_SAVEFILEAS is called implicit.
  808.         */
  809.         case SM_SAVEFILE:
  810.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  811.             pszFile = (CHAR*)WinQueryWindowPtr(hwnd, QWL_FILE);
  812.             if(pszFile)    {
  813.                 if(SaveFile(WinQueryWindow(hwnd, QW_PARENT),
  814.                             hwndMLE,
  815.                             pszFile))    {
  816.                     pmle = (MLE*)WinQueryWindowPtr(hwnd, QWL_THIS);
  817.                     pmle->TouchFile(FALSE);
  818.                     return (MRESULT)TRUE;
  819.                     }
  820.                 return (MRESULT)FALSE;
  821.                 }
  822.  
  823.         /*
  824.         * ask for a filename and copy the cntents of the MLE to this file
  825.         */
  826.         case SM_SAVEFILEAS:
  827.             hwndMLE = WinQueryWindowULong(hwnd, QWL_HWNDMLE);
  828.  
  829.             /*
  830.             * display "save as"-dialogbox
  831.             */
  832.             FILEDLG    fdFiledlg;
  833.             memset(&fdFiledlg, 0, sizeof(FILEDLG));
  834.             fdFiledlg.cbSize    = sizeof(FILEDLG);
  835.             fdFiledlg.fl        = FDS_HELPBUTTON | FDS_CENTER | FDS_SAVEAS_DIALOG;
  836.             fdFiledlg.pszTitle    = "Save File As...";
  837.             strcpy(fdFiledlg.szFullFile, "*.*");
  838.             WinFileDlg(HWND_DESKTOP, hwnd, &fdFiledlg);
  839.             if(fdFiledlg.lReturn == DID_OK)    {
  840.                 /*
  841.                 * check if file already exists (ask if overwrite)
  842.                 */
  843.                 if(ValidateFilename(WinQueryWindow(hwnd, QW_PARENT),
  844.                                                         fdFiledlg.szFullFile))
  845.                     if(SaveFile(WinQueryWindow(hwnd, QW_PARENT),
  846.                                 hwndMLE,
  847.                                 fdFiledlg.szFullFile))    {
  848.                         pmle = (MLE*)WinQueryWindowPtr(hwnd, QWL_THIS);
  849.                         pmle->TouchFile(FALSE);
  850.                         return (MRESULT)TRUE;
  851.                         }
  852.                 }
  853.             return (MRESULT)FALSE;
  854.  
  855.         /*
  856.         * close the MLE (ask the user if contents should be saved)
  857.         */
  858.         case WM_CLOSE:
  859.             pmle = (MLE*)WinQueryWindowPtr(hwnd, QWL_THIS);
  860.             pszFile = (CHAR*)WinQueryWindowPtr(hwnd, QWL_FILE);
  861.             if(pmle->Touched())        {
  862.                 if(!pszFile)
  863.                     pszFile = "[Untitled]";
  864.                 sprintf(szQuery, "%s has been changed! Save it?", pszFile);
  865.                 sResponce = WinMessageBox(HWND_DESKTOP, hwnd, szQuery,
  866.                                     "Close File", 0, MB_QUERY | MB_YESNO);
  867.  
  868.                 if(sResponce == MBID_YES)
  869.                     pmle->SaveFile();
  870.                 }
  871.  
  872.             pmle->SetClosed();
  873.             return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  874.  
  875.         default:
  876.             return(WinDefWindowProc(hwnd, msg, mp1, mp2));
  877.         }
  878.     return((MRESULT)NULL);
  879.     }
  880.  
  881.  
  882.