Using the cursor position

Discussions related to mouse, keyboard, fonts and Graphical User Interface
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Using the cursor position

Post by KenDown »

I have an edit box set up with

Code: Select all

          SYS"LoadLibrary","RICHED20.DLL"      
          textbox%=FN_createwindow(@hwnd%,"RichEdit20W","",354,4,344,246,0,&200044,0)
To do what I need to do, I have to set up a structure:

Code: Select all

DIMcharrange{cpmin%,cpmax%}
What I want to do is click in the edit box and then extract the text where I click. I find the cursor position (or caret position) and start processing thus:

Code: Select all

            REM EM_EXGETSEL=&434
            SYS"SendMessage",textbox%,&434,0,charrange{}
            IFcharrange.cpmin%>0THEN
              j%=charrange.cpmin%
        
              REM Find the start (F%) and end (L%) of the text and
              REM move the text into a block of memory beginning at F%
              REM WM_GETTEXTLENGTH=&E
              SYS"SendMessage",textbox%,&E,0,0TOL%
              SYS"GlobalAlloc",0,L%+1TOF%
              REM WM_GETTEXT=&D
              SYS"SendMessage",textbox%,&D,L%+1,F%
        
              REM Bodge by adding in all carriage returns
              l%=0:n%=0
              REPEAT:l%-=((n%?F%)=13):n%+=1:UNTILn%=j%+l%
              j%+=l%
         ENDIF
j% should be the caret position so that $(F%+j%) would give me the text I want. In fact j% falls increasingly behind where I clicked because the original call to "SendMessage" does not appear to count the lines or to only count CHR$10 and not CHR$13 (or vice versa). Hence the "bodge" which runs through the text and counts in all the lines - and notice that the end of the loop has to be increased with every line, otherwise you still end up with j% falling short of the true caret position.

Does anyone have a solution to this problem - or have I solved a problem that you too have been experiencing?
RichardRussell

Re: Using the cursor position

Post by RichardRussell »

KenDown wrote: Mon 04 May 2020, 23:28Does anyone have a solution to this problem?
Yes. Use EM_GETTEXTRANGE rather than WM_GETTEXT and it will work. WM_GETTEXT 'helpfully' converts the line endings into CRLF which, as you have found, causes a displacement between positions in the returned text and the caret position. EM_GETTEXTRANGE returns the text with (I think) CR line endings so everything agrees; it will also get only the text you need, saving you the trouble (and time) of getting the entire document and extracting the wanted subset yourself.
KenDown
Posts: 327
Joined: Wed 04 Apr 2018, 06:36

Re: Using the cursor position

Post by KenDown »

Thanks, though I *think* that requires that you select the text you wish to copy.

What I want to do is click once in a paragraph and then transfer that entire paragraph elsewhere, which means that I have to work out the caret position, work backwards to the start of the paragraph, work forward to the end of the paragraph, and then transfer the paragraph. As the paragraphs are all of different lengths, things get complicated.

However I will make a note of that call for future use. Many thanks.
RichardRussell

Re: Using the cursor position

Post by RichardRussell »

KenDown wrote: Tue 05 May 2020, 14:12 Thanks, though I *think* that requires that you select the text you wish to copy.
No, it doesn't. Do you really think I would have suggested it as a solution had that been the case? It takes a CHARRANGE structure to specify what text you want it to return (the same structure you are already using to find the caret position) and is completely independent of selection.
However I will make a note of that call for future use.
You could use it to recover the entire document if you wish (just set the range appropriately) and then it would be a direct replacement for WM_GETTEXT except that you wouldn't have to bother adjusting for the CRLF displacements; all your existing paragraph-detection code could remain the same (or possibly even be simpler).

Used that way EM_GETTEXTRANGE directly solves the problem you asked about; of course if you actually prefer to use your more complicated solution that's fine, but in that case I wonder why you asked the question.