Selected text in Multistring field?

On 14/08/2013 at 05:14, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   12-14 
Platform:   Windows  ; Mac  ;  Mac OSX  ; 
Language(s) :     C++  ;

---------
Hi,

does anybody know how (and if it is possible) to retrieve the currently selected text in a multistring field? I am in a GeDialog btw.

I remember that there were messages sent when the user edits the field...maybe something like a message? I just don't remember where it was (way too long ago).

Thanks in advance
Sam

On 14/08/2013 at 05:33, xxxxxxxx wrote:

have you tried bfm_action ?

On 14/08/2013 at 06:31, xxxxxxxx wrote:

Thanks first of all. BFM_ACTION was what I meant! However, none of the actual action states give me the current text selection afai can see. 😕

On 14/08/2013 at 07:16, xxxxxxxx wrote:

hm, there are also these ids in bfm_message :

_<_t_>_
BFM_EDITFIELD_GETCURSORPOS
|
Returns the cursor position in an edit field ([LONG](file:///E:/Misc/SDK%20Help/C4d%20SDK%20Documentation%20C++/help/pages/ge_sys_math/typedef_ge_sys_math_584.html#LONG2)).

---|---

BFM_EDITFIELD_GETBLOCKSTART
|
Returns the block start position in an edit field ([LONG](file:///E:/Misc/SDK%20Help/C4d%20SDK%20Documentation%20C++/help/pages/ge_sys_math/typedef_ge_sys_math_584.html#LONG2)).
<_<_t_>_

sounds that the range between those could be the selected range, but i have never used them, so i might be wrong.

On 14/08/2013 at 07:54, xxxxxxxx wrote:

Yeah I had found these but they only seem to be for LONG edit fields (at least that was my assumption with the LONG statement), but I will try them. Thanks!

On 14/08/2013 at 07:54, xxxxxxxx wrote:

This is a snippet from my free AutoComplete plugin that finds the last word in a text box:

/////////////// This section gets the last word of text the user types into the texbox /////////////////  
 String allWords;                      //This will hold the entire text in the textbox  
 String lastWord;                      //This will hold the last word that is typed into a text box  
       
  if (msg.GetId()==BFM_GETCURSORINFO)  
  {  
      if(GetString(MY_MULTIBOX, allWords))  
      {  
          LONG length = allWords.GetLength();  
          LONG pos = NULL;                                     //The variable that will hold the position of the string  
          Bool lastSpace = allWords.FindLast(" ",&pos, -1);    //Find the last blank space and store it's position in the string  
          if(pos>0)                                            //If there is at least one empty space found  
          {  
             lastWord = allWords.SubStr(pos+1, length - pos);  //Grab the last word (sub string)  
          }  
      }  
  }  
/////////////////////////////////////////////////////////////////////////////////////////////////////////// 

Hope that helps,
-ScottA

On 14/08/2013 at 07:55, xxxxxxxx wrote:

thanks Scott. Browsing strings is not the issue but I really need the selected text.

On 14/08/2013 at 08:05, xxxxxxxx wrote:

I understood LONG in that way, that those container ids are of type LONG, providing the caret
and block position as an integer value.

On 14/08/2013 at 08:12, xxxxxxxx wrote:

And I think you are absolutely right. Now that I also see SETCURSORPOS it seems pretty obvious. Thanks, I check if these work!

On 14/08/2013 at 15:47, xxxxxxxx wrote:

This is the solution I came up with for getting the selected text in a GeDialog() text box:

LONG myDialog::Message(const BaseContainer &msg, BaseContainer &result)  
{   
  String text;    
  this->GetString (1001, text);   //Get the text in the text box (1001 is the id for the edit text gizmo)  
  
  if(GetString(1001, text))       //If the edit text gizmo is not empty  
  {  
      //The cStart value is the position in the text where you started dragging(highligthing the text)  
      //The cPos value is the current position the cursor is in  
      //The range of selected text characters = cPos-cStart  
  
      BaseContainer blockStart(BFM_EDITFIELD_GETBLOCKSTART);   
      GeData bs = SendMessage(1001, blockStart);  
      LONG cStart = bs.GetLong();  
   
      BaseContainer cursorPos(BFM_EDITFIELD_GETCURSORPOS);  
      GeData cp = SendMessage(1001, cursorPos);  
      LONG cPos = cp.GetLong();  
  
      LONG numSelected = cPos-cStart;     //The number of selected text characters  
  
      String selected = "";  
  
      if(numSelected >= 1)               //If the user selected the text from left to right  
      {  
          GePrint("Start: " + LongToString(cStart) + " " + "Pos: " + LongToString(cPos) + " " + "NumSel: " + LongToString(numSelected));  
          for (LONG i=0; i<numSelected; i++)  
          {  
              String s = text.SubStr(cStart+i, 1);  
              String combine = selected.operator+=(s);    //Adds the current char to the "selected" string variable  
          }  
      }  
  
      GePrint(selected);   
  }  
  
  return GeDialog::Message(msg,result);  
}  

Seems to work pretty well.
But I'm always interested in seeing how other people solve things. I learn new things that way.
So if you figured out another way to so it. I'd love to see what you came up with.

-ScottA

On 28/08/2013 at 01:29, xxxxxxxx wrote:

Hi Scott,

thanks for your example. Anyway, this only seems to work for a normal text field not a multistring field. In a multistring field the values are always 0.

So there is no way to retrieve this in a multistring (multiline) field (question pointed at support)?