xHarbour Reference Documentation > Function Reference |
Displays and/or edits character strings and memo fields in text mode.
MemoEdit( [<cString>] , ; [<nTop>] , ; [<nLeft>] , ; [<nBottom>] , ; [<nRight>] , ; [<lEditMode>] , ; [<cUserFunc>] , ; [<nLineLen>] , ; [<nTabSize>] , ; [<nBufferRow>], ; [<nBufferCol>], ; [<nRowOffset>], ; [<nColOffset>] ) --> cTextBuffer
As an alternative, the value .F. (false) can be passed for <cUserFunc>. This causes MemoEdit() to display <cString> in the specified rectangle and return immediately. The passed string can neither be scrolled nor edited.
If a single text line in the text buffer contains more than <nLineLen> characters, the text line is word wrapped.
If <nLineLen> is specified as being larger than <nRight> - <nLeft> of the display rectangle, and the user navigates the text cursor to a column position beyond the coordinates of the MemoEdit() rectangle, the displayed text is scrolled horizontally.
The return value of MemoEdit() depends on the key a user pressed to terminate the function.
Alt+W | When the user pressed the key combination Alt+W (K_ALT_W), the edited text buffer is returned as a character string. |
Esc | When the user pressed the Escape key (K_ESC), the return value is a copy of <cString>. |
MemoEdit() is a function for editing character strings, or memo fields, in console windows or full screen applications. The function provides a character oriented user interface and processes user input for editing text. Similar to AChoice() and DbEdit(), MemoEdit() employs a standard behaviour that can be configured by a user defined function <cUserFunc>.
Altough MemoEdit() is equipped with an extensive parameter profile, it is simple to use since all parameters are optional. The simplest form of using MemoEdit() is given by this line of code:
cText := MemoEdit()
Assigning the return value of MemoEdit() to a memory variable invokes the standard text editing behaviour of the function, i.e. the entire console window, or screen, is used for displaying the internal text buffer. The edited text is assigned to a memory variable when the user terminates text editing by pressing Alt+W. If text editing is ended with the Escape key, MemoEdit() returns an unchanged copy of <cString>.
It is important to understand that the user edits only the internal text buffer. This internal buffer is filled with a copy of parameter <cString>, if specified. All other parameters for row and column coordinates change the default (initial) display of the rectangle where text is displayed and can be edited by the user.
Whether or not MemoEdit() exposes standard or user-configured text editing behavior depends on the parameter <cUserFunc>, which is a character string containing the name of a user defined function.
MemoEdit() without user function
In its standard behavior, MemoEdit() processes the keys listed in the following table:
Standard key processing of MemoEdit()
Key | Description |
---|---|
Navigation in the text buffer | |
Up (Ctrl+E) | Go to previous line |
Down (Ctrl+X) | Go to next line |
Left (Ctrl+S) | Go to previous character |
Right(Ctrl+D) | Go to next character |
Ctrl+Left (Ctrl+A) | Go to previous word |
Ctrl+Right (Ctrl+F) | Go to next word |
Home | Go to begin-of-line |
End | Go to end-of-line |
Ctrl+Home | Go to first displayed line |
Ctrl+End | Go to last displayed line |
PgUp | Go to previous page |
PgDn | Go to next page |
Ctrl+PgUp | Go to first line |
Ctrl+PgDn | Go to last line |
Editing the text buffer | |
Printable characters | Insert character |
Return | Begin a new paragraph |
Delete | Delete character at cursor |
Backspace | Delete character to left of cursor |
Tab | Insert tab character or spaces |
Ctrl+Y | Delete the current line |
Ctrl+T | Delete word right |
Ctrl+B | Reformat paragraph |
Ctrl+V (Ins) | Toggle insert/overstrike mode |
Alt+W | Terminate editing with changes |
Esc | Terminate editing without changes |
Keys are grouped into the tasks navigation within the text buffer and editing it. MemoEdit() supports insert and overstrike modes, which is toggled by the Ins key. An automatic word wrap is applied to the text buffer when the number of characters entered in the current text line exceeds the value for parameter <nLineLen>. This word wrap is marked in the text buffer with a so called "Soft carriage return" (Chr(141)) which indicates the end-of-line, not the end-of-paragraph. The latter is marked in the text when the user presses the Return key. This inserts a "Hard carriage return" (Chr(13)) into the text buffer.
Note that "Soft carriage returns" remain in the text returned my MemoEdit(). When this text is output to a printer, or processed otherwise, it may be necessary to replace "Soft carriage returns" with blank spaces or "Hard carriage returns". The functions HardCR(), MemoTran() or StrTran() can be used to accomplish this.
MemoEdit() with user function
If a user function <cUserFunc> is specified, the standard editing behavior of MemoEdit() becomes configurable. For this, MemoEdit() distinguishes non-configurable keys from key-exceptions. The function applies its default action to the text buffer, when non-configurable keys are pressed. The user function is called for keys that yield an exception, and the return value of the user function instructs MemoEdit() how to process such a key. If there are no more keys pending in the keyboard buffer, the user function is called once again. As a consequence, the user function is called during different MemoEdit() modes.
The user function receives three numeric values from MemoEdit(): the current MemoEdit() mode, the current row, and the current column of the text buffer. #define constants are available in MEMOEDIT.CH that identify the different modes of MemoEdit().
MemoEdit() modes
Constant | Mode | Description |
---|---|---|
ME_IDLE | 0 | MemoEdit() is idle, all keys are processed |
ME_UNKEY | 1 | Unknown key, text buffer is unaltered |
ME_UNKEYX | 2 | Unknown key, text buffer is altered |
ME_INIT | 3 | Initialization mode |
ME_INIT | The user function is called for the first time when MemoEdit() is invoked. At this point, MemoEdit() is initializing its text buffer and has not displayed it yet. The return value of the user function can be used at this stage to initialize word wrapping or the scrolling mode of MemoEdit() (see ME_TOGGLEWRAP and ME_TOGGLESCROLL in the table further down). The user function is called repeatedly in the initialization stage of MemoEdit() until the value ME_DEFAULT (0) is returned. After this, the text buffer is displayed and MemoEdit() continues key processing according to <lEditMode>. That is, if <lEditMode> is .F. (false), the user can scroll the text but cannot edit it. |
ME_UNKEY | This mode tells the user function that a configurable (unknown) key is pressed and the text buffer is not altered, yet. The return value of the user function instructs MemoEdit() how to treat a configurable key. Use function LastKey() to obtain the Inkey code of such key. |
Configurable keys of MemoEdit()
Key | Default key processing |
---|---|
Ctrl+Y | Delete the current line |
Ctrl+T | Delete word right |
Ctrl+B | Reformat paragraph |
Ctrl+V (Ins) | Toggle insert/overstrike mode |
Alt+W | Terminate editing with changes |
Esc | Terminate editing without changes |
Returning ME_DEFAULT (0) from the user function for a configurable key instructs MemoEdit() to perform its default action. A different return value causes a different action, thus redefines the key (return values from the user function are explained further down). |
ME_UNKEYX | The same as ME_UNKEY, but the text buffer is altered. |
ME_IDLE | There are no more keys avalable in the keyboard buffer for processing. MemoEdit() calls the user function once in this situation and enters a wait state afterwards, until a new key is pressed. This mode is usually used to update row and column numbers on the screen if this information is presented to the user. |
The second parameter passed to the user function is the current row in the text buffer. Rows are numbered beginning with 1.
The third parameter passed to the user function is the current column in the text buffer. Columns are numbered beginning with 0.
During the modes ME_INIT, ME_UNKEY and ME_UNKEYX, the return value of the user function instructs MemoEdit() what action to take for the pressed key. There are several #define constants available in MEMOEDIT.CH for this purpose.
Return values for the MemoEdit() user function
Constant | Value | Description |
---|---|---|
ME_DEFAULT | 0 | Perform default action |
ME_UNKEY | 1-31 | Process requested action corresponding to key code |
ME_IGNORE | 32 | Ignore unknown key |
ME_DATA | 33 | Treat unknown key as data |
ME_TOGGLEWRAP | 34 | Toggle word wrap mode |
ME_TOGGLESCROLL | 35 | Toggle scroll mode |
ME_WORDRIGHT | 100 | Perform word-right operation |
ME_BOTTOMRIGHT | 101 | Perform bottom-right operation |
See also: | HardCR(), MemoLine(), MemoRead(), MemoTran(), MemoWrit(), StrTran() |
Category: | Character functions , Memo functions , UI functions |
Header: | inkey.ch, memoedit.ch |
Source: | rtl\memoedit.prg |
LIB: | xhb.lib |
DLL: | xhbdll.dll |
// The example implements a simple file editor using MemoEdit() // with user function. The user function displays status information // and configures the Alt+S (Save) and Alt+C (Cancel) as termination // keys #include "Inkey.ch" #include "Memoedit.ch" STATIC slChanged := .F. PROCEDURE Main( cFileName ) LOCAL cScreen LOCAL cText := "" SAVE SCREEN TO cScreen SET SCOREBOARD OFF SetCancel( .F. ) CLS IF .NOT. Empty( cFileName ) .AND. File( cFileName ) cText := MemoRead( cFileName ) ENDIF @ 0, 0 TO MaxRow(), MaxCol() DOUBLE cText := MemoEdit( cText, ; 1, 1 , ; MaxRow()-1, MaxCol()-1, ; .T., "USERFUNC" ) IF .NOT. Empty( cFileName ) .AND. ; File( cFileName ) .AND. ; slChanged .AND. ; Alert( "Save changes?", { "Yes", "No" } ) == 1 // remove "soft carriage return/line feeds" cText := StrTran( cText, Chr(141)+Chr(10), " " ) // save file MemoWrit( cFileName, cText ) ENDIF RESTORE SCREEN FROM cScreen RETURN FUNCTION UserFunc( nMode, nRow, nCol ) LOCAL nKey := LastKey() LOCAL nRet := ME_DEFAULT LOCAL cInfo := "" DO CASE CASE nMode == ME_INIT Set( _SET_INSERT, .F. ) // start in overstrike mode CASE nMode == ME_IDLE IF nKey > 31 .AND. nKey < 256 slChanged := .T. ENDIF cInfo := "[row: " + LTrim(Str(nRow)) cInfo += " col: " + LTrim(Str(nCol))+"]" cInfo += Chr(205)+Chr(205) IF Set( _SET_INSERT ) cInfo += "[Ins]" ELSE cInfo += "[Ovr]" ENDIF IF slChanged cInfo += Chr(205)+Chr(205)+"[Chg]" ENDIF @ MaxRow(), 2 SAY cInfo + Replicate(Chr(205),6) CASE nMode == ME_UNKEY .OR. nMode == ME_UNKEYX // buffer is changed slChanged := ( nMode == ME_UNKEYX ) DO CASE CASE nKey IN { K_ALT_W, K_CTRL_W, K_ESC } nRet := ME_IGNORE // ignore default termination keys CASE nKey == K_ALT_S nRet := K_ALT_W // Save with Alt+S CASE nKey == K_ALT_C nRet := K_ESC // Cancel with Alt+C slChanged := .F. ENDCASE ENDCASE RETURN nRet
http://www.xHarbour.com