home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / code / wxwin140 / src / wx_text.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  16.0 KB  |  713 lines

  1. /*
  2.  * File:     wx_text.cc
  3.  * Purpose:  wxTextWindow implementation
  4.  *
  5.  *                       wxWindows 1.40
  6.  * Copyright (c) 1993 Artificial Intelligence Applications Institute,
  7.  *                   The University of Edinburgh
  8.  *
  9.  *                     Author: Julian Smart
  10.  *                       Date: 18-4-93
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose is hereby granted without fee, provided
  14.  * that the above copyright notice, author statement and this permission
  15.  * notice appear in all copies of this software and related documentation.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
  18.  * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
  19.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
  22.  * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
  23.  * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24.  * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
  25.  * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
  26.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <windows.h>
  30. #include <iostream.h>
  31. #include <fstream.h>
  32. #include <stdio.h>
  33.  
  34. #include "common.h"
  35. #include "wx_main.h"
  36. #include "wx_text.h"
  37. #include "wx_event.h"
  38. #include "wx_utils.h"
  39. #include "wx_frame.h"
  40. #include "wx_privt.h"
  41.  
  42. #ifdef wx_motif
  43. #include <Xm/Text.h>
  44. #include <sys/types.h>
  45. #include <sys/stat.h>
  46. #endif
  47.  
  48. #ifdef wx_xview
  49. #include <xview/textsw.h>
  50. #endif
  51.  
  52. #ifdef wx_msw
  53. class wxTextWnd : public wxSubWnd
  54. {
  55. public:
  56.   wxWindow *wx_window;
  57.   char **lines;
  58.   int no_lines;
  59.   int current_line;
  60.  
  61.   int cxChar;
  62.   int cyChar;
  63.  
  64.   int cxClient;
  65.   int cyClient;
  66.  
  67.   wxTextWnd(wxWnd *parent, wxWindow *wx_win,
  68.              int x, int y, int width, int height, DWORD style);
  69.   ~wxTextWnd();
  70.  
  71.   void CalcNewSize(int x, int y);
  72.  
  73.   void OnCreate(void);
  74.   BOOL OnPaint(void);
  75.   void OnSize(int x, int y, UINT);
  76.  
  77.   void WriteText(char *text);
  78.  
  79. };
  80. #endif
  81.  
  82. wxTextWindow::wxTextWindow(wxFrame *frame, int x, int y, int width, int height,
  83.                            int style)
  84. {
  85.   file_name = NULL;
  86.  
  87. #ifdef wx_motif
  88.   textPosition = 0;
  89.   textModified = FALSE;
  90.   int real_y = y;
  91.   Widget textWidget = XmCreateScrolledText(frame->workArea, "text_widget", NULL, 0);
  92.  
  93.   XtVaSetValues(textWidget, 
  94.                 XmNleftAttachment, XmATTACH_SELF,
  95.                 XmNrightAttachment, XmATTACH_SELF,
  96.                 XmNtopAttachment, XmATTACH_SELF,
  97.                 XmNbottomAttachment, XmATTACH_SELF,
  98.                 NULL);
  99.  
  100.   XtVaSetValues(textWidget,
  101.                 XmNeditable, True,
  102.                 XmNeditMode, XmMULTI_LINE_EDIT,
  103.                 NULL);
  104.  
  105.   wxWidgetHashTable->Put((long)textWidget, this);
  106.  
  107.   XtOverrideTranslations(textWidget,
  108.               XtParseTranslationTable("<Configure>: resize()"));
  109.  
  110.   Widget parent = XtParent(textWidget);
  111.   if (x > -1)
  112.     XtVaSetValues(parent,
  113.                   XmNleftAttachment, XmATTACH_SELF,
  114.                   XmNx, x,
  115.                   NULL);
  116.  
  117.   if (y > -1)
  118.     XtVaSetValues(parent,
  119.                   XmNtopAttachment, XmATTACH_SELF,
  120.                   XmNy, real_y,
  121.                   NULL);
  122.  
  123.   if (width > -1)
  124.     XtVaSetValues(parent, XmNwidth, width, NULL);
  125.   if (height > -1)
  126.     XtVaSetValues(parent, XmNheight, height, NULL);
  127.  
  128.   XtManageChild(textWidget);
  129.   handle = (char *)textWidget;
  130. #endif
  131. #ifdef wx_xview
  132.   int real_y = frame->y_offset;
  133.   if (y > -1)
  134.     real_y = y + frame->y_offset;  // Allow for possible menu bar
  135.  
  136.   Frame x_frame = (Frame)frame->handle;
  137.   Textsw x_textsw = (Textsw)xv_create(x_frame, TEXTSW,
  138.                             WIN_CLIENT_DATA, (char *)this, XV_SHOW, FALSE,
  139.                             TEXTSW_MEMORY_MAXIMUM, 400000,
  140.                             NULL);
  141.   handle = (char *)x_textsw;
  142.   window_parent = frame;
  143.   file_name = NULL;
  144.  
  145.   if (x > -1)
  146.     xv_set(x_textsw, XV_X, x, NULL);
  147.   if (y > -1)
  148.     xv_set(x_textsw, XV_Y, real_y, NULL);
  149.   if (width > -1)
  150.     xv_set(x_textsw, XV_WIDTH, width, NULL);
  151.   if (height > -1)
  152.     xv_set(x_textsw, XV_HEIGHT, height, NULL);
  153.  
  154.   xv_set(x_textsw, XV_SHOW, TRUE, NULL);
  155. #endif
  156.  
  157. #ifdef wx_msw
  158.   wxWinType = wxTYPE_XWND;
  159.   wxWnd *cparent = NULL;
  160.   if (frame)
  161.     cparent = (wxWnd *)frame->handle;
  162.  
  163.   DWORD ms_flags = WS_HSCROLL | WS_VSCROLL | WS_CHILD | WS_VISIBLE;
  164.   if (style & wxBORDER)
  165.     ms_flags |= WS_BORDER;
  166.   handle = (char *)new wxTextWnd(cparent, this, x, y, width, height, ms_flags);
  167.  
  168. #endif
  169.  
  170.   if (frame) frame->AddChild(this);
  171.   window_parent = frame;
  172. }
  173.  
  174. wxTextWindow::~wxTextWindow(void)
  175. {
  176. #ifdef wx_motif
  177. #endif
  178. #ifdef wx_xview
  179.   Textsw textsw = (Textsw)handle;
  180.  
  181.   textsw_reset(textsw, 0, 0);
  182. #endif
  183. }
  184.  
  185. Bool wxTextWindow::LoadFile(char *file)
  186. {
  187.   if (file_name)
  188.     delete file_name;
  189.  
  190.   file_name = copystring(file);
  191. #ifdef wx_motif
  192.   Widget textWidget = (Widget)handle;
  193.   FILE *fp;
  194.  
  195.   struct stat statb;
  196.   if ((stat(file, &statb) == -1) || (statb.st_mode & S_IFMT) != S_IFREG ||
  197.       !(fp = fopen(file, "r")))
  198.   {
  199.     return FALSE;
  200.   }
  201.   else
  202.   {
  203.     long len = statb.st_size;
  204.     char *text;
  205.     if (!(text = XtMalloc((unsigned)(len+1))))
  206.     {
  207.       fclose(fp);
  208.       return FALSE;
  209.     }
  210.     if (fread(text, sizeof(char), len, fp) != len)
  211.       {}
  212.     fclose(fp);
  213.  
  214.     text[len] = 0;
  215.     XmTextSetString(textWidget, text);
  216.     textPosition = len;
  217.     XtFree(text);
  218.     textModified = FALSE;
  219.     return TRUE;
  220.   }
  221. #endif
  222. #ifdef wx_xview
  223.  
  224.   Textsw textsw = (Textsw)handle;
  225.  
  226.   Textsw_status status;
  227.   xv_set(textsw, TEXTSW_STATUS, &status, TEXTSW_FILE, file_name, TEXTSW_FIRST, 0, NULL);
  228.  
  229.   return (status == TEXTSW_STATUS_OKAY);
  230. #endif
  231. #ifdef wx_msw
  232.  Clear();
  233.  
  234.  ifstream input(file);
  235.  if (!input.bad())
  236.  {
  237.    wxTextWnd *text_win = (wxTextWnd *)handle;
  238.    text_win->no_lines = 0;
  239.    while (!input.eof())
  240.    {
  241.      Bool eol = FALSE;
  242.      input.getline(wxBuffer, 500);
  243.      text_win->lines[text_win->no_lines] = copystring(wxBuffer);
  244.      text_win->no_lines ++;
  245.    }
  246.    if (text_win->no_lines > 0)
  247.      text_win->current_line = text_win->no_lines - 1;
  248.    else text_win->current_line = 0;
  249.  
  250.  
  251.    RECT rect;
  252.    GetClientRect(text_win->handle, &rect);
  253.    text_win->OnSize(rect.right, rect.bottom, 0);
  254.    InvalidateRgn(text_win->handle, NULL, TRUE);
  255.    UpdateWindow(text_win->handle);
  256.  
  257.    return TRUE;
  258.  }
  259.  return FALSE;
  260. #endif
  261. }
  262.  
  263. // If file is null, try saved file name first
  264. // Returns TRUE if succeeds.
  265. Bool wxTextWindow::SaveFile(char *file)
  266. {
  267. #ifdef wx_motif
  268.   Widget textWidget = (Widget)handle;
  269.   FILE *fp;
  270.  
  271.   if (!(fp = fopen(file, "w")))
  272.   {
  273.     return FALSE;
  274.   }
  275.   else
  276.   {
  277.     char *text = XmTextGetString(textWidget);
  278.     long len = XmTextGetLastPosition(textWidget);
  279.  
  280.     if (fwrite(text, sizeof(char), len, fp) != len)
  281.     {
  282.       // Did not write whole file
  283.     }
  284.     // Make sure newline terminates the file
  285.     if (text[len-1] != '\n')
  286.       fputc('\n', fp);
  287.  
  288.     fclose(fp);
  289.     XtFree(text);
  290.     textModified = FALSE;
  291.     return TRUE;
  292.   }
  293. #endif
  294. #ifdef wx_xview
  295.   Textsw textsw = (Textsw)handle;
  296.  
  297.   char *the_file = file;
  298.   if (!file)
  299.     the_file = file_name;
  300.  
  301.   if (the_file)
  302.     return !textsw_store_file(textsw, the_file, 100, 100);
  303.   else
  304.    return FALSE;
  305. #endif
  306.  
  307. #ifdef wx_msw
  308.   return 0;
  309. #endif
  310. }
  311.  
  312. void wxTextWindow::WriteText(char *text)
  313. {
  314. #ifdef wx_motif
  315.   Widget textWidget = (Widget)handle;
  316.   XmTextInsert(textWidget, textPosition, text);
  317.   textPosition += strlen(text);
  318.   XtVaSetValues(textWidget, XmNcursorPosition, textPosition, NULL);
  319.   XmTextShowPosition(textWidget, textPosition);
  320.   textModified = TRUE;
  321. #endif
  322. #ifdef wx_xview
  323.   Textsw textsw = (Textsw)handle;
  324.  
  325.   int l = strlen(text);
  326.   char *new_text = new char[l];
  327.   strcpy(new_text, text);
  328.   int i;
  329.  
  330.   // Convert new lines to something the textsw recognises
  331.   for (i = 0; i < l; i++)
  332.     if (new_text[i] == '\n')
  333.       new_text[i] = (char)10;
  334.  
  335.   xv_set(textsw, TEXTSW_INSERTION_POINT, TEXTSW_INFINITY, NULL);
  336.   textsw_insert(textsw, new_text, l);
  337.   delete new_text;
  338. #endif
  339. #ifdef wx_msw
  340.   char *the_text = copystring(text);  // Necessary in case text points to
  341.                                       // wxBuffer
  342.  
  343.   wxTextWnd *text_win = (wxTextWnd *)handle;
  344.   if (text_win->no_lines < wxTEXT_MAX_LINES)
  345.   {
  346.     int len = strlen(the_text);
  347.  
  348.     Bool text_end = FALSE;
  349.  
  350.     int i = 0;
  351.     while (!text_end)
  352.     {
  353.       int j = 0;
  354.       Bool eol = FALSE;
  355.       int old_line_length = strlen(text_win->lines[text_win->current_line]);
  356.       strcpy(wxBuffer, text_win->lines[text_win->current_line]);
  357.  
  358.       while (!eol && !text_end)
  359.       {
  360.         if (i == len)
  361.         {
  362.           wxBuffer[j+old_line_length] = 0;
  363.           text_end = TRUE;
  364.         }
  365.         else
  366.         {
  367.           char ch = the_text[i];
  368.  
  369.           if (ch == '\n' || (j+old_line_length) > 490)
  370.           {
  371.             eol = TRUE;
  372.             wxBuffer[j+old_line_length] = 0;
  373.             if ((j + old_line_length) > 490)
  374.             {
  375.               i --; j --;
  376.             }
  377.           }
  378.           else
  379.           {
  380.             wxBuffer[j+old_line_length] = ch;
  381.           }
  382.           i ++;
  383.           j ++;
  384.         }
  385.       }
  386.       delete text_win->lines[text_win->current_line];
  387.       text_win->lines[text_win->current_line] = copystring(wxBuffer);
  388.  
  389.       HDC dc = GetDC(text_win->handle);
  390.       SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
  391.       SetBkColor(dc, GetSysColor(COLOR_WINDOW));
  392.  
  393.       int x = (text_win->cxChar) * (1 - text_win->xscroll_position);
  394.       int y = (text_win->cyChar) * (text_win->current_line - text_win->yscroll_position);
  395.       TextOut(dc, x, y, wxBuffer, strlen(wxBuffer));
  396.       ReleaseDC(text_win->handle, dc);
  397.  
  398.       if (eol)
  399.       {
  400.         text_win->current_line ++;
  401.         text_win->no_lines ++;
  402.         text_win->lines[text_win->current_line] = new char[1];
  403.         text_win->lines[text_win->current_line][0] = 0;
  404.  
  405.         RECT rect;
  406.         GetClientRect(text_win->handle, &rect);
  407.         text_win->CalcNewSize(rect.right, rect.bottom);
  408.  
  409.         if (y >= (rect.bottom - text_win->cyChar))
  410.           text_win->OnVScroll(SB_BOTTOM, 0, NULL);
  411.  
  412.         (void)wxYield();
  413.       }
  414.     }
  415.  
  416.   }
  417.   delete the_text;
  418. #endif
  419. }
  420.  
  421. void wxTextWindow::SetSize(int x, int y, int w, int h)
  422. {
  423. #ifdef wx_motif
  424.   Widget textWidget = (Widget)handle;
  425.   int real_y = y;
  426.  
  427.   Widget parent = XtParent(textWidget);
  428.   if (x > -1)
  429.     XtVaSetValues(parent,
  430.                   XmNleftAttachment, XmATTACH_SELF,
  431.                   XmNx, x,
  432.                   NULL);
  433.  
  434.   if (y > -1)
  435.     XtVaSetValues(parent,
  436.                   XmNtopAttachment, XmATTACH_SELF,
  437.                   XmNy, real_y,
  438.                   NULL);
  439.  
  440.   if (w > -1)
  441.     XtVaSetValues(parent, XmNwidth, w, NULL);
  442.   if (h > -1)
  443.     XtVaSetValues(parent, XmNheight, h, NULL);
  444.  
  445.   Dimension yy;
  446.   XtVaGetValues(textWidget, XmNy, &yy, NULL);
  447. #endif
  448. #ifdef wx_xview
  449.   int currentX, currentY;
  450.   GetPosition(¤tX, ¤tY);
  451.   if (x == -1)
  452.     x = currentX;
  453.   if (y == -1)
  454.     y = currentY;
  455.  
  456.   int real_y = y;
  457.  
  458.   if (window_parent)
  459.     real_y += ((wxFrame *)window_parent)->y_offset;  // Allow for possible menu bar
  460.  
  461.   Xv_opaque object = (Xv_opaque)handle;
  462.   (void)xv_set(object, XV_X, x, XV_Y, real_y, XV_WIDTH, w, XV_HEIGHT, h, NULL);
  463. #endif
  464. #ifdef wx_msw
  465.   wxWnd *wnd = (wxWnd *)handle;
  466.   if (wnd)
  467.     MoveWindow(wnd->handle, x, y, w, h, TRUE);
  468. #endif
  469.   OnSize(w, h);
  470. }
  471.  
  472.  
  473. void wxTextWindow::Clear(void)
  474. {
  475. #ifdef wx_motif
  476.   XmTextSetString((Widget)handle, "");
  477.   textPosition = 0;
  478.   textModified = FALSE;
  479. #endif
  480. #ifdef wx_xview
  481.   Textsw textsw = (Textsw)handle;
  482.  
  483. //  textsw_delete(textsw, 0, TEXTSW_INFINITY);
  484.   textsw_reset(textsw, 0, 0);
  485. #endif
  486. #ifdef wx_msw
  487.   wxTextWnd *text_win = (wxTextWnd *)handle;
  488.   int i;
  489.   for (i = 0; i < text_win->no_lines; i++)
  490.   {
  491.     delete text_win->lines[i];
  492.     text_win->lines[i] = NULL;
  493.   }
  494.   text_win->lines[0] = new char[1];
  495.   text_win->lines[0][0] = 0;
  496.   text_win->no_lines = 1;
  497.   text_win->current_line = 0;
  498.  
  499.   RECT rect;
  500.   GetClientRect(text_win->handle, &rect);
  501.   text_win->OnSize(rect.right, rect.bottom, 0);
  502.   InvalidateRgn(text_win->handle, NULL, TRUE);
  503. #endif
  504. }
  505.  
  506. Bool wxTextWindow::Modified(void)
  507. {
  508. #ifdef wx_motif
  509.   return textModified;
  510. #endif
  511. #ifdef wx_xview
  512.   Textsw textsw = (Textsw)handle;
  513.   return (xv_get(textsw, TEXTSW_MODIFIED));
  514. #endif
  515. #ifdef wx_msw
  516.   return FALSE;
  517. #endif
  518. }
  519.  
  520. // Not clear whether Clear is required as well as DiscardEdits
  521. void wxTextWindow::DiscardEdits(void)
  522. {
  523. #ifdef wx_motif
  524.   XmTextSetString((Widget)handle, "");
  525.   textPosition = 0;
  526.   textModified = FALSE;
  527. #endif
  528. #ifdef wx_xview
  529.   Textsw textsw = (Textsw)handle;
  530.  
  531.   textsw_reset(textsw, 0, 0);
  532. #endif
  533. #ifdef wx_msw
  534.   Clear();
  535. #endif
  536. }
  537.  
  538. char *wxTextWindow::GetContents(void)
  539. {
  540. #ifdef wx_motif
  541.   return NULL;
  542. #endif
  543. #ifdef wx_xview
  544.   Textsw textsw = (Textsw)handle;
  545.   xv_set(textsw, TEXTSW_INSERTION_POINT, TEXTSW_INFINITY, NULL);
  546.   int last = (int)xv_get(textsw, TEXTSW_INSERTION_POINT);
  547.   char *buf = new char[last];
  548.   xv_get(textsw, TEXTSW_CONTENTS, 0, buf, last);
  549.   buf[last] = 0;
  550.   
  551.   return buf;
  552. #endif
  553. #ifdef wx_msw
  554.   return NULL;
  555. #endif
  556. }
  557.  
  558. wxTextWindow& wxTextWindow::operator<<(char *s)
  559. {
  560.   WriteText(s);
  561.   return *this;
  562. }
  563.  
  564. wxTextWindow& wxTextWindow::operator<<(float f)
  565. {
  566.   static char buf[100];
  567.   sprintf(buf, "%.2f", f);
  568.   WriteText(buf);
  569.   return *this;
  570. }
  571.  
  572. wxTextWindow& wxTextWindow::operator<<(double d)
  573. {
  574.   static char buf[100];
  575.   sprintf(buf, "%.2lf", d);
  576.   WriteText(buf);
  577.   return *this;
  578. }
  579.  
  580. wxTextWindow& wxTextWindow::operator<<(int i)
  581. {
  582.   static char buf[100];
  583.   sprintf(buf, "%i", i);
  584.   WriteText(buf);
  585.   return *this;
  586. }
  587.  
  588. wxTextWindow& wxTextWindow::operator<<(long i)
  589. {
  590.   static char buf[100];
  591.   sprintf(buf, "%ld", i);
  592.   WriteText(buf);
  593.   return *this;
  594. }
  595.  
  596. wxTextWindow& wxTextWindow::operator<<(char c)
  597. {
  598.   char buf[2];
  599.  
  600.   buf[0] = c;
  601.   buf[1] = 0;
  602.   WriteText(buf);
  603.   return *this;
  604. }
  605.  
  606. #ifdef wx_msw
  607. wxTextWnd::wxTextWnd(wxWnd *parent, wxWindow *wx_win,
  608.                        int x, int y, int width, int height, DWORD style):
  609.   wxSubWnd(parent, "wxCanvasClass", wx_win, x, y, width, height, style)
  610. {
  611.   no_lines = 1;
  612.   current_line = 0;
  613.   lines = new char *[wxTEXT_MAX_LINES];
  614.   lines[0] = new char[1];
  615.   lines[0][0] = 0;
  616.  
  617.   OnCreate();
  618.   ShowScrollBar(handle, SB_BOTH, TRUE);
  619. }
  620.  
  621. wxTextWnd::~wxTextWnd()
  622. {
  623.   if (lines)
  624.   {
  625.     int i;
  626.     for (i = 0; i < no_lines; i++)
  627.     {
  628.       delete lines[i];
  629.       lines[i] = NULL;
  630.     }
  631.     delete lines;
  632.   }
  633. }
  634.  
  635. BOOL wxTextWnd::OnPaint()
  636. {
  637.   RECT rect;
  638.   if (GetUpdateRect(handle, &rect, FALSE))
  639.   {
  640.     PAINTSTRUCT ps;
  641.     // Hold a pointer to the dc so long as the OnPaint() message
  642.     // is being processed
  643.     HDC dc = BeginPaint(handle, &ps);
  644.  
  645.     ::SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
  646.     ::SetBkColor(dc, GetSysColor(COLOR_WINDOW));
  647.  
  648.     HBRUSH brush = GetStockObject(WHITE_BRUSH);
  649.     ::FillRect(dc, &rect, brush);
  650.  
  651.     int nStart = yscroll_position;
  652.     int nEnd = min(no_lines, yscroll_position + (rect.bottom/cyChar));
  653.  
  654.     int i;
  655.     int x,y;
  656.     for (i = nStart; i < nEnd; i++)
  657.     {
  658.       x = cxChar * (1 - xscroll_position);
  659.       y = cyChar * (i - yscroll_position);
  660.       TextOut(dc, x, y, lines[i], strlen(lines[i]));
  661.     }
  662.  
  663.     EndPaint(handle, &ps);
  664.     return 0;
  665.   }
  666.   return 1;
  667. }
  668.  
  669. void wxTextWnd::OnCreate(void)
  670. {
  671.   TEXTMETRIC tm;
  672.   HDC dc = GetDC(handle);
  673.   GetTextMetrics(dc, &tm);
  674.   ReleaseDC(handle, dc);
  675.   cxChar = tm.tmAveCharWidth;
  676.   cyChar = tm.tmHeight + tm.tmExternalLeading;
  677.   yscroll_pixels_per_line = cyChar;
  678.   xscroll_pixels_per_line = cxChar;
  679.   xscroll_lines = 300;
  680.   yscroll_lines = 0;
  681.   ReleaseDC(handle, dc);
  682. }
  683.  
  684. void wxTextWnd::OnSize(int x, int y, UINT)
  685. {
  686.   CalcNewSize(x, y);
  687.   InvalidateRgn(handle, NULL, TRUE);
  688. }
  689.  
  690. void wxTextWnd::CalcNewSize(int x, int y)
  691. {
  692.   cxClient = x;
  693.   cyClient = y;
  694.  
  695.   int nMaxWidth = xscroll_lines*xscroll_pixels_per_line;
  696.  
  697.   int nVscrollMax = max(0, (int)(no_lines + 2 - cyClient/cyChar));
  698.   yscroll_position = min(yscroll_position, nVscrollMax);
  699.  
  700.   SetScrollRange(handle, SB_VERT, 0, nVscrollMax, FALSE);
  701.   SetScrollPos(handle, SB_VERT, yscroll_position, TRUE);
  702.  
  703.   int nHscrollMax = max(0, (int)(2 + nMaxWidth - cxClient/cxChar));
  704.   xscroll_position = min(xscroll_position, nHscrollMax);
  705.  
  706.   SetScrollRange(handle, SB_HORZ, 0, nHscrollMax, FALSE);
  707.   SetScrollPos(handle, SB_HORZ, xscroll_position, TRUE);
  708.  
  709.   yscroll_lines = no_lines;
  710. }
  711. #endif
  712.  
  713.