home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 08 / dflat5 / editbox.c < prev    next >
Text File  |  1991-06-23  |  31KB  |  1,252 lines

  1. /* ------------- editbox.c ------------ */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include <ctype.h>
  8. #include "dflat.h"
  9.  
  10. #define EDITBUFFERLENGTH  4096
  11. #define ENTRYBUFFERLENGTH 1024
  12. #define GROWLENGTH        1024
  13.  
  14.  
  15. #define EditBufLen(wnd) (isMultiLine(wnd) ? EDITBUFFERLENGTH : ENTRYBUFFERLENGTH)
  16. #define WndCol (wnd->CurrCol-wnd->wleft)
  17.  
  18. #define CurrChar (TextLine(wnd, wnd->CurrLine)+wnd->CurrCol)
  19.  
  20. static void PasteText(WINDOW, char *, int);
  21. static void SaveDeletedText(WINDOW, char *, int);
  22. static void Forward(WINDOW);
  23. static void Backward(WINDOW);
  24. static void End(WINDOW);
  25. static void Home(WINDOW);
  26. static void Downward(WINDOW);
  27. static void Upward(WINDOW);
  28. static void StickEnd(WINDOW);
  29. static void UpLine(WINDOW);
  30. static void DownLine(WINDOW);
  31. static void NextWord(WINDOW);
  32. static void PrevWord(WINDOW);
  33. static void ResetEditBox(WINDOW);
  34. static void AddTextPointers(WINDOW, int, int);
  35. static int TextLineNumber(WINDOW, char *);
  36. #ifdef INCLUDE_DIALOG_BOXES
  37. static void SearchTextBox(WINDOW);
  38. static void ReplaceTextBox(WINDOW);
  39. static void SearchNext(WINDOW, int);
  40. #endif
  41. #ifdef INCLUDE_MULTILINE
  42. #define SetLinePointer(wnd, ln)    (wnd->CurrLine = ln)
  43. #else
  44. #define SetLinePointer(wnd, ln) (wnd->CurrLine = 0)
  45. #endif
  46.  
  47. static int KeyBoardMarking, ButtonDown;
  48. int TextMarking;
  49. static int bx, by;
  50.  
  51. char *Clipboard;
  52. int ClipboardLength;
  53.  
  54. int EditBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  55. {
  56.     int rtn;
  57.     static int py = -1;
  58.     int kx = (int) p1 - GetLeft(wnd);
  59.     int ky = (int) p2 - GetTop(wnd);
  60.     int c;
  61.     RECT rc;
  62.     char *lp;
  63.     int len;
  64.     int    mx;
  65.     int    my;
  66.     char *currchar = CurrChar;
  67.     int PassOn = FALSE;
  68.  
  69.     rc = ClientRect(wnd);
  70.     switch (msg)    {
  71.         case CREATE_WINDOW:
  72.             rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  73.             wnd->text = calloc(1, EditBufLen(wnd)+1);
  74.             wnd->textlen = EditBufLen(wnd);
  75.             ResetEditBox(wnd);
  76.             return rtn;
  77.         case ADDTEXT:
  78.             rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  79.             currchar = CurrChar;
  80.             if (!isMultiLine(wnd))    {
  81.                 wnd->CurrLine = 0;
  82.                 wnd->CurrCol = strlen((char *)p1);
  83.                 if (wnd->CurrCol >= ClientWidth(wnd))    {
  84.                     wnd->wleft = wnd->CurrCol - ClientWidth(wnd);
  85.                     wnd->CurrCol -= wnd->wleft;
  86.                 }
  87.                 wnd->BlkEndCol = wnd->CurrCol;
  88.                 PostMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  89.             }
  90.             BuildTextPointers(wnd);
  91.             return rtn;
  92.         case SETTEXT:
  93.             rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  94.             wnd->CurrLine = 0;
  95.             return rtn;
  96.         case CLEARTEXT:
  97.             ResetEditBox(wnd);
  98.             ClearTextPointers(wnd);
  99.             break;
  100.         case KEYBOARD_CURSOR:
  101.             rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  102.             if (wnd == inFocus)    {
  103.                 if (!CharInView(wnd, (int)p1+BorderAdj(wnd),
  104.                         (int)p2+TopBorderAdj(wnd)))
  105.                     SendMessage(NULLWND, HIDE_CURSOR, 0, 0);
  106.                 else 
  107.                     SendMessage(NULLWND, SHOW_CURSOR,
  108.                         GetCommandToggle(MainMenu, ID_INSERT), 0);
  109.             }
  110.             return rtn;
  111.         case EB_GETTEXT:    {
  112.             char *cp1 = (char *)p1;
  113.             char *cp2 = wnd->text;
  114.             while (p2-- && *cp2 && *cp2 != '\n')
  115.                 *cp1++ = *cp2++;
  116.             *cp1 = '\0';
  117.             return TRUE;
  118.         }
  119.         case EB_PUTTEXT:
  120.             SendMessage(wnd, CLEARTEXT, 0, 0);
  121.             SendMessage(wnd, ADDTEXT, p1, p2);
  122.             return TRUE;
  123.         case SETFOCUS:
  124.             rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  125.             if (p1)    {
  126.                 SendMessage(NULLWND, SHOW_CURSOR, GetCommandToggle(MainMenu, ID_INSERT), 0);
  127.                 SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  128.             }
  129.             else
  130.                 SendMessage(NULLWND, HIDE_CURSOR, 0, 0);
  131.             return rtn;
  132. #ifdef INCLUDE_MULTILINE
  133.         case SHIFT_CHANGED:
  134.             if (!((int)p1 & (LEFTSHIFT | RIGHTSHIFT)) && KeyBoardMarking)    {
  135.                 SendMessage(wnd, BUTTON_RELEASED, 0, 0);
  136.                 KeyBoardMarking = FALSE;
  137.             }
  138.             break;
  139.         case DOUBLE_CLICK:
  140.             if (KeyBoardMarking)
  141.                 return TRUE;
  142.             break;
  143. #endif
  144.         case LEFT_BUTTON:
  145. #ifdef INCLUDE_SCROLLBARS
  146.             if (HScrolling || VScrolling)
  147.                 break;
  148. #endif
  149. #ifdef INCLUDE_MULTILINE
  150.             if (KeyBoardMarking || TextMarking)
  151.                 return TRUE;
  152. #endif
  153. #ifdef INCLUDE_SYSTEM_MENUS
  154.             if (WindowMoving || WindowSizing)
  155.                 break;
  156. #endif
  157.             if (!InsideRect(p1, p2, rc))
  158.                 break;
  159.  
  160.             mx = (int) p1 - GetClientLeft(wnd);
  161.             my = (int) p2 - GetClientTop(wnd);
  162.  
  163. #ifdef INCLUDE_MULTILINE
  164.             if (isMultiLine(wnd))    {
  165.  
  166.                 if (BlockMarked(wnd))    {
  167.                     ClearBlock(wnd);
  168.                     SendMessage(wnd, PAINT, 0, 0);
  169.                 }
  170.  
  171.                 if (wnd->wlines)    {
  172.                     if (my > wnd->wlines-1)
  173.                         break;
  174.                     lp = TextLine(wnd, my+wnd->wtop);
  175.                     len = (int) (strchr(lp, '\n') - lp);
  176.                     mx = min(mx, len);
  177.                     if (mx < wnd->wleft)    {
  178.                         mx = 0;
  179.                         SendMessage(wnd, KEYBOARD, HOME, 0);
  180.                     }
  181.                     ButtonDown = TRUE;
  182.                     bx = mx;
  183.                     by = my;
  184.                 }
  185.                 else
  186.                     mx = my = 0;
  187.  
  188.                 wnd->WndRow = my;
  189.                 SetLinePointer(wnd, my+wnd->wtop);
  190.             }
  191. #endif
  192.             if (isMultiLine(wnd) || !BlockMarked(wnd))
  193.                 wnd->CurrCol = mx+wnd->wleft;
  194.             PostMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  195.             return TRUE;
  196. #ifdef INCLUDE_MULTILINE
  197.         case MOUSE_MOVED:
  198.             mx = (int) p1 - GetClientLeft(wnd);
  199.             my = (int) p2 - GetClientTop(wnd);
  200.             if (my > wnd->wlines-1)
  201.                 break;
  202.  
  203.             if (ButtonDown)    {
  204.                 SetAnchor(wnd, bx+wnd->wleft, by+wnd->wtop);
  205.                 TextMarking = TRUE;
  206.                 SendMessage(wnd, CAPTURE_MOUSE, TRUE, 0);
  207.                 ButtonDown = FALSE;
  208.             }
  209.  
  210.             if (TextMarking
  211. #ifdef INCLUDE_SYSTEM_MENUS
  212.                     && !(WindowMoving || WindowSizing)
  213. #endif
  214.                             )    {
  215.                 int ptop;
  216.                 int pbot;
  217.                 char *lp;
  218.                 int len;
  219.                 int y;
  220.                 int bbl, bel;
  221.                 RECT rc;
  222.                 rc = ClientRect(wnd);
  223.  
  224.                 if (!InsideRect(p1, p2, rc))      {
  225.                     int hs = -1, sc = -1;
  226.                     if (p1 < GetClientLeft(wnd))    {
  227.                         hs = FALSE;
  228.                         p1 = GetClientLeft(wnd);
  229.                     }
  230.                     if (p1 > GetClientRight(wnd))    {
  231.                         hs = TRUE;
  232.                         p1 = GetClientRight(wnd);
  233.                     }
  234.                     if (p2 < GetClientTop(wnd))    {
  235.                         sc = FALSE;
  236.                         p2 = GetClientTop(wnd);
  237.                     }
  238.                     if (p2 > GetClientBottom(wnd))    {
  239.                         sc = TRUE;
  240.                         p2 = GetClientBottom(wnd);
  241.                     }
  242.                     SendMessage(NULLWND, MOUSE_CURSOR, p1, p2);
  243.                     if (sc != -1)
  244.                         SendMessage(wnd, SCROLL, sc, 0);
  245.                     if (hs != -1)
  246.                         SendMessage(wnd, HORIZSCROLL, hs, 0);
  247.                     mx = (int) p1 - GetClientLeft(wnd);
  248.                     my = (int) p2 - GetClientTop(wnd);
  249.                 }
  250.  
  251.                 ptop = min(wnd->BlkBegLine, wnd->BlkEndLine);
  252.                 pbot = max(wnd->BlkBegLine, wnd->BlkEndLine);
  253.  
  254.                 lp = TextLine(wnd, wnd->wtop+my);
  255.                 len = (int) (strchr(lp, '\n') - lp);
  256.                 mx = min(mx, len-wnd->wleft);
  257.  
  258.                 wnd->BlkEndCol = mx+wnd->wleft;
  259.                 wnd->BlkEndLine = my+wnd->wtop;
  260.  
  261.                 bbl = min(wnd->BlkBegLine, wnd->BlkEndLine);
  262.                 bel = max(wnd->BlkBegLine, wnd->BlkEndLine);
  263.  
  264.                 while (ptop < bbl)    {
  265.                     WriteTextLine(wnd, NULL, ptop, FALSE);
  266.                     ptop++;
  267.                 }
  268.                 for (y = bbl; y <= bel; y++)
  269.                     WriteTextLine(wnd, NULL, y, FALSE);
  270.                 while (pbot > bel)    {
  271.                     WriteTextLine(wnd, NULL, pbot, FALSE);
  272.                     --pbot;
  273.                 }
  274.                 return TRUE;
  275.             }
  276.             break;
  277.         case BUTTON_RELEASED:
  278.             if (!isMultiLine(wnd))
  279.                 break;
  280.             ButtonDown = FALSE;
  281. #ifdef INCLUDE_SCROLLBARS
  282.             if (HScrolling || VScrolling)
  283.                 break;
  284. #endif
  285.             if (TextMarking
  286. #ifdef INCLUDE_SYSTEM_MENUS
  287.                     && !(WindowMoving || WindowSizing)
  288. #endif
  289.                             )    {
  290.                 PostMessage(wnd, RELEASE_MOUSE, 0, 0);
  291.                 TextMarking = FALSE;
  292.                 if (wnd->BlkBegLine > wnd->BlkEndLine)    {
  293.                     swap(wnd->BlkBegLine, wnd->BlkEndLine);
  294.                     swap(wnd->BlkBegCol, wnd->BlkEndCol);
  295.                 }
  296.                 if (wnd->BlkBegLine == wnd->BlkEndLine &&
  297.                         wnd->BlkBegCol > wnd->BlkEndCol)
  298.                     swap(wnd->BlkBegCol, wnd->BlkEndCol);
  299.                 return TRUE;
  300.             }
  301.             else
  302.                 py = -1;
  303.             break;
  304.         case SCROLL:
  305.             if (!isMultiLine(wnd))
  306.                 break;
  307.             if ((rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2)) != FALSE)    {
  308.                 if (p1)    {
  309.                     /* -------- scrolling up --------- */
  310.                     if (wnd->WndRow == 0)    {
  311.                         DownLine(wnd);
  312.                         StickEnd(wnd);
  313.                     }
  314.                     else
  315.                         --wnd->WndRow;
  316.                 }
  317.                 else    {
  318.                     /* -------- scrolling down --------- */
  319.                     if (wnd->WndRow == ClientHeight(wnd)-1)    {
  320.                         UpLine(wnd);
  321.                         StickEnd(wnd);
  322.                     }
  323.                     else
  324.                         wnd->WndRow++;
  325.                 }
  326.                 SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  327.             }
  328.             return rtn;
  329. #endif
  330.         case HORIZSCROLL:
  331.             if (p1 && wnd->CurrCol == wnd->wleft &&
  332.                     *currchar == '\n')
  333.                 return FALSE;
  334.             if ((rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2)) != FALSE)    {
  335.                 if (wnd->CurrCol < wnd->wleft)
  336.                     wnd->CurrCol++;
  337.                 else if (WndCol == ClientWidth(wnd))
  338.                     --wnd->CurrCol;
  339.                 SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  340.             }
  341.             return rtn;
  342. #ifdef INCLUDE_SYSTEM_MENUS
  343.         case MOVE:
  344.             rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  345.             SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  346.             return rtn;
  347.         case SIZE:
  348.             rtn = BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  349.             if (WndCol > ClientWidth(wnd)-1)
  350.                 wnd->CurrCol = ClientWidth(wnd)-1 + wnd->wleft;
  351.             if (wnd->WndRow > ClientHeight(wnd)-1)    {
  352.                 wnd->WndRow = ClientHeight(wnd)-1;
  353.                 SetLinePointer(wnd, wnd->WndRow+wnd->wtop);
  354.             }
  355.             SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  356.             return rtn;
  357. #endif
  358.         case KEYBOARD:
  359. #ifdef INCLUDE_SYSTEM_MENUS
  360.             if (WindowMoving || WindowSizing)
  361.                 break;
  362. #endif
  363.             if ((int)p2 & ALTKEY)
  364.                 break;
  365.             c = (int) p1;
  366.             switch (c)    {
  367.                 case CTRL_FWD:
  368.                 case CTRL_BS:
  369.                 case CTRL_HOME:
  370.                 case CTRL_END:
  371.                     break;
  372.                 case ESC:
  373.                 case F1:
  374.                 case F2:
  375.                 case F3:
  376.                 case F4:
  377.                 case F5:
  378.                 case F6:
  379.                 case F7:
  380.                 case F8:
  381.                 case F9:
  382.                 case F10:
  383.                 case SHIFT_INS:
  384.                 case SHIFT_DEL:
  385.                     PassOn = TRUE;
  386.                 default:
  387.                     if ((int)p2 & CTRLKEY)
  388.                         PassOn = TRUE;
  389.                 break;
  390.             }
  391.             if (PassOn)
  392.                 break;
  393. #ifdef INCLUDE_MULTILINE
  394.             if (isMultiLine(wnd))    {
  395.                 if ((int)p2 & (LEFTSHIFT | RIGHTSHIFT))    {
  396.                     SendMessage(NULLWND, CURRENT_KEYBOARD_CURSOR,
  397.                         (PARAM) &kx, (PARAM) &ky);
  398.  
  399.                     kx -= GetClientLeft(wnd);
  400.                     ky -= GetClientTop(wnd);
  401.  
  402.                     switch (c)    {
  403.                         case HOME:
  404.                         case END:
  405.                         case PGUP:
  406.                         case PGDN:
  407.                         case UP:
  408.                         case DN:
  409.                         case FWD:
  410.                         case BS:
  411.                         case CTRL_FWD:
  412.                         case CTRL_BS:
  413.                             if (!KeyBoardMarking)    {
  414.                                 if (BlockMarked(wnd))    {
  415.                                     ClearBlock(wnd);
  416.                                     SendMessage(wnd, PAINT, 0, 0);
  417.                                 }
  418.                                 KeyBoardMarking = TextMarking = TRUE;
  419.                                 SetAnchor(wnd, kx+wnd->wleft, ky+wnd->wtop);
  420.                             }
  421.                             break;
  422.                         default:
  423.                             break;
  424.                     }
  425.                 }
  426.                 else if (((c != DEL && c != RUBOUT) ||
  427.                         !isMultiLine(wnd)) && BlockMarked(wnd))    {
  428.                     ClearBlock(wnd);
  429.                     SendMessage(wnd, PAINT, 0, 0);
  430.                 }
  431.             }
  432. #endif
  433.             switch (c)    {
  434. #ifdef INCLUDE_MULTILINE
  435.                 case PGUP:
  436.                 case PGDN:
  437.                     if (!isMultiLine(wnd))
  438.                         break;
  439.                     BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  440.                     SetLinePointer(wnd, wnd->wtop+wnd->WndRow);
  441.                     StickEnd(wnd);
  442.                     SendMessage(wnd, KEYBOARD_CURSOR,WndCol, wnd->WndRow);
  443.                     break;
  444. #endif
  445.                 case HOME:
  446.                     Home(wnd);
  447.                     break;
  448.                 case END:
  449.                     End(wnd);
  450.                     break;
  451.                 case CTRL_FWD:
  452.                     NextWord(wnd);
  453.                     break;
  454.                 case CTRL_BS:
  455.                     PrevWord(wnd);
  456.                     break;
  457.                 case CTRL_HOME:
  458.                     if (!isMultiLine(wnd))    {
  459.                         Home(wnd);
  460.                         break;
  461.                     }
  462. #ifdef INCLUDE_MULTILINE
  463.                     rtn = BaseWndProc(EDITBOX, wnd, msg, HOME, p2);
  464.                     Home(wnd);
  465.                     wnd->CurrLine = 0;
  466.                     wnd->WndRow = 0;
  467.                     SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  468.                     return rtn;
  469. #endif
  470.                 case CTRL_END:
  471.                     if (!isMultiLine(wnd))    {
  472.                         End(wnd);
  473.                         break;
  474.                     }
  475. #ifdef INCLUDE_MULTILINE
  476.                     Home(wnd);
  477.                     rtn = BaseWndProc(EDITBOX, wnd, msg, END, p2);
  478.                     SetLinePointer(wnd, wnd->wlines-1);
  479.                     wnd->WndRow = min(ClientHeight(wnd)-1, wnd->wlines-1);
  480.                     End(wnd);
  481.                     SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  482.                     return rtn;
  483. #endif
  484. #ifdef INCLUDE_MULTILINE
  485.                 case UP:
  486.                     if (!isMultiLine(wnd))
  487.                         break;
  488.                     Upward(wnd);
  489.                     break;
  490.                 case DN:
  491.                     if (!isMultiLine(wnd))
  492.                         break;
  493.                     Downward(wnd);
  494.                     break;
  495. #endif
  496.                 case FWD:
  497.                     Forward(wnd);
  498.                     break;
  499.                 case BS:
  500.                     Backward(wnd);
  501.                     break;
  502.             }
  503. #ifdef INCLUDE_MULTILINE
  504.             if (KeyBoardMarking)    {
  505.                 SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  506.                 SendMessage(NULLWND, CURRENT_KEYBOARD_CURSOR,
  507.                     (PARAM) &kx, (PARAM) &ky);
  508.                 SendMessage(wnd, MOUSE_MOVED, kx, ky);
  509.                 return TRUE;
  510.             }
  511. #endif
  512.             if (!TestAttribute(wnd, READONLY))    {
  513.                 switch (c)    {
  514.                     case HOME:
  515.                     case END:
  516.                     case PGUP:
  517.                     case PGDN:
  518.                     case UP:
  519.                     case DN:
  520.                     case FWD:
  521.                     case BS:
  522.                     case CTRL_FWD:
  523.                     case CTRL_BS:
  524.                     case CTRL_HOME:
  525.                     case CTRL_END:
  526.                     case RUBOUT:
  527.                         if (!isMultiLine(wnd) && BlockMarked(wnd))    {
  528.                             ClearBlock(wnd);
  529.                             SendMessage(wnd, PAINT, 0, 0);
  530.                         }
  531.                         if (c != RUBOUT)
  532.                             break;
  533.                         if (wnd->CurrLine == 0 && wnd->CurrCol == 0)
  534.                             break;
  535.                         Backward(wnd);
  536.                         currchar = CurrChar;
  537.                         SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  538.                     case DEL:
  539.                         if (BlockMarked(wnd))    {
  540.                             SendMessage(wnd, COMMAND, ID_DELETETEXT, 0);
  541.                             return TRUE;
  542.                         }
  543.                         if (*(currchar+1) == '\0')
  544.                             return TRUE;
  545.                         if (*(currchar+1))    {
  546.                             int repaint = *currchar == '\n';
  547.                             strcpy(currchar, currchar+1);
  548.                             if (repaint)    {
  549.                                 BuildTextPointers(wnd);
  550.                                 SendMessage(wnd, PAINT, 0, 0);
  551.                             }
  552.                             else    {
  553.                                 AddTextPointers(wnd, wnd->CurrLine+1, -1);
  554.                                 WriteTextLine(wnd, NULL, wnd->WndRow+wnd->wtop, FALSE);
  555.                             }
  556.                         }
  557.                         wnd->TextChanged = TRUE;
  558.                         break;
  559.                     case INS:
  560.                         InvertCommandToggle(MainMenu, ID_INSERT);
  561.                         SendMessage(NULLWND, SHOW_CURSOR, GetCommandToggle(MainMenu, ID_INSERT), 0);
  562.                         break;
  563.                     case '\r':
  564. #ifdef INCLUDE_MULTILINE
  565.                         if (isMultiLine(wnd))
  566.                             c = '\n';
  567. #endif
  568.                     default:
  569.                         if (c == '\t')    {
  570.                             int insmd = GetCommandToggle(MainMenu, ID_INSERT);
  571.                             if (!isMultiLine(wnd))
  572.                                 PostMessage(GetParent(wnd), msg, p1, p2);
  573. #ifdef INCLUDE_MULTILINE
  574.                             else do    {
  575.                                 if (!insmd && *(CurrChar+1) == '\0')
  576.                                     break;
  577.                                 SendMessage(wnd, KEYBOARD,
  578.                                     insmd ? ' ' : FWD, 0);
  579.                             } while (wnd->CurrCol % cfg.Tabs);
  580. #endif
  581.                             return TRUE;
  582.                         }
  583.                         if ((c != '\n' && c < ' ') || (c & 0x1000))
  584.                             /* ---- not recognized by editor --- */
  585.                             break;
  586. #ifdef INCLUDE_MULTILINE
  587.                         if (!isMultiLine(wnd) && BlockMarked(wnd))    {
  588.                             ResetEditBox(wnd);
  589.                             ClearBlock(wnd);
  590.                             currchar = CurrChar;
  591.                         }
  592. #endif
  593.                         if (*currchar == '\0')    {
  594.                             *currchar = '\n';
  595.                             *(currchar+1) = '\0';
  596.                             wnd->wlines++;
  597.                         }
  598.                         /* --- displayable char or newline --- */
  599.                         if (c == '\n' ||
  600.                                 GetCommandToggle(MainMenu, ID_INSERT) ||
  601.                                     *currchar == '\n')    {
  602.                             if (wnd->text[wnd->textlen-1] != '\0')    {
  603.                                 wnd->textlen += GROWLENGTH;
  604.                                 wnd->text = realloc(wnd->text, wnd->textlen+1);
  605.                                 wnd->text[wnd->textlen-1] = '\0';
  606.                                 currchar = CurrChar;
  607.                             }
  608.                             /* ------ insert mode ------ */
  609.                             memmove(currchar+1, currchar, strlen(currchar)+1);
  610.                             AddTextPointers(wnd, wnd->CurrLine+1, 1);
  611. #ifdef INCLUDE_MULTILINE
  612.                             if (isMultiLine(wnd))
  613.                                 wnd->textwidth = max(wnd->textwidth,
  614.                                     (int) (TextLine(wnd, wnd->CurrLine+1)-
  615.                                     TextLine(wnd, wnd->CurrLine)));
  616.                             else
  617. #endif
  618.                                 wnd->textwidth = max(wnd->textwidth,
  619.                                     strlen(wnd->text));
  620.                             WriteTextLine(wnd, NULL,
  621.                                 wnd->wtop+wnd->WndRow, FALSE);
  622.                         }
  623.                         /* ----- put the char in the buffer ----- */
  624.                         *currchar = c;
  625.                         wnd->TextChanged = TRUE;
  626.                         if (c == '\n')    {
  627.                             wnd->wleft = 0;
  628.                             BuildTextPointers(wnd);
  629.                             End(wnd);
  630.                             Forward(wnd);
  631.                             SendMessage(wnd, PAINT, 0, 0);
  632.                             break;
  633.                         }
  634.                         /* ---------- test end of window --------- */
  635.                         if (WndCol == ClientWidth(wnd)-1)    {
  636.                             int dif;
  637.                             char *cp = currchar;
  638.                             while (*cp != ' ' && cp != TextLine(wnd, wnd->CurrLine))
  639.                                 --cp;
  640. #ifdef INCLUDE_MULTILINE
  641.                             if (!isMultiLine(wnd) || cp == TextLine(wnd, wnd->CurrLine) ||
  642.                                     !GetCommandToggle(MainMenu, ID_WRAP))
  643. #endif
  644.                                 SendMessage(wnd, HORIZSCROLL, TRUE, 0);
  645. #ifdef INCLUDE_MULTILINE
  646.                             else    {
  647.                                 dif = 0;
  648.                                 if (c != ' ')    {
  649.                                     dif = (int) (currchar - cp);
  650.                                     wnd->CurrCol -= dif;
  651.                                     SendMessage(wnd, KEYBOARD, DEL, 0);
  652.                                     --dif;
  653.                                 }
  654.                                 SendMessage(wnd, KEYBOARD, '\r', 0);
  655.                                 currchar = CurrChar;
  656.                                 wnd->CurrCol = dif;
  657.                                 if (c == ' ')
  658.                                     break;
  659.                             }
  660. #endif
  661.                         }
  662.                         /* ------ display the character ------ */
  663.                         SetStandardColor(wnd);
  664.                         PutWindowChar(wnd, WndCol+BorderAdj(wnd),
  665.                             wnd->WndRow+TopBorderAdj(wnd), c);
  666.                         /* ----- advance the pointers ------ */
  667.                         wnd->CurrCol++;
  668.                         break;
  669.                 }
  670.             }
  671.             SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  672.             return TRUE;
  673. #ifdef INCLUDE_MULTILINE
  674.         case COMMAND:    {
  675.             char *bbl, *bel, *bb;
  676.             int len;
  677.  
  678.             if (BlockMarked(wnd))    {
  679.                 bbl = TextLine(wnd, wnd->BlkBegLine) + wnd->BlkBegCol;
  680.                 bel = TextLine(wnd, wnd->BlkEndLine) + wnd->BlkEndCol;
  681.                 len = (int) (bel - bbl);
  682.             }
  683.             switch ((int)p1)    {
  684. #ifdef INCLUDE_CLIPBOARD
  685.                 case ID_CUT:
  686.                 case ID_COPY:
  687.                     ClipboardLength = len;
  688.                     Clipboard = realloc(Clipboard, ClipboardLength);
  689.                     if (Clipboard != NULL)
  690.                         memmove(Clipboard, bbl, ClipboardLength);
  691. #endif
  692.                 case ID_DELETETEXT:
  693.                     if (p1 != ID_COPY)    {
  694.                         if (p1 != ID_CUT)
  695.                             SaveDeletedText(wnd, bbl, len);
  696.                         wnd->TextChanged = TRUE;
  697.                         strcpy(bbl, bel);
  698.                         wnd->CurrLine = TextLineNumber(wnd, bbl - wnd->BlkBegCol);
  699.                         wnd->CurrCol = wnd->BlkBegCol;
  700.                         wnd->WndRow = wnd->BlkBegLine - wnd->wtop;
  701.                         if (wnd->WndRow < 0)    {
  702.                             wnd->wtop = wnd->BlkBegLine;
  703.                             wnd->WndRow = 0;
  704.                         }
  705.                         SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  706.                     }
  707.                     ClearBlock(wnd);
  708.                     BuildTextPointers(wnd);
  709.                     SendMessage(wnd, PAINT, 0, 0);
  710.                     return TRUE;
  711. #ifdef INCLUDE_CLIPBOARD
  712.                 case ID_CLEAR:
  713.                     SaveDeletedText(wnd, bbl, len);
  714.                     wnd->CurrLine = TextLineNumber(wnd, bbl);
  715.                     wnd->CurrCol = wnd->BlkBegCol;
  716.                     wnd->WndRow = wnd->BlkBegLine - wnd->wtop;
  717.                     if (wnd->WndRow < 0)    {
  718.                         wnd->WndRow = 0;
  719.                         wnd->wtop = wnd->BlkBegLine;
  720.                     }
  721.                     while (bbl < bel)    {
  722.                         char *cp = strchr(bbl, '\n');
  723.                         if (cp > bel)
  724.                             cp = bel;
  725.                         strcpy(bbl, cp);
  726.                         bel -= (int) (cp - bbl);
  727.                         bbl++;
  728.                     }
  729.                     ClearBlock(wnd);
  730.                     BuildTextPointers(wnd);
  731.                     SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  732.                     SendMessage(wnd, PAINT, 0, 0);
  733.                     wnd->TextChanged = TRUE;
  734.                     return TRUE;
  735.                 case ID_PASTE:
  736.                     if (Clipboard != NULL)    {
  737.                         PasteText(wnd, Clipboard, ClipboardLength);
  738.                         wnd->TextChanged = TRUE;
  739.                     }
  740.                     return TRUE;
  741. #endif
  742.                 case ID_UNDO:
  743.                     if (wnd->DeletedText != NULL)    {
  744.                         PasteText(wnd, wnd->DeletedText, wnd->DeletedLength);
  745.                         free(wnd->DeletedText);
  746.                         wnd->DeletedText = NULL;
  747.                     }
  748.                     return TRUE;
  749.                 case ID_PARAGRAPH:    {
  750.                     char *bl;
  751.                     int bc, ec;
  752.                     int fl, el;
  753.                     int Blocked;
  754.  
  755.                     el = wnd->BlkEndLine;
  756.                     ec = wnd->BlkEndCol;
  757.                     if (!BlockMarked(wnd))    {
  758.                         Blocked = FALSE;
  759.                         /* ---- forming paragraph from cursor position --- */
  760.                         fl = wnd->wtop + wnd->WndRow;
  761.                         bl = TextLine(wnd, wnd->CurrLine);
  762.                         bc = wnd->CurrCol;
  763.                         Home(wnd);
  764.                         bbl = bel = bl;
  765.                         if (bc >= ClientWidth(wnd))
  766.                             bc = 0;
  767.                         /* ---- locate the end of the paragraph ---- */
  768.                         while (*bel)    {
  769.                             int blank = TRUE;
  770.                             char *bll = bel;
  771.                             /* --- blank line marks end of paragraph --- */
  772.                             while (*bel && *bel != '\n')    {
  773.                                 if (*bel != ' ')
  774.                                     blank = FALSE;
  775.                                 bel++;
  776.                             }
  777.                             if (blank)    {
  778.                                 bel = bll;
  779.                                 break;
  780.                             }
  781.                             if (*bel)
  782.                                 bel++;
  783.                         }
  784.                         if (bel == bbl)    {
  785.                             SendMessage(wnd, KEYBOARD, DN, 0);
  786.                             return TRUE;
  787.                         }
  788.                         if (*bel == '\0')
  789.                             --bel;
  790.                         if (*bel == '\n')
  791.                             --bel;
  792.                     }
  793.                     else    {
  794.                         Blocked = TRUE;
  795.                         /* ---- forming paragraph from marked block --- */
  796.                         fl = wnd->BlkBegLine;
  797.                         bc = wnd->CurrCol = wnd->BlkBegCol;
  798.                         wnd->CurrLine = fl;
  799.                         if (fl < wnd->wtop)
  800.                             wnd->wtop = fl;
  801.                         wnd->WndRow = fl - wnd->wtop;
  802.                         SendMessage(wnd, KEYBOARD, '\r', 0);
  803.                         el++, fl++;
  804.                         if (bc != 0)    {
  805.                             SendMessage(wnd, KEYBOARD, '\r', 0);
  806.                             el++, fl ++;
  807.                         }
  808.                         bc = 0;
  809.                         bl = TextLine(wnd, fl);
  810.                         wnd->CurrLine = fl;
  811.                         bbl = bl + bc;
  812.                         bel = TextLine(wnd, el) + ec;
  813.                     }
  814.  
  815.                     /* --- change all newlines in block to spaces --- */
  816.                     while (CurrChar < bel)    {
  817.                         if (*CurrChar == '\n')    {
  818.                             *CurrChar = ' ';
  819.                             wnd->CurrLine++;
  820.                             wnd->CurrCol = 0;
  821.                         }
  822.                         else
  823.                             wnd->CurrCol++;
  824.                     }
  825.  
  826.                     /* ---- insert newlines at new margin boundaries ---- */
  827.                     bb = bbl;
  828.                     while (bbl < bel)    {
  829.                         bbl++;
  830.                         if ((int)(bbl - bb) == ClientWidth(wnd)-1)    {
  831.                             while (*bbl != ' ' && bbl > bb)
  832.                                 --bbl;
  833.                             if (*bbl != ' ')    {
  834.                                 bbl = strchr(bbl, ' ');
  835.                                 if (bbl == NULL || bbl >= bel)
  836.                                     break;
  837.                             }
  838.                             *bbl = '\n';
  839.                             bb = bbl+1;
  840.                         }
  841.                     }
  842.                     ec = (int)(bel - bb);
  843.                     BuildTextPointers(wnd);
  844.  
  845.                     if (Blocked)    {
  846.                         /* ---- position cursor at end of new paragraph ---- */
  847.                         if (el < wnd->wtop ||
  848.                                 wnd->wtop + ClientHeight(wnd) < el)
  849.                             wnd->wtop = el-ClientHeight(wnd);
  850.                         if (wnd->wtop < 0)
  851.                             wnd->wtop = 0;
  852.                         wnd->WndRow = el - wnd->wtop;
  853.                         wnd->CurrLine = el;
  854.                         wnd->CurrCol = ec;
  855.                         SendMessage(wnd, KEYBOARD, '\r', 0);
  856.                         SendMessage(wnd, KEYBOARD, '\r', 0);
  857.                     }
  858.                     else    {
  859.                         /* --- put cursor back at beginning --- */
  860.                         wnd->CurrLine = TextLineNumber(wnd, bl);
  861.                         wnd->CurrCol = bc;
  862.                         if (fl < wnd->wtop)
  863.                             wnd->wtop = fl;
  864.                         wnd->WndRow = fl - wnd->wtop;
  865.                     }
  866.                     SendMessage(wnd, PAINT, 0, 0);
  867.                     SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  868.                     wnd->TextChanged = TRUE;
  869.                     BuildTextPointers(wnd);
  870.                     return TRUE;
  871.                 }
  872. #ifdef INCLUDE_DIALOG_BOXES
  873.                 case ID_SEARCH:
  874.                     SearchTextBox(wnd);
  875.                     break;
  876.                 case ID_REPLACE:
  877.                     ReplaceTextBox(wnd);
  878.                     break;
  879.                 case ID_SEARCHNEXT:
  880.                     SearchNext(wnd, TRUE);
  881.                     break;
  882. #endif
  883.                 default:
  884.                     break;
  885.             }
  886.             break;
  887.         }
  888. #endif
  889.         case CLOSE_WINDOW:
  890.             SendMessage(NULLWND, HIDE_CURSOR, 0, 0);
  891.             if (wnd->DeletedText != NULL)
  892.                 free(wnd->DeletedText);
  893.             break;
  894.         default:
  895.             break;
  896.     }
  897.     return BaseWndProc(EDITBOX, wnd, msg, p1, p2);
  898. }
  899.  
  900. #ifdef INCLUDE_MULTILINE
  901. static void PasteText(WINDOW wnd, char *SaveTo, int len)
  902. {
  903.     int plen = strlen(wnd->text) + len;
  904.     char *bl, *el;
  905.  
  906.     if (plen > wnd->textlen)    {
  907.         wnd->text = realloc(wnd->text, plen+1);
  908.         wnd->textlen = plen;
  909.     }
  910.     bl = CurrChar;
  911.     el = bl+len;
  912.     memmove(el,    bl,    strlen(bl)+1);
  913.     memmove(bl, SaveTo, len);
  914.     BuildTextPointers(wnd);
  915.     SendMessage(wnd, PAINT, 0, 0);
  916. }
  917.  
  918. static void SaveDeletedText(WINDOW wnd, char *bbl, int len)
  919. {
  920.     wnd->DeletedLength = len;
  921.     if ((wnd->DeletedText = realloc(wnd->DeletedText, len)) != NULL)
  922.         memmove(wnd->DeletedText, bbl, len);
  923. }
  924.  
  925. #endif
  926.  
  927. static void Forward(WINDOW wnd)
  928. {
  929.     if (*(CurrChar+1) == '\0')
  930.         return;
  931. #ifdef INCLUDE_MULTILINE
  932.     if (*CurrChar == '\n')    {
  933.         Home(wnd);
  934.         Downward(wnd);
  935.     }
  936. #endif
  937.     else    {
  938.         wnd->CurrCol++;
  939.         if (WndCol == ClientWidth(wnd))    {
  940.             wnd->wleft++;
  941.             SendMessage(wnd, PAINT, 0, 0);
  942.         }
  943.     }
  944. }
  945.  
  946. static void StickEnd(WINDOW wnd)
  947. {
  948.     char *cp = TextLine(wnd, wnd->CurrLine);
  949.     int len = (int) (strchr(cp, '\n') - cp);
  950.  
  951.     wnd->CurrCol = min(len, wnd->CurrCol);
  952.     if (wnd->wleft > wnd->CurrCol)    {
  953.         wnd->wleft = max(0, wnd->CurrCol - 4);
  954.         SendMessage(wnd, PAINT, 0, 0);
  955.     }
  956.     else if (wnd->CurrCol-wnd->wleft >= ClientWidth(wnd))    {
  957.         wnd->wleft = wnd->CurrCol - (ClientWidth(wnd)-1);
  958.         SendMessage(wnd, PAINT, 0, 0);
  959.     }
  960. }
  961.  
  962. #ifdef INCLUDE_MULTILINE
  963. static void Downward(WINDOW wnd)
  964. {
  965.     if (isMultiLine(wnd) && wnd->WndRow+wnd->wtop+1 < wnd->wlines)    {
  966.         DownLine(wnd);
  967.         if (wnd->WndRow == ClientHeight(wnd)-1)
  968.             SendMessage(wnd, SCROLL, TRUE, 0);
  969.         wnd->WndRow++;
  970.         StickEnd(wnd);
  971.     }
  972. }
  973.  
  974. static void DownLine(WINDOW wnd)
  975. {
  976.     wnd->CurrLine++;
  977. }
  978.  
  979. static void UpLine(WINDOW wnd)
  980. {
  981.     if (wnd->CurrLine > 0)
  982.         --wnd->CurrLine;
  983. }
  984.  
  985. static void Upward(WINDOW wnd)
  986. {
  987.     if (isMultiLine(wnd) && wnd->CurrLine != 0)    {
  988.         UpLine(wnd);
  989.         if (wnd->WndRow == 0)
  990.             SendMessage(wnd, SCROLL, FALSE, 0);
  991.         --wnd->WndRow;
  992.         StickEnd(wnd);
  993.     }
  994. }
  995. #endif
  996.  
  997. static void Backward(WINDOW wnd)
  998. {
  999.     if (wnd->CurrCol)    {
  1000.         if (wnd->CurrCol-- <= wnd->wleft)    {
  1001.             if (wnd->wleft != 0)    {
  1002.                 --wnd->wleft;
  1003.                 SendMessage(wnd, PAINT, 0, 0);
  1004.                 return;
  1005.             }
  1006.         }
  1007.         else
  1008.             return ;
  1009.     }
  1010. #ifdef INCLUDE_MULTILINE
  1011.     if (isMultiLine(wnd) && wnd->CurrLine != 0)    {
  1012.         Upward(wnd);
  1013.         End(wnd);
  1014.     }
  1015. #endif
  1016. }
  1017.  
  1018. static void End(WINDOW wnd)
  1019. {
  1020.     while (*CurrChar != '\n')
  1021.         ++wnd->CurrCol;
  1022.     if (WndCol >= ClientWidth(wnd))    {
  1023.         wnd->wleft = wnd->CurrCol - (ClientWidth(wnd)-1);
  1024.         SendMessage(wnd, PAINT, 0, 0);
  1025.     }
  1026. }
  1027.  
  1028. static void Home(WINDOW wnd)
  1029. {
  1030.     wnd->CurrCol = 0;
  1031.     if (wnd->wleft != 0)    {
  1032.         wnd->wleft = 0;
  1033.         SendMessage(wnd, PAINT, 0, 0);
  1034.     }
  1035. }
  1036.  
  1037. #define isWhite(c)     ((c) == ' ' || (c) == '\n')
  1038.  
  1039. static void NextWord(WINDOW wnd)
  1040. {
  1041.     int savetop = wnd->wtop;
  1042.     int saveleft = wnd->wleft;
  1043.     ClearVisible(wnd);
  1044.     while (!isWhite(*CurrChar))    {
  1045.         if (*(CurrChar+1) == '\0')
  1046.             break;
  1047.         Forward(wnd);
  1048.     }
  1049.     while (isWhite(*CurrChar))    {
  1050.         if (*(CurrChar+1) == '\0')
  1051.             break;
  1052.         Forward(wnd);
  1053.     }
  1054.     SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  1055.     SetVisible(wnd);
  1056.     if (wnd->wtop != savetop || wnd->wleft != saveleft)
  1057.         SendMessage(wnd, PAINT, 0, 0);
  1058. }
  1059.  
  1060. static void PrevWord(WINDOW wnd)
  1061. {
  1062.     int savetop = wnd->wtop;
  1063.     int saveleft = wnd->wleft;
  1064.     ClearVisible(wnd);
  1065.     Backward(wnd);
  1066.     while (isWhite(*CurrChar))    {
  1067.         if (wnd->CurrLine == 0 && wnd->CurrCol == 0)
  1068.             break;
  1069.         Backward(wnd);
  1070.     }
  1071.     while (!isWhite(*CurrChar))    {
  1072.         if (wnd->CurrLine == 0 && wnd->CurrCol == 0)
  1073.             break;
  1074.         Backward(wnd);
  1075.     }
  1076.     if (isWhite(*CurrChar))
  1077.         Forward(wnd);
  1078.     if (wnd->wleft != saveleft)
  1079.         if (wnd->CurrCol >= saveleft)
  1080.             if (wnd->CurrCol - saveleft < ClientWidth(wnd))
  1081.                 wnd->wleft = saveleft;
  1082.     SendMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  1083.     SetVisible(wnd);
  1084.     if (wnd->wtop != savetop || wnd->wleft != saveleft)
  1085.         SendMessage(wnd, PAINT, 0, 0);
  1086. }
  1087.  
  1088. static void ResetEditBox(WINDOW wnd)
  1089. {
  1090.     *wnd->text = '\0';
  1091.     wnd->wlines = 0;
  1092.     wnd->CurrLine = 0;
  1093.     wnd->CurrCol = 0;
  1094.     wnd->WndRow = 0;
  1095.     wnd->TextChanged = FALSE;
  1096.     wnd->wleft = 0;
  1097.     wnd->textwidth = 0;
  1098. }
  1099.  
  1100. static void AddTextPointers(WINDOW wnd, int lineno, int ct)
  1101. {
  1102.     while (lineno < wnd->wlines)
  1103.         *((wnd->TextPointers) + lineno++) += ct;
  1104. }
  1105.  
  1106. static int TextLineNumber(WINDOW wnd, char *lp)
  1107. {
  1108.     int lineno;
  1109.     char *cp;
  1110.     for (lineno = 0; lineno < wnd->wlines; lineno++)    {
  1111.         cp = wnd->text + *((wnd->TextPointers) + lineno);
  1112.         if (cp == lp)
  1113.             return lineno;
  1114.         if (lineno && cp > lp)
  1115.             return lineno - 1;
  1116.     }
  1117.     return 0;
  1118. }
  1119.  
  1120. #ifdef INCLUDE_MULTILINE
  1121. #ifdef INCLUDE_DIALOG_BOXES
  1122.  
  1123. extern DBOX SearchText;
  1124. extern DBOX ReplaceText;
  1125. static int checkcase = TRUE;
  1126. static int Replacing = FALSE;
  1127.  
  1128. static void ReplaceTextBox(WINDOW wnd)
  1129. {
  1130.     if (checkcase)
  1131.         SetCheckBox(&ReplaceText, ID_MATCHCASE);
  1132.     if (DialogBox(wnd, &ReplaceText, TRUE, NULL))    {
  1133.         checkcase = CheckBoxSetting(&ReplaceText, ID_MATCHCASE);
  1134.         Replacing = TRUE;
  1135.         SearchNext(wnd, FALSE);
  1136.     }
  1137. }
  1138.  
  1139. static void SearchTextBox(WINDOW wnd)
  1140. {
  1141.     if (checkcase)
  1142.         SetCheckBox(&SearchText, ID_MATCHCASE);
  1143.     if (DialogBox(wnd, &SearchText, TRUE, NULL))    {
  1144.         checkcase = CheckBoxSetting(&SearchText, ID_MATCHCASE);
  1145.         Replacing = FALSE;
  1146.         SearchNext(wnd, FALSE);
  1147.     }
  1148. }
  1149.  
  1150. static int SearchCmp(int a, int b)
  1151. {
  1152.     if (b == '\n')
  1153.         b = ' ';
  1154.     if (checkcase)
  1155.         return a != b;
  1156.     return tolower(a) != tolower(b);
  1157. }
  1158.  
  1159. static void SearchNext(WINDOW wnd, int incr)
  1160. {
  1161.     char *s1, *s2, *cp1 = CurrChar;
  1162.     DBOX *db = Replacing ? &ReplaceText : &SearchText;
  1163.     char *cp = GetEditBoxText(db, ID_SEARCHFOR);
  1164.     int rpl = TRUE, FoundOne = FALSE;
  1165.     while (rpl)    {
  1166.         rpl = Replacing ?
  1167.                 CheckBoxSetting(&ReplaceText, ID_REPLACEALL) : FALSE;
  1168.         if (BlockMarked(wnd))    {
  1169.             ClearBlock(wnd);
  1170.             SendMessage(wnd, PAINT, 0, 0);
  1171.         }
  1172.         if (cp && cp1 && *cp && *cp1)    {
  1173.             if (incr)
  1174.                 cp1++;
  1175.             while (*cp1)    {
  1176.                 s1 = cp;
  1177.                 s2 = cp1;
  1178.                 while (*s1 && *s1 != '\n')    {
  1179.                     if (SearchCmp(*s1,*s2))
  1180.                         break;
  1181.                     s1++, s2++;
  1182.                 }
  1183.                 if (*s1 == '\0' || *s1 == '\n')
  1184.                     break;
  1185.                 cp1++;
  1186.             }
  1187.             if (*s1 == 0 || *s1 == '\n')    {
  1188.                 /* ----- hit at *cp1 ------- */
  1189.                 FoundOne = TRUE;
  1190.                 wnd->BlkEndLine = TextLineNumber(wnd, s2);
  1191.                 wnd->BlkEndCol = (int)(s2 - TextLine(wnd, wnd->BlkEndLine));
  1192.  
  1193.                 wnd->BlkBegLine = TextLineNumber(wnd, cp1);
  1194.                 wnd->BlkBegCol = (int)(cp1 - TextLine(wnd, wnd->BlkBegLine));
  1195.  
  1196.                 wnd->CurrCol = wnd->BlkBegCol;
  1197.                 wnd->CurrLine = wnd->BlkBegLine;
  1198.                 wnd->WndRow = wnd->CurrLine - wnd->wtop;
  1199.  
  1200.                 if (WndCol > ClientWidth(wnd)-1)
  1201.                     wnd->wleft = wnd->CurrCol;
  1202.                 if (wnd->WndRow > ClientHeight(wnd)-1)    {
  1203.                     wnd->wtop = wnd->CurrLine;
  1204.                     wnd->WndRow = 0;
  1205.                 }
  1206.                 SendMessage(wnd, PAINT, 0, 0);
  1207.                 PostMessage(wnd, KEYBOARD_CURSOR, WndCol, wnd->WndRow);
  1208.                 if (Replacing)    {
  1209.                     if (rpl || YesNoBox("Replace the text?"))    {
  1210.                         char *cr = GetEditBoxText(db, ID_REPLACEWITH);
  1211.                         int oldlen = strlen(cp)-1;
  1212.                         int newlen = strlen(cr)-1;
  1213.                         int dif;
  1214.                         if (oldlen < newlen)    {
  1215.                             dif = newlen-oldlen;
  1216.                             if (wnd->textlen < strlen(wnd->text)+dif)    {
  1217.                                 int offset = (int)(cp1-wnd->text);
  1218.                                 wnd->textlen += dif;
  1219.                                 wnd->text = realloc(wnd->text, wnd->textlen);
  1220.                                 if (wnd->text == NULL)
  1221.                                     return;
  1222.                                 cp1 = wnd->text + offset;
  1223.                             }
  1224.                             memmove(cp1+dif, cp1, strlen(cp1)+1);
  1225.                         }
  1226.                         else if (oldlen > newlen)    {
  1227.                             dif = oldlen-newlen;
  1228.                             memmove(cp1, cp1+dif, strlen(cp1)+1);
  1229.                         }
  1230.                         strncpy(cp1, cr, newlen);
  1231.                         wnd->TextChanged = TRUE;
  1232.                         BuildTextPointers(wnd);
  1233.                     }
  1234.                     if (rpl)    {
  1235.                         incr = TRUE;
  1236.                         continue;
  1237.                     }
  1238.                     ClearBlock(wnd);
  1239.                     SendMessage(wnd, PAINT, 0, 0);
  1240.                 }
  1241.                 return;
  1242.             }
  1243.             break;
  1244.         }
  1245.     }
  1246.     if (cp && *cp && !FoundOne)
  1247.         MessageBox("Search/Replace Text", "No match found");
  1248. }
  1249.  
  1250. #endif
  1251. #endif
  1252.