home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / OWL1.PAK / EDIT.CPP < prev    next >
Text File  |  1995-08-29  |  13KB  |  430 lines

  1. // ObjectWindows - (C) Copyright 1992 by Borland International
  2.  
  3. /* --------------------------------------------------------
  4.   EDIT.CPP
  5.   Defines type TEdit.  This defines the basic behavior
  6.   of all edit controls.
  7.   -------------------------------------------------------- */
  8.  
  9. #include <dos.h>
  10. #include <string.h>
  11. #include <alloc.h>
  12. #include "edit.h"
  13.  
  14. /* Constructor for a TEdit object. Initializes its data fields using
  15.    passed parameters and default values. By default, an associated
  16.    static control will have a border and its text will be left-justified.
  17.    Also by default, an associated multiline edit control will have
  18.    horizontal and vertical scroll bars */
  19. TEdit::TEdit(PTWindowsObject AParent, int AnId, LPSTR ATitle, int X,
  20.              int Y, int W, int H, WORD ATextLen, BOOL Multiline,
  21.              PTModule AModule)
  22.       : TStatic(AParent, AnId, ATitle, X, Y, W, H, ATextLen, AModule)
  23. {
  24.   // undo the styles set by TStatic
  25.   Attr.Style = (Attr.Style & ~SS_LEFT) | WS_TABSTOP;
  26.  
  27.   Attr.Style |= ES_LEFT | ES_AUTOHSCROLL | WS_BORDER;
  28.   if ( Multiline )
  29.     Attr.Style |= ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL |
  30.                   WS_HSCROLL;
  31. }
  32.  
  33. /* Constructor for a TEdit to be associated with a MS-Windows
  34.   interface element created by MS-Windows from a resource definition.
  35.   Initializes its data fields using passed parameters.  Data transfer
  36.   is enabled, by default, for the TEdit. */
  37. TEdit::TEdit(PTWindowsObject AParent, int ResourceId, WORD TextLen,
  38.              PTModule AModule)
  39.       : TStatic(AParent, ResourceId, TextLen, AModule)
  40. {
  41.   EnableTransfer();
  42. }
  43.  
  44. /* Returns a BOOL value indicating whether or not the last change
  45.    to the text of the associated edit control can be undone.  */
  46. BOOL TEdit::CanUndo()
  47. {
  48.   return SendMessage(HWindow, EM_CANUNDO, 0, 0) != 0;
  49. }
  50.  
  51. /* Undoes the last change to the to the text of the associated
  52.    edit control. */
  53. void TEdit::Undo()
  54. {
  55.   SendMessage(HWindow, WM_UNDO, 0, 0);
  56. }
  57.  
  58. /* Pastes the contents of the clipboard into the text of the associated
  59.   edit control. */
  60. void TEdit::Paste()
  61. {
  62.   SendMessage(HWindow, WM_PASTE, 0, 0);
  63. }
  64.  
  65. /* Copies the text selected in the associated edit control to the
  66.   clipboard. */
  67. void TEdit::Copy()
  68. {
  69.   SendMessage(HWindow, WM_COPY, 0, 0);
  70. }
  71.  
  72. /* Cuts the text selected in the associated edit control into the
  73.   clipboard. */
  74. void TEdit::Cut()
  75. {
  76.   SendMessage(HWindow, WM_CUT, 0, 0);
  77. }
  78.  
  79. // virtual response functions
  80.  
  81. /* Responds to an incoming "Cut" command (with a CM_EDITCUT command
  82.   identifier) by calling Cut. */
  83. void TEdit::CMEditCut (TMessage&)
  84. {
  85.   Cut();
  86. }
  87.  
  88. /* Responds to an incoming "Copy" command (with a CM_EDITCOPY command
  89.   identifier) by calling Copy. */
  90. void TEdit::CMEditCopy (TMessage&)
  91. {
  92.   Copy();
  93. }
  94.  
  95. /* Responds to an incoming "Paste" command (with a CM_EDITPASTE command
  96.   identifier) by calling Paste. */
  97. void TEdit::CMEditPaste(TMessage&)
  98. {
  99.   Paste();
  100. }
  101.  
  102. /* Responds to an incoming "Delete" command (with a CM_EDITDELETE
  103.    command identifier) by calling DeleteSelection. */
  104. void TEdit::CMEditDelete(TMessage&)
  105. {
  106.   DeleteSelection();
  107. }
  108.  
  109. /* Responds to an incoming "Clear" command (with a CM_EDITCLEAR command
  110.   identifier) by calling Clear. */
  111. void TEdit::CMEditClear(TMessage&)
  112. {
  113.   Clear();
  114. }
  115.  
  116. /* Responds to an incoming "Undo" command (with a CM_EDITUNDO command
  117.   identifier) by calling Undo. */
  118. void TEdit::CMEditUndo(TMessage&)
  119. {
  120.   Undo();
  121. }
  122.  
  123. /* Beeps when edit control runs out of space */
  124. void TEdit::ENErrSpace(TMessage& Msg)
  125. {
  126.   MessageBeep(0);
  127.   DefNotificationProc(Msg);
  128. }
  129.  
  130. /* Returns the number of lines in the associated edit control. Note that
  131.    GetNumLines returns 1 when the edit control has no text (i.e. it has
  132.    one line with no text in it). Returns zero if an error occurs. */
  133. int TEdit::GetNumLines()
  134. {
  135.   return (WORD)SendMessage(HWindow, EM_GETLINECOUNT, 0, 0);
  136. }
  137.  
  138. /* Returns the length of the line (whose number is passed) in the
  139.  associated edit control.  If -1 is passed as the line number, the
  140.  following applies: returns the length of the line upon which the caret
  141.  is positioned; if text is selected on the line, returns the line length
  142.  minus the number of selected characters; if selected text spans more
  143.  than one line,  returns the length of the lines minus the number of
  144.  selected characters. */
  145. int TEdit::GetLineLength(int LineNumber)
  146. {
  147.   int StartPos = -1;
  148.  
  149.   if ( LineNumber > -1 )
  150.     StartPos = GetLineIndex(LineNumber);
  151.   return (WORD)SendMessage(HWindow, EM_LINELENGTH, StartPos, 0);
  152. }
  153.  
  154. /* Retrieves the text of the line of the associated edit control
  155.    with the passed line number.  Return FALSE if an error occurs
  156.    or if the text did not completely fit in the passed buffer.
  157.    The returned string is null-terminated. */
  158. BOOL TEdit::GetLine(LPSTR ATextString, int StrSize, int LineNumber)
  159. {
  160.   int BytesCopied;
  161.   BOOL Success;
  162.  
  163.   if ( StrSize <= 0 )
  164.     return FALSE;
  165.  
  166.   if ( (StrSize >= GetLineLength(LineNumber) + 1) )
  167.     Success = TRUE;
  168.   else
  169.     Success = FALSE;
  170.  
  171.   if ( StrSize == 1 )
  172.   {
  173.     ATextString[0] = '\0';
  174.     return Success;
  175.   }
  176.  
  177.   ((WORD FAR *)ATextString)[0] = StrSize;
  178.  
  179.   BytesCopied = (WORD)(SendMessage(HWindow, EM_GETLINE,
  180.                                    LineNumber, long(ATextString)));
  181.   if ( BytesCopied != 0 )
  182.   {
  183.     ATextString[BytesCopied] = '\0'; // Windows returns non-null terminated string
  184.     return Success;
  185.   }
  186.   return FALSE;
  187. }
  188.  
  189. /* Selects the text in the associated edit control which begins
  190.    and ends at the passed positions. */
  191. BOOL TEdit::SetSelection(int StartPos, int EndPos)
  192. {
  193.   return (SendMessage(HWindow, EM_SETSEL, 0, MAKELONG(StartPos,EndPos)) != 0);
  194. }
  195.  
  196. /* Returns, in the passed var parameters, the starting and
  197.    ending positions of the text selected in the associated
  198.    edit control. */
  199. void TEdit::GetSelection(int& StartPos, int& EndPos)
  200. {
  201.     long RetValue;
  202.  
  203.     RetValue = SendMessage(HWindow, EM_GETSEL, 0, 0);
  204.     StartPos = LOWORD(RetValue);
  205.     EndPos   = HIWORD(RetValue);
  206. }
  207.  
  208. /* Returns a BOOL value indicating whether or not the user has
  209.    changed the text in the associated edit control. */
  210. BOOL TEdit::IsModified()
  211. {
  212.   return (SendMessage(HWindow, EM_GETMODIFY, 0, 0) != 0);
  213. }
  214.  
  215. /* Clears the change flag for the associated edit control. */
  216. void TEdit::ClearModify()
  217. {
  218.   SendMessage(HWindow, EM_SETMODIFY, 0, 0);
  219. }
  220.  
  221. /* Returns the number of the line of the associated edit control which
  222.   contains the character whose position is passed.  If the position
  223.   passed is greater than the position of the last character, the number
  224.   of the last line is returned. If -1 is passed, the number of the line
  225.   which contains the first selected character is returned. */
  226. int TEdit::GetLineFromPos(int CharPos)
  227. {
  228.   return (int)SendMessage(HWindow, EM_LINEFROMCHAR, CharPos, 0L);
  229. }
  230.  
  231. /* Returns the number of characters in the associated edit control that
  232.   occur before the line whose number is passed.  If -1 is passed, the
  233.   line number of the line upon which the caret is positioned is used. */
  234. int TEdit::GetLineIndex(int LineNumber)
  235. {
  236.     return  (WORD)SendMessage(HWindow, EM_LINEINDEX, LineNumber, 0);
  237. }
  238.  
  239. /* Scrolls the text of the associated edit control by the
  240.   specified horizontal and vertical amounts. */
  241. void TEdit::Scroll(int HorizontalUnit, int VerticalUnit)
  242. {
  243.     SendMessage(HWindow, EM_LINESCROLL, 0,
  244.                 MAKELONG(VerticalUnit, HorizontalUnit));
  245. }
  246.  
  247. /* Sets the selection of the associated edit control to
  248.    the passed string. (Does a "paste" type of action
  249.    without affecting the clipboard). */
  250. void TEdit::Insert(LPSTR ATextString)
  251. {
  252.   SendMessage(HWindow, EM_REPLACESEL, 0, (long)ATextString);
  253. }
  254.  
  255. /* Searchs for and selects the given text in the edit control and
  256.   returns the offset of the text or -1 if the text is not found.
  257.   If the StartPos = -1 then it is assumed that the start pos is
  258.   the end of the current selection. */
  259. int TEdit::Search(int StartPos, LPSTR AText, BOOL CaseSensitive)
  260. {
  261.   LPSTR SText, Line = NULL, Pos = NULL;
  262.   int LineSize = 0, LineLen, NumLines, CurLine, Offset, SBeg;
  263.  
  264.   if ( AText[0] == '\0' )
  265.     return -1;
  266.   if ( StartPos == -1 )
  267.     GetSelection(SBeg, StartPos);
  268.   if ( !CaseSensitive )
  269.     SText = AnsiLower(_fstrdup(AText));
  270.   else
  271.     SText = AText;
  272.   CurLine = GetLineFromPos(StartPos);
  273.   Offset = StartPos - GetLineIndex(CurLine);
  274.   NumLines = GetNumLines();
  275.   while ( CurLine < NumLines )
  276.   {
  277.     LineLen = GetLineLength(CurLine);
  278.     if ( LineLen >= LineSize )
  279.     {
  280.       LineSize = LineLen + 1;
  281.       Line = (LPSTR)farrealloc(Line, LineSize);
  282.     }
  283.     if ( Line == NULL )
  284.       return -1;
  285.     GetLine(Line, LineSize, CurLine);
  286.     if ( !CaseSensitive )
  287.       AnsiLower(Line);
  288.     Pos = _fstrstr(&Line[Offset], SText);
  289.     if ( Pos )
  290.     {
  291.       SBeg = (int)(GetLineIndex(CurLine) + (Pos - Line));
  292.       SetSelection(SBeg, SBeg + _fstrlen(SText));
  293.       break;
  294.     }
  295.     Offset = 0;
  296.     CurLine++;
  297.   }
  298.   if ( Line )
  299.     farfree(Line);
  300.   if ( !CaseSensitive )
  301.     farfree(SText);
  302.   if ( Pos )
  303.     return SBeg;
  304.   else
  305.     return -1;
  306. }
  307.  
  308.  
  309. /* Deletes the selected text in the associated edit control.  Returns
  310.   FALSE if no text is selected. */
  311. BOOL TEdit::DeleteSelection()
  312. {
  313.     int StartPos , EndPos;
  314.  
  315.     GetSelection(StartPos, EndPos);
  316.     if ( StartPos != EndPos )
  317.     {
  318.     SendMessage(HWindow, WM_CLEAR, 0, 0);
  319.     return TRUE;
  320.     }
  321.     return FALSE;
  322. }
  323.  
  324. /* Deletes the text of the associated edit control between
  325.    the passed positions.  Returns FALSE if an error occurs. */
  326. BOOL TEdit::DeleteSubText(int StartPos, int EndPos)
  327. {
  328.     if ( SetSelection(StartPos, EndPos) )
  329.         return DeleteSelection();
  330.     else
  331.       return FALSE;
  332. }
  333.  
  334. /* Deletes the text at the passed line number in the associated edit
  335.   control.  If -1 is passed, deletes the current line.  Returns False
  336.   if the line passed is out of range (and not -1) or if an error occurs. */
  337. BOOL TEdit::DeleteLine(int LineNumber)
  338. {
  339.   int FirstPos , LastPos;
  340.  
  341.   if ( LineNumber == -1 )
  342.     LineNumber = GetLineFromPos(GetLineIndex(-1));
  343.   FirstPos = GetLineIndex(LineNumber);
  344.   if ( FirstPos != -1 )
  345.   {
  346.     LastPos = GetLineIndex(LineNumber + 1);
  347.     if ( LastPos == -1 )
  348.       LastPos = FirstPos + GetLineLength(LineNumber);
  349.     if ( FirstPos == 0  && FirstPos == LastPos )
  350.     {
  351.       SetText("");
  352.     return TRUE;
  353.     }
  354.     else
  355.     return DeleteSubText(FirstPos, LastPos);
  356.   }
  357.   return FALSE;
  358. }
  359.  
  360. /* Retrieves the text of the associated edit control between the passed
  361.   positions. */
  362. void TEdit::GetSubText(LPSTR ATextString,int StartPos,int EndPos)
  363. {
  364.   int StartLine , EndLine , StartChar , EndChar;
  365.   int TempSize , TempIndex = 0 , TempStart , TempEnd;
  366.   int TempLine , TempLineLength;
  367.   BOOL OkToContinue = TRUE;
  368.   Pchar PLine;
  369.  
  370.   if ( EndPos >= StartPos )
  371.   {
  372.     StartLine = GetLineFromPos(StartPos);
  373.     EndLine = GetLineFromPos(EndPos);
  374.     StartChar = StartPos - GetLineIndex(StartLine);
  375.     EndChar = EndPos - GetLineIndex(EndLine);
  376.     for (TempLine = StartLine; TempLine <= EndLine; ++TempLine)
  377.       if ( OkToContinue )
  378.       {
  379.         TempLineLength = GetLineLength(TempLine);
  380.       PLine = new char [TempLineLength+1];
  381.         if ( TempLine == StartLine )
  382.           TempStart = StartChar;
  383.         else
  384.           TempStart = 0;
  385.         if ( TempLine == EndLine )
  386.           TempEnd = (EndChar>TempLineLength) ? TempLineLength : EndChar;
  387.         else
  388.           TempEnd = TempLineLength;
  389.         TempSize = TempEnd - TempStart;
  390.         if ( GetLine(PLine, TempLineLength + 1, TempLine) )
  391.         {
  392.             // Can happen if we're indexing the CR/LF
  393.             if (TempSize>0)
  394.             {
  395.                 movedata(FP_SEG(&PLine[TempStart]),
  396.                          FP_OFF(&PLine[TempStart]),
  397.                          FP_SEG(&ATextString[TempIndex]),
  398.                          FP_OFF(&ATextString[TempIndex]), TempSize );
  399.                 TempIndex += TempSize;
  400.             }
  401.             if ( TempLine != EndLine )
  402.             {
  403.                 ATextString[TempIndex++] = 0x0d;  // CR
  404.                 ATextString[TempIndex++] = 0x0a;  // LF
  405.             }
  406.         }
  407.         else
  408.           OkToContinue = FALSE;
  409.     delete PLine;
  410.       } // if OkToContinue (and for loop)
  411.   }
  412.   ATextString[TempIndex] = '\0';
  413. }
  414.  
  415. /* Limits the amount of text that an edit control can have to the
  416.   value of TextLen */
  417. void TEdit::SetupWindow()
  418. {
  419.   TStatic::SetupWindow();
  420.   if ( TextLen != 0 )
  421.     SendMessage(HWindow, EM_LIMITTEXT, TextLen - 1, 0);
  422. }
  423.  
  424. TStreamable *TEdit::build()
  425. {
  426.   return new TEdit(streamableInit);
  427. }
  428.  
  429. TStreamableClass RegEdit("TEdit", TEdit::build, __DELTA(TEdit));
  430.