|
Post by 1180michel on Mar 15, 2021 16:05:39 GMT -5
Hi ! How to get current cursor position in texteditor (line-column of the cursor) ? !!! I don't speak about mouse position, but about the blinking cursor. That's of course not the same ! I didn't see anything in texteditor instructions. May be an API call ? Thanks for help ! 1180michel
|
|
|
Post by Rod on Mar 16, 2021 4:09:51 GMT -5
Well, no. Essentially the texteditor is a control for user driven input. You are wanting to do what? Insert text, remove text? You can organise limited interaction. But tell us what you are doing to get best advice.
This puts the cursor to the end of any text in the control, probably of no use.
'now Richards trick to put the cursor at the end of the text if handle = tHandle then calldll #user32, "SendMessageA", handle as ulong, _ _EM_SETSEL as long, 100 as long, 100 as long, r as long end if
This highlights found text, you basically need to extract the whole text and parse it back in. Cluncky
' code starts nomainwin texteditor #main.te 0, 0, 200, 200 button #main.next, "Find Next", [find], LR, 100, 30 button #main.first, "Find First", [first], LR, 250, 30 open "Text" for window as #main #main "trapclose [quit]"
'build some multiline text t$="this is line one."+chr$(13)+"this is line two."+chr$(13)+"this is line three."
[first] 'set word count to -1 when find first is clicked 'it will increment to 0 when it drops through to [find] wcounter=-1
[find] 'increase the word counter everytime find next is clicked wcounter=wcounter+1
'grab the first part of the string letter by letter up to the current word position 'note that there are hidden control characters to preserve wc=0 letter=1 firstpart$="" while wc<wcounter and wcounter>0 'get printable text while asc(mid$(t$,letter,1))>32 and letter<len(t$) firstpart$=firstpart$+mid$(t$,letter,1) letter=letter+1 wend 'get control characters while asc(mid$(t$,letter,1))<33 and letter<len(t$) firstpart$=firstpart$+mid$(t$,letter,1) letter=letter+1 wend wc=wc+1 wend
'grab the new word newword$="" while asc(mid$(t$,letter,1))>32 and letter<len(t$) newword$=newword$+mid$(t$,letter,1) letter=letter+1 wend 'note we leave the control characters alone and attach them to the last part
'grab the rest lastpart$=right$(t$,len(t$)-letter+1)
'now cls #main.te "!cls"
'print the firstpart #main.te firstpart$;
'now find out where the text cursor is, col and row, the insert point
'row #main.te "!lines ri"
'col #main.te "!line ";ri;" s$" ci=len(s$) ci=ci+1
'now cls #main.te "!cls"
'print the text minus the word to highlight #main.te firstpart$+lastpart$
'set the insertion point and insert the word #main.te "!select ";ci;" ";ri #main.te "!insert newword$"
'now sit and wait ready to loop back round and show the next find 'or start again with find first 'or quit wait
[quit] close #main end
Perhaps graphicbox text is better suited to the task but we need to know what you are doing.
|
|
|
Post by Walt Decker on Mar 16, 2021 9:49:28 GMT -5
Actually you can get the caret position by using the "GetCaretPos()" API. However, that gives the position in window client coordinates. To get the column, row position you will have to use the "GetTextExtent32Ex"() API then divide the number of characters provided to that function by the point.x value to give the average character width Then divide the position obtained from "GetCaretPos"() by the average width to get the column and the height returned by the average character height to get the row position. The sequence would look something like this: STRUCT tPoint, X AS LONG, Y AS LONG STRUCT tChr, X AS LONG, Y AS LONG
CALLDLL #USER, "GetCaretPos", tPoint AS STRUCT, RetVal AS VOID CALLDLL #USER, "GetDC", WinHndl AS ULONG '<-- handle of window WinDc AS ULONG '<-- Device context Txt$ = "aAbBcCQqJj0O" CALLDLL #GDI, "GetTextExtent32ExA", WinDc AS ULONG, Txt$ AS PTR, 12 AS LONG, tChr AS STRUCT, RetVal AS LONG
ChrCellX = INT(tChr.X.struct / 12)
Col = tPoint.X.struct / ChrCellX Row = tPoint.Y.struct / tChr.Y.struct
That will only work if you are using the windows default font. If you are using a different font the process, for LB, is a little more complicated.
ERROR CORRECTION: GetTextExtent32ExA should be GetTextExtentPoint32A
|
|
|
Post by Rod on Mar 16, 2021 10:08:16 GMT -5
:) I think that probably explains why there is no native function(). There are other text editor, richtext editors that probably better support such function but we need to know if a simpler solution will suffice.
|
|
|
Post by Walt Decker on Mar 16, 2021 10:58:18 GMT -5
It would not be difficult to design a caret pos function for LB. LB already divides the editor window into columns and rows. This is based on the average width and height of the font requested by the user. It would just be a matter of dividing the caret pos by those averages.
As it currently is, LB uses its own handle for the font. This causes the programmer to jump through hoops to get the caret position.
|
|
|
Post by 1180michel on Mar 16, 2021 13:01:44 GMT -5
THANKS TO ALL ! GetCaretPos was what I needed. I had seen it on the net, but did not well understand what it did. Now, it's OK ! See You later ! 1180michel
|
|
|
Post by Walt Decker on Mar 16, 2021 14:35:20 GMT -5
Here are some function for dealing with the caret in an edit control. FWIW, the caret belongs to the edit control that has the focus. The cursor belongs to the windows operating system.
Use FN.GetCharCellEx() to get the character cells for fonts other than the default font.
Use FN.GetChrCell() for the default font.
' FUNCTION FN.GetCharCellEx(FntName$, PointSize, Bold, Italic, BYREF CellSzx, BYREF CellSzy) '========================================================================================/' ' FntName$ MUST BE AS IT APPEARS IN THE CHOOSE FONT DIALOG, E. G. Times New Roman '========================================================================================/'
LOGPIXELSY = 90
FW.DONTCARE = 0 FW.NORMAL = 400 FW.BOLD = 700
OUT.TT.PRECIS = 4 CLIP.DEFAULT.PRECIS = 0 DEFAULT.QUALITY = 0 FF.DONTCARE = 0
OPEN "User32.dll" FOR DLL AS #USER OPEN "gdi32.dll" FOR DLL AS #GDI
RetVal = 0 FontHndl = 0 CyPixels = 0 HndlDc = 0 LenTxt = 0 OldObj = 0
Txt$ = "AaBbXxQqJjGgOo" LenTxt = LEN(Txt$)
STRUCT tChr, X AS LONG, Y AS LONG
CALLDLL #USER, "GetDC", 0 AS ULONG, HndlDc AS ULONG CALLDLL #GDI, "GetDeviceCaps", HndlDc AS ULONG, LOGPIXELSY AS LONG, CyPixels AS LONG
PointSize = -1 * INT((PointSize * CyPixels) / 72)
SELECT CASE Bold CASE 0 Bold = FW.DONTCARE CASE 1 Bold = FW.NORMAL CASE 2 Bold = FW.BOLD END SELECT
CALLDLL #GDI, "CreateFontA", _ PointSize AS LONG, _ 0 AS LONG, _ 'height, width(default=0) 0 AS LONG, 0 AS LONG, _ 'escapement(angle), orientation Bold AS LONG, _ 'weight (%FW_DONTCARE = 0, %FW_NORMAL = 400, %FW_BOLD = 700) Italic AS LONG, _ 'Italic Underline AS LONG, _ 'Underline StrikOut AS LONG, _ 'StrikeThru ChrSet AS LONG, OUT.TT.PRECIS AS LONG, _ CLIP.DEFAULT.PRECIS AS LONG, DEFAULT.QUALITY AS LONG, _ FF.DONTCARE AS LONG , FntName$ AS PTR, FontHndl AS ULONG
CALLDLL #GDI, "SelectObject", HndlDc AS ULONG, FontHndl AS ULONG, OldObj AS ULONG CALLDLL #GDI, "GetTextExtentPoint32A", HndlDc AS ULONG, Txt$ AS PTR, _ LenTxt AS LONG, tChr AS STRUCT, RetVal AS LONG
CellSzx = INT(tChr.X.struct / LenTxt) CellSzy = tChr.Y.struct
CALLDLL #GDI, "SelectObject", HndlDc AS ULONG, OldObj AS ULONG, RetVal AS ULONG CALLDLL #GDI, "DeleteObject", FontHndl AS ULONG, RetVal AS VOID CALLDLL #USER, "ReleaseDC", 0 AS ULONG, HndlDc AS ULONG, RetVal AS VOID CLOSE #GDI CLOSE #USER FN.GetChrCellEx = FontHndl END FUNCTION
'-------------------------------------------------------------------------------- '--------------------------------------------------------------------------------
FUNCTION FN.GetChrCell(BYREF CellSzx, BYREF CellSzy)
RetVal = 0 DevDc = 0 LenTxt = 0
Txt$ = "AaBbXxQqJjGgOo" LenTxt = LEN(Txt$)
STRUCT tChr, X AS LONG, Y AS LONG
OPEN "User32.dll" FOR DLL AS #USER OPEN "gdi32.dll" FOR DLL AS #GDI
CALLDLL #USER, "GetDC", 0 AS ULONG, DevDc AS ULONG CALLDLL #GDI, "GetTextExtentPoint32A", DevDc AS ULONG, Txt$ AS PTR, _ LenTxt AS LONG, tChr AS STRUCT, RetVal AS LONG
CellSzx = INT(tChr.X.struct / LenTxt) CellSzy = tChr.Y.struct
CALLDLL #USER, "ReleaseDC", 0 AS ULONG, DevDc AS ULONG, RetVal AS VOID
CLOSE #USER CLOSE #GDI
END FUNCTION
'-------------------------------------------------------------------------------- '--------------------------------------------------------------------------------
FUNCTION FN.GetCaretRC(CellSzx, CellSzy, BYREF CarCol, BYREF CarRow)
OPEN "User32.dll" FOR DLL AS #USER
RetVal = 0
STRUCT tPoint, X AS LONG, Y AS LONG
CALLDLL #USER, "GetCaretPos", tPoint AS STRUCT, RetVal AS VOID
CarCol = INT(tPoint.X.struct / CellSzx) CarRow = INT(tPoint.Y.struct / CellSzy)
CLOSE #USER END FUNCTION
'-------------------------------------------------------------------------------- '--------------------------------------------------------------------------------
FUNCTION FN.PutCaret(CellSzx, CellSzy, PntX, PntY)
OPEN "User32.dll" FOR DLL AS #USER
RetVal = 0
PntX = PntX * CellSzx PntY = PntY * CellSzy
CALLDLL #USER, "SetCaretPos", PntX AS LONG, PntY AS LONG, RetVal AS VOID
CLOSE #USER
END FUNCTION
'-------------------------------------------------------------------------------- '--------------------------------------------------------------------------------
FUNCTION FN.GetCaretXY(BYREF PntX, BYRET PntY) OPEN "User32.dll" FOR DLL AS #USER
RetVal = 0
STRUCT tPoint, X AS LONG, Y AS LONG
CALLDLL #USER, "GetCaretPos", tPoint AS STRUCT, RetVal AS VOID
PntX = tPoint.X.struct PntY = tPoint.Y.struct
END FUNCTION '
|
|
|
Post by 1180michel on Mar 23, 2021 16:19:16 GMT -5
Thanks, Walt ! Very interesting !
|
|