Function MlCtoPos() Foundation
Determines the position of a character in a formatted character string.
MlCtoPos( <cString> , ;
<nLineLen> , ;
<nRow> , ;
<nCol> , ;
[<nTabSize>], ;
[<lWrap>] ) --> nPosition
The function MlCtoPos() calculates the position of a character in the formatted character string <cString> based on the specified row and column. The character position counter begins with the value one.
The memo function MlCtoPos() determines the exact position of a character in a formatted character string based on row and column position within the text. Formatting characters like tab (Chr(9)) and return are considered in determining the return value. The row position begins with the value one and the column position begins with zero. The counter for the return value (position of the character in <cString>) begins with one. Further processing can be performed using SubStr() based on this position.
The function MlCtoPos() is often used with MPostoLc(). For example, these functions might be used to program text search routines for MemoEdit().
// The example shows an extensive MemoEdit() routine using a
// user function. From the user function a search routine
// can be started with Alt+S. In the UDF MemoSeek(), a search
// expression is input by the user. When the expression
// is found, the cursor is positioned in the MemoEdit() text buffer
// on the first character in the search expression. Note the
// STATIC file-wide variables.
#include "Inkey.ch"
#include "Setcurs.ch"
#include "Memoedit.ch"
STATIC snWinRow , snWinCol, snBuffRow, snBuffCol
STATIC snTop , snLeft , snBottom , snRight
STATIC slExit := .F.
STATIC snTabsize := 3
STATIC snLineLen := 128
**************
PROCEDURE Main
? FileEdit( "TEST.PRG", 2, 2, 22, 76 )
Inkey(0)
RETURN
*****************
FUNCTION FileEdit( cFilename, nTop, nLeft, nBottom, nRight )
LOCAL lUpdated := .F.
LOCAL cString := MemoRead( cFilename )
LOCAL cScreen := SaveScreen( nTop, nLeft, nBottom, nRight )
snTop := nTop + 1 // initialize
snLeft := nLeft + 1 // static variables
snBottom := nBottom - 1
snRight := nRight - 1
snWinRow := 0
snWinCol := 0
snBuffRow := 1
snBuffCol := 0
slExit := .F.
SET SCOREBOARD OFF
DO WHILE .NOT. slExit
// display box with title
DispBox( nTop, nLeft, nBottom, nRight, 2 )
@ nTop, nLeft+1 SAY ;
PadC(cFileName, nRight-nLeft-1, Chr(205) )
// edit text
cString := MemoEdit( cString , ;
snTop , ;
snLeft , ;
snBottom , ;
snRight , ;
.T. , ;
"UserFunc" , ;
snLineLen , ;
snTabSize , ;
snBuffRow , ;
snBuffCol , ;
snWinRow , ;
snWinCol )
IF ! slExit
MemoSeek( cString ) // call search function
ENDIF
ENDDO
SET SCOREBOARD ON
RestScreen( nTop, nLeft, nBottom, nRight, cScreen )
RETURN MemoWrit( cFilename, cString )
******************
PROCEDURE MemoSeek( cString )
LOCAL cSeek := Space( 40 ), nPos, aPos, nFound
// Get search expression
@ snBottom+1, snLeft SAY "Search:" GET cSeek
READ
cSeek := Upper( Trim( cSeek ) )
IF ! Empty( cSeek )
// find current position in the text buffer
nPos := MlCtoPos( cString , ;
snLineLen, ;
snBuffRow, ;
snBuffCol, ;
snTabSize )
// search forward only for expression
nFound := At( cSeek, SubStr( Upper( cString ), nPos+1 ) )
IF nFound > 0
nPos += nFound
// find corresponding row and column
// in the text buffer
aPos := MPostoLc( cString , ;
snLineLen, ;
nPos , ;
snTabSize )
// new position in the window of MemoEdit()
snWinRow += ( aPos[1] - snBuffRow )
snWinCol += ( aPos[2] - snBuffCol )
// new position in the text buffer for MemoEdit()
snBuffRow := aPos[1]
snBuffCol := aPos[2]
ELSE
@ snBottom+1, snLeft SAY ;
PadR("Not found!",snRight-snLeft-1, Chr(205) )
Inkey(0)
ENDIF
ENDIF
RETURN
******************
FUNCTION UserFunc( nMode, nRow, nCol )
LOCAL nKey := LastKey()
LOCAL nReturn := ME_DEFAULT // default return value
snBuffRow := nRow
snBuffCol := nCol
snWinRow := Row() - snTop
snWinCol := Col() - snTop
DO CASE
CASE nMode == ME_IDLE // display position in
nRow := Row() // the text buffer
nCol := Col()
SetPos( snBottom+1, snLeft )
?? "Row:" , Str(snBuffRow,4)
?? " Column:", Str(snBuffCol,2)
SetPos( nRow, nCol )
CASE nMode == ME_UNKEY .OR. nMode == ME_UNKEYX
DO CASE
CASE nKey == K_F7 // next word with F7
nReturn:= ME_WORDRIGHT
CASE nKey == K_F8 // last character in the
nReturn:= ME_BOTTOMRIGHT // window with F8
CASE nKey == K_F9 // switch word wrap
nReturn:= ME_TOGGLEWRAP // with F9
CASE nKey == K_F10 // switch scroll
nReturn:= ME_TOGGLESCROLL // with F10
CASE nKey == K_CTRL_RET .OR. ; // save on Ctrl-Return
nKey == K_CTRL_W
slExit := .T.
nReturn:= K_CTRL_W
CASE nKey == K_ESC
slExit := .T.
CASE nKey == K_ALT_S // terminate and search
nReturn:= K_CTRL_W
CASE nKey == K_INS // set cursor based on
IF SetCursor() == SC_SPECIAL1 // insertion mode
SetCursor( SC_NORMAL )
ELSE
SetCursor( SC_SPECIAL1 )
ENDIF
ENDCASE
OTHERWISE // on initialization
nReturn := IIf( ReadInsert(), 0, K_INS )
// switch to insertion
SetCursor( SC_SPECIAL1 ) // mode by default
ENDCASE
RETURN nReturn
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.