home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 08 / dflat5 / textbox.c < prev    next >
Text File  |  1991-06-25  |  15KB  |  621 lines

  1. /* ------------- textbox.c ------------ */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <dos.h>
  7. #include "dflat.h"
  8.  
  9. #ifdef INCLUDE_SCROLLBARS
  10. static int ComputeVScrollBox(WINDOW);
  11. static int ComputeHScrollBox(WINDOW);
  12. static void MoveScrollBox(WINDOW, int);
  13. #endif
  14. static char *GetTextLine(WINDOW, int);
  15.  
  16. #ifdef INCLUDE_SCROLLBARS
  17. int HScrolling = FALSE;
  18. int VScrolling = FALSE;
  19. #endif
  20.  
  21. int TextBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  22. {
  23. #ifdef INCLUDE_SCROLLBARS
  24.     int    mx = (int) p1 - GetLeft(wnd);
  25.     int    my = (int) p2 - GetTop(wnd);
  26. #endif
  27.     switch (msg)    {
  28.         case CREATE_WINDOW:
  29.             wnd->HScrollBox = wnd->VScrollBox = TRUE;
  30.             ClearTextPointers(wnd);
  31.             break;
  32.         case ADDTEXT:    {
  33.             /* ======== need to assure that length !> 64K ======= */
  34.             int adln = strlen((char *)p1);
  35.             if (wnd->text != NULL)    {
  36.                 int txln = strlen(wnd->text);
  37.                 if (txln+adln > wnd->textlen)    {
  38.                     wnd->text = realloc(wnd->text, txln+adln+2);
  39.                     wnd->textlen = txln+adln;
  40.                 }
  41.             }
  42.             else    {
  43.                 if ((wnd->text = malloc(adln+2)) != NULL)
  44.                     *wnd->text = '\0';
  45.                 wnd->textlen = adln+1;
  46.             }
  47.             if (wnd->text != NULL)    {
  48.                 strcat(wnd->text, (char*) p1);
  49.                 strcat(wnd->text, "\n");
  50.                 BuildTextPointers(wnd);
  51.             }
  52.             break;
  53.         }
  54.         case SETTEXT:    {
  55.             char *cp;
  56.             unsigned int len;
  57.             cp = (void *) p1;
  58.             len = strlen(cp)+1;
  59.             if (wnd->text == NULL || wnd->textlen < len)    {
  60.                 wnd->textlen = len;
  61.                 if ((wnd->text = realloc(wnd->text, len)) == NULL)
  62.                     break;
  63.             }
  64.             strcpy(wnd->text, cp);
  65.             BuildTextPointers(wnd);
  66.             break;
  67.         }
  68.         case CLEARTEXT:
  69.             if (wnd->text != NULL)
  70.                 free(wnd->text);
  71.             wnd->text = NULL;
  72.             wnd->textlen = 0;
  73.             wnd->wlines = 0;
  74.             wnd->textwidth = 0;
  75.             wnd->wtop = wnd->wleft = 0;
  76.             ClearBlock(wnd);
  77.             ClearTextPointers(wnd);
  78.             break;
  79.         case KEYBOARD:
  80. #ifdef INCLUDE_SYSTEM_MENUS
  81.             if (WindowMoving || WindowSizing)
  82.                 break;
  83. #endif
  84.             switch ((int) p1)    {
  85.                 case UP:
  86.                     if (wnd->wtop)
  87.                         SendMessage(wnd, SCROLL, FALSE, 0);
  88.                     return TRUE;
  89.                 case DN:
  90.                     if (wnd->wtop+ClientHeight(wnd) < wnd->wlines)
  91.                         SendMessage(wnd, SCROLL, TRUE, 0);
  92.                     return TRUE;
  93.                 case FWD:
  94.                     SendMessage(wnd, HORIZSCROLL, TRUE, 0);
  95.                     return TRUE;
  96.                 case BS:
  97.                     SendMessage(wnd, HORIZSCROLL, FALSE, 0);
  98.                     return TRUE;
  99.                 case PGUP:
  100.                     if (wnd->wtop)    {
  101.                         wnd->wtop -= ClientHeight(wnd);
  102.                         if (wnd->wtop < 0)
  103.                             wnd->wtop = 0;
  104.                         SendMessage(wnd, PAINT, 0, 0);
  105.                         return TRUE;
  106.                     }
  107.                     return TRUE;
  108.                 case PGDN:
  109.                     if (wnd->wtop+ClientHeight(wnd) < wnd->wlines)    {
  110.                         wnd->wtop += ClientHeight(wnd);
  111.                         if (wnd->wtop > wnd->wlines-ClientHeight(wnd))
  112.                             wnd->wtop = wnd->wlines-ClientHeight(wnd);
  113.                         SendMessage(wnd, PAINT, 0, 0);
  114.                         return TRUE;
  115.                     }
  116.                     return TRUE;
  117.                 case HOME:
  118.                     if (wnd->wtop || wnd->wleft)    {
  119.                         wnd->wtop = wnd->wleft = 0;
  120.                         SendMessage(wnd, PAINT, 0, 0);
  121.                     }
  122.                     return TRUE;
  123.                 case END:
  124.                     if (wnd->wtop+ClientHeight(wnd) < wnd->wlines)    {
  125.                         wnd->wtop = wnd->wlines-ClientHeight(wnd);
  126.                         wnd->wleft = 0;
  127.                         SendMessage(wnd, PAINT, 0, 0);
  128.                     }
  129.                     return TRUE;
  130.                 default:
  131.                     break;
  132.             }
  133.             break;
  134.         case LEFT_BUTTON:
  135. #ifdef INCLUDE_SYSTEM_MENUS
  136.             if (WindowSizing || WindowMoving)
  137.                 return FALSE;
  138. #endif
  139. #ifdef INCLUDE_SCROLLBARS
  140.             if (TestAttribute(wnd, VSCROLLBAR) && (VScrolling ||
  141.                     mx == WindowWidth(wnd)-1))    {
  142.  
  143.                 /* -------- in the right border ------- */
  144.                 if (my == 0 || my == ClientHeight(wnd)+1)
  145.                     /* ------ above or below the scroll bar ---- */
  146.                     break;
  147.  
  148.                 /* ---------- in the scroll bar ----------- */
  149.  
  150.                 VScrolling = TRUE;
  151.  
  152.                 if (my == 1)    {
  153.                     /* -------- top scroll button --------- */
  154.                     SendMessage(wnd, SCROLL, FALSE, 0);
  155.                     return TRUE;
  156.                 }
  157.                 if (my == ClientHeight(wnd))    {
  158.                     /* -------- bottom scroll button --------- */
  159.                     SendMessage(wnd, SCROLL, TRUE, 0);
  160.                     return TRUE;
  161.                 }
  162.                 if (my-1 != wnd->VScrollBox)    {
  163.                     int dir = my-1 > wnd->VScrollBox;
  164.  
  165.                     while (dir ? (my-1 > wnd->VScrollBox) :
  166.                                  (my-1 < wnd->VScrollBox))    {
  167.                         if (!SendMessage(wnd, SCROLL, dir, TRUE))
  168.                             break;
  169.                         wnd->VScrollBox = ComputeVScrollBox(wnd);
  170.                     }
  171.                     SendMessage(wnd, SHOW_WINDOW, 0, 0);
  172.                     return TRUE;
  173.                 }
  174.             }
  175.             if (TestAttribute(wnd, HSCROLLBAR) &&
  176.                 (HScrolling || my == WindowHeight(wnd)-1))    {
  177.                 /* -------- in the bottom border ------- */
  178.                 if (mx == 0 || my == ClientWidth(wnd)+1)
  179.                     /* ------  outside the scroll bar ---- */
  180.                     break;
  181.  
  182.                 HScrolling = TRUE;
  183.  
  184.                 if (mx == 1)    {
  185.                     SendMessage(wnd, HORIZSCROLL, FALSE, 0);
  186.                     return TRUE;
  187.                 }
  188.                 if (mx == WindowWidth(wnd)-2)    {
  189.                     SendMessage(wnd, HORIZSCROLL, TRUE, 0);
  190.                     return TRUE;
  191.                 }
  192.  
  193.                 if (mx-1 != wnd->HScrollBox)    {
  194.                     int dir = mx-1 > wnd->HScrollBox;
  195.                     while (dir ? (mx-1 > wnd->HScrollBox) :
  196.                                  (mx-1 < wnd->HScrollBox))    {
  197.                         if (!SendMessage(wnd, HORIZSCROLL, dir, TRUE))
  198.                             break;
  199.                         wnd->HScrollBox = ComputeHScrollBox(wnd);
  200.                     }
  201.                     SendMessage(wnd, SHOW_WINDOW, 0, 0);
  202.                     return TRUE;
  203.                 }
  204.             }
  205.             break;
  206.         case BUTTON_RELEASED:
  207.             HScrolling = VScrolling = FALSE;
  208.             break;
  209. #endif
  210.         case SCROLL:
  211.             if (isVisible(wnd))    {
  212.                 if (p1)    {
  213.                     if (wnd->wtop+ClientHeight(wnd) >= wnd->wlines)
  214.                         return FALSE;
  215.                     wnd->wtop++;
  216.                 }
  217.                 else    {
  218.                     if (wnd->wtop == 0)
  219.                         return FALSE;
  220.                     --wnd->wtop;
  221.                 }
  222.                 if ((int) p2 == FALSE)    {
  223.                     RECT rc;
  224.                     rc = ClipRectangle(wnd, ClientRect(wnd));
  225.                     if (ValidRect(rc))    {
  226.                         scroll_window(wnd, rc, (int)p1);
  227.                         if (!(int)p1)
  228.                             WriteTextLine(wnd, NULL, wnd->wtop, FALSE);
  229.                         else    {
  230.                             int y = RectBottom(rc)-GetClientTop(wnd);
  231.                             WriteTextLine(wnd, NULL,
  232.                                 wnd->wtop+y, FALSE);
  233.                         }
  234.                     }
  235. #ifdef INCLUDE_SCROLLBARS
  236.                     if (TestAttribute(wnd, VSCROLLBAR))    {
  237.                         int vscrollbox = ComputeVScrollBox(wnd);
  238.                         if (vscrollbox != wnd->VScrollBox)
  239.                             MoveScrollBox(wnd, vscrollbox);
  240.                     }
  241. #endif
  242.                 }
  243.             }
  244.             return TRUE;
  245.         case HORIZSCROLL:
  246.             if (isVisible(wnd))    {
  247.                 if (p1)    {
  248.                     if (wnd->wleft + ClientWidth(wnd)-1 >= wnd->textwidth)
  249.                         return FALSE;
  250.                     wnd->wleft++;
  251.                 }
  252.                 else    {
  253.                     if (wnd->wleft == 0)
  254.                         return FALSE;
  255.                     --wnd->wleft;
  256.                 }
  257.                 if ((int) p2 == FALSE)
  258.                     SendMessage(wnd, PAINT, 0, 0);
  259.             }
  260.             return TRUE;
  261.         case PAINT:
  262.             if (isVisible(wnd) && wnd->wlines)    {
  263.                 RECT rc, rcc;
  264.                 int y;
  265.                 char blankline[SCREENWIDTH+1];
  266.  
  267.                 if ((RECT *)p1 == NULL)
  268.                     rc = RelativeWindowRect(wnd, WindowRect(wnd));
  269.                 else
  270.                     rc = *(RECT *)p1;
  271.  
  272.                 if (TestAttribute(wnd, HASBORDER) &&
  273.                         RectRight(rc) >= WindowWidth(wnd)-1)    {
  274.                     if (RectLeft(rc) >= WindowWidth(wnd)-1)
  275.                         return TRUE;
  276.                     RectRight(rc) = WindowWidth(wnd)-2;
  277.                 }
  278.  
  279.                 rcc = AdjustRectangle(wnd, rc);
  280.                 memset(blankline, ' ', SCREENWIDTH);
  281.                 blankline[RectRight(rcc)+1] = '\0';
  282.  
  283.                 for (y = RectTop(rc); y <= RectBottom(rc); y++)    {
  284.                     int yy;
  285.                     if (TestAttribute(wnd, HASBORDER | HASTITLEBAR))    {
  286.                         if (y < TopBorderAdj(wnd))
  287.                             continue;
  288.                         if (y > WindowHeight(wnd)-2)
  289.                             continue;
  290.                     }
  291.                     yy = y-TopBorderAdj(wnd);
  292.                     if (yy < wnd->wlines-wnd->wtop)
  293.                         WriteTextLine(wnd, &rc, yy+wnd->wtop, FALSE);
  294.                     else    {
  295.                         SetStandardColor(wnd);
  296.                         writeline(wnd, blankline+RectLeft(rcc),
  297.                                 RectLeft(rcc)+1, y, FALSE);
  298.                     }
  299.                 }
  300. #ifdef INCLUDE_SCROLLBARS
  301.                 if (TestAttribute(wnd, VSCROLLBAR | HSCROLLBAR))    {
  302.                     int hscrollbox = ComputeHScrollBox(wnd);
  303.                     int vscrollbox = ComputeVScrollBox(wnd);
  304.                     if (hscrollbox != wnd->HScrollBox ||
  305.                             vscrollbox != wnd->VScrollBox)    {
  306.                         wnd->HScrollBox = hscrollbox;
  307.                         wnd->VScrollBox = vscrollbox;
  308.                         SendMessage(wnd, BORDER, p1, 0);
  309.                     }
  310.                 }
  311. #endif
  312.                 return FALSE;
  313.             }
  314.             break;
  315.         case CLOSE_WINDOW:
  316.             SendMessage(wnd, CLEARTEXT, 0, 0);
  317.             if (wnd->TextPointers != NULL)    {
  318.                 free(wnd->TextPointers);
  319.                 wnd->TextPointers = NULL;
  320.             }
  321.             break;
  322.         default:
  323.             break;
  324.     }
  325.     return BaseWndProc(TEXTBOX, wnd, msg, p1, p2);
  326. }
  327.  
  328. #ifdef INCLUDE_SCROLLBARS
  329. static int ComputeVScrollBox(WINDOW wnd)
  330. {
  331.     int pagelen = wnd->wlines - ClientHeight(wnd);
  332.     int barlen = ClientHeight(wnd)-2;
  333.     int lines_tick;
  334.     int vscrollbox;
  335.  
  336.     if (pagelen < 1 || barlen < 1)
  337.         vscrollbox = 1;
  338.     else    {
  339.         if (pagelen > barlen)
  340.             lines_tick = pagelen / barlen;
  341.         else
  342.             lines_tick = barlen / pagelen;
  343.         vscrollbox = 1 + (wnd->wtop / lines_tick);
  344.         if (vscrollbox > ClientHeight(wnd)-2 ||
  345.                 wnd->wtop + ClientHeight(wnd) >= wnd->wlines)
  346.             vscrollbox = ClientHeight(wnd)-2;
  347.     }
  348.     return vscrollbox;
  349. }
  350.  
  351. static int ComputeHScrollBox(WINDOW wnd)
  352. {
  353.     int pagewidth = wnd->textwidth - ClientWidth(wnd);
  354.     int barlen = ClientWidth(wnd)-2;
  355.     int chars_tick;
  356.     int hscrollbox;
  357.  
  358.     if (pagewidth < 1 || barlen < 1)
  359.         hscrollbox = 1;
  360.     else     {
  361.         if (pagewidth > barlen)
  362.             chars_tick = pagewidth / barlen;
  363.         else
  364.             chars_tick = barlen / pagewidth;
  365.         hscrollbox = 1 + (wnd->wleft / chars_tick);
  366.         if (hscrollbox > ClientWidth(wnd)-2 ||
  367.                 wnd->wleft + ClientWidth(wnd) >= wnd->textwidth)
  368.             hscrollbox = ClientWidth(wnd)-2;
  369.     }
  370.     return hscrollbox;
  371. }
  372. #endif
  373.  
  374. static char *GetTextLine(WINDOW wnd, int selection)
  375. {
  376.     char *line;
  377.     int len = 0;
  378.     char *cp, *cp1;
  379.     cp = cp1 = TextLine(wnd, selection);
  380.     while (*cp && *cp != '\n')    {
  381.         len++;
  382.         cp++;
  383.     }
  384.     line = malloc(len+6);
  385.     if (line != NULL)    {
  386.         memmove(line, cp1, len);
  387.         line[len] = '\0';
  388.     }
  389.     return line;
  390. }
  391.  
  392. void WriteTextLine(WINDOW wnd, RECT *rcc, int y, int reverse)
  393. {
  394.     int len = 0;
  395.     int dif = 0;
  396.     static unsigned char line[100];
  397.     RECT rc;
  398.     unsigned char *lp, *svlp;
  399.     int lnlen;
  400.     int i;
  401.     int trunc = FALSE;
  402.  
  403.     if (y < wnd->wtop || y >= wnd->wtop+ClientHeight(wnd))
  404.         return;
  405.  
  406.     if (rcc == NULL)
  407.         rc = RelativeWindowRect(wnd, WindowRect(wnd));
  408.     else
  409.         rc = *rcc;
  410.  
  411.     if (RectLeft(rc) >= WindowWidth(wnd)-1)
  412.         return;
  413.     if (RectRight(rc) == 0)
  414.         return;
  415.  
  416.     rc = AdjustRectangle(wnd, rc);
  417.  
  418.     lp = svlp = GetTextLine(wnd, y);
  419.     lnlen = LineLength(lp);
  420.  
  421.     /* -------- insert block color change controls ------- */
  422.     if (BlockMarked(wnd))    {
  423.         int bbl = wnd->BlkBegLine;
  424.         int bel = wnd->BlkEndLine;
  425.         int bbc = wnd->BlkBegCol;
  426.         int bec = wnd->BlkEndCol;
  427.         int by = y;
  428.  
  429.         if (bbl > bel)    {
  430.             swap(bbl, bel);
  431.             swap(bbc, bec);
  432.         }
  433.         if (bbl == bel && bbc > bec)
  434.             swap(bbc, bec);
  435.  
  436.         if (by >= bbl && by <= bel)    {
  437.             /* ------ the block includes this line ----- */
  438.             int blkbeg = 0;
  439.             int blkend = lnlen;
  440.             if (!(by > bbl && by < bel))    {
  441.                 /* --- the entire line is not in the block --- */
  442.                 if (by == bbl)
  443.                     /* ---- the block begins on this line ---- */
  444.                     blkbeg = bbc;
  445.                 if (by == bel)
  446.                     /* ---- the block ends on this line ---- */
  447.                     blkend = bec;
  448.             }
  449.             memmove(lp+blkend+1, lp+blkend, strlen(lp+blkend)+1);
  450.             lp[blkend] = RESETCOLOR;
  451.             memmove(lp+blkbeg+3, lp+blkbeg, strlen(lp+blkbeg)+1);
  452.             lp[blkbeg] = CHANGECOLOR;
  453.             SetReverseColor(wnd);
  454.             lp[blkbeg+1] = foreground | 0x80;
  455.             lp[blkbeg+2] = background | 0x80;
  456.             lnlen += 4;
  457.         }
  458.     }
  459.  
  460.     for (i = 0; i < wnd->wleft+3; i++)    {
  461.         if (*(lp+i) == '\0')
  462.             break;
  463.         if (*(unsigned char *)(lp + i) == RESETCOLOR)
  464.             break;
  465.     }
  466.     if (*(lp+i) && i < wnd->wleft+3)    {
  467.         if (wnd->wleft+4 > lnlen)
  468.             trunc = TRUE;
  469.         else 
  470.             lp += 4;
  471.     }
  472.     else     {
  473.         for (i = 0; i < wnd->wleft; i++)    {
  474.             if (*(lp+i) == '\0')
  475.                 break;
  476.             if (*(unsigned char *)(lp + i) == CHANGECOLOR)    {
  477.                 *(lp+wnd->wleft+2) = *(lp+i+2);
  478.                 *(lp+wnd->wleft+1) = *(lp+i+1);
  479.                 *(lp+wnd->wleft) = *(lp+i);
  480.                 break;
  481.             }
  482.         }
  483.     }
  484.  
  485.     if (!trunc)    {
  486.         if (lnlen < wnd->wleft)
  487.             lnlen = 0;
  488.         else
  489.             lp += wnd->wleft;
  490.  
  491.  
  492.         if (y-wnd->wtop < RectTop(rc) || y-wnd->wtop > RectBottom(rc))
  493.             return;
  494.  
  495.         if (lnlen > RectLeft(rc))    {
  496.             int ct = RectLeft(rc);
  497.             char *initlp = lp;
  498.             while (ct)    {
  499.                 if (*(unsigned char *)lp == CHANGECOLOR)
  500.                     lp += 3;
  501.                 else if (*(unsigned char *)lp == RESETCOLOR)
  502.                     lp++;
  503.                 else
  504.                     lp++, --ct;
  505.             }
  506.             if (RectLeft(rc))    {
  507.                 char *lpp = lp;
  508.                 while (*lpp)    {
  509.                     if (*(unsigned char *)lpp == CHANGECOLOR)
  510.                         break;
  511.                     if (*(unsigned char *)lpp == RESETCOLOR)    {
  512.                         lpp = lp;
  513.                         while (lpp >= initlp)    {
  514.                             if (*(unsigned char *)lpp == CHANGECOLOR)    {
  515.                                 lp -= 3;
  516.                                 memmove(lp,lpp,3);
  517.                                 break;
  518.                             }
  519.                             --lpp;
  520.                         }
  521.                         break;
  522.                     }
  523.                     lpp++;
  524.                 }
  525.             }
  526.             lnlen = LineLength(lp);
  527.             len = min(lnlen, RectWidth(rc));
  528.             lnlen = LineLength(lp);
  529.             dif = strlen(lp) - lnlen;
  530.             len += dif;
  531.             if (len > 0)
  532.                 strncpy(line, lp, len);
  533.         }
  534.     }
  535.  
  536.     while (len < RectWidth(rc)+dif)
  537.         line[len++] = ' ';
  538.     line[len] = '\0';
  539.  
  540.     dif = 0;
  541.     if (reverse)    {
  542.         char *cp = line;
  543.         SetReverseColor(wnd);
  544.         while ((cp = strchr(cp, CHANGECOLOR)) != NULL)    {
  545.             cp += 2;
  546.             *cp++ = background | 0x80;
  547.         }
  548.         if (*(unsigned char *)line == CHANGECOLOR)
  549.             dif = 3;
  550.     }
  551.     else
  552.         SetStandardColor(wnd);
  553.     writeline(wnd, line+dif,
  554.                 RectLeft(rc)+BorderAdj(wnd),
  555.                     y-wnd->wtop+TopBorderAdj(wnd), FALSE);
  556.     if (svlp != NULL)
  557.         free(svlp);
  558. }
  559.  
  560. void SetAnchor(WINDOW wnd, int mx, int my)
  561. {
  562.     if (BlockMarked(wnd))    {
  563.         ClearBlock(wnd);
  564.         SendMessage(wnd, PAINT, 0, 0);
  565.     }
  566.     /* ------ set the anchor ------ */
  567.     wnd->BlkBegLine = wnd->BlkEndLine = my;
  568.     wnd->BlkBegCol = wnd->BlkEndCol = mx;
  569.     WriteTextLine(wnd, NULL, my, FALSE);
  570. }
  571.  
  572. void ClearTextPointers(WINDOW wnd)
  573. {
  574.     wnd->TextPointers = realloc(wnd->TextPointers, sizeof(int));
  575.     if (wnd->TextPointers != NULL)
  576.         *(wnd->TextPointers) = 0;
  577. }
  578.  
  579. #define INITLINES 100
  580.  
  581. void BuildTextPointers(WINDOW wnd)
  582. {
  583.     char *cp = wnd->text, *cp1;
  584.     int incrs = INITLINES;
  585.     int off;
  586.     wnd->textwidth = wnd->wlines = 0;
  587.     while (*cp)    {
  588.         if (incrs == INITLINES)    {
  589.             incrs = 0;
  590.             wnd->TextPointers = realloc(wnd->TextPointers,
  591.                     (wnd->wlines + INITLINES) * sizeof(int));
  592.             if (wnd->TextPointers == NULL)
  593.                 break;
  594.         }
  595.         off = (unsigned int) (cp - wnd->text);
  596.         *((wnd->TextPointers) + wnd->wlines) = off;
  597.         wnd->wlines++;
  598.         incrs++;
  599.         cp1 = cp;
  600.         while (*cp && *cp != '\n')
  601.             cp++;
  602.         wnd->textwidth = max(wnd->textwidth,
  603.                         (unsigned int) (cp - cp1));
  604.         if (*cp)
  605.             cp++;
  606.     }
  607. }
  608.  
  609. #ifdef INCLUDE_SCROLLBARS
  610. static void MoveScrollBox(WINDOW wnd, int vscrollbox)
  611. {
  612.     foreground = FrameForeground(wnd);
  613.     background = FrameBackground(wnd);
  614.     PutWindowChar(wnd, WindowWidth(wnd)-1,
  615.             wnd->VScrollBox+1, SCROLLBARCHAR);
  616.     PutWindowChar(wnd, WindowWidth(wnd)-1,
  617.             vscrollbox+1, SCROLLBOXCHAR);
  618.     wnd->VScrollBox = vscrollbox;
  619. }
  620. #endif
  621.