Announcement

Collapse
No announcement yet.

Retrieving the selected text from a RichEdit control

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Retrieving the selected text from a RichEdit control

    Hi all,

    I'm trying to do a bit of programming where some selected text magically
    appears in a label as soon as its selected (depending on certain criteria).

    Using Phoenix I put this code under the RichEdit1_SelChange event handler
    but for some reason it only seems to return the first character of the selection.

    Is there something obvious that I'm doing wrong here?

    Code:
      Local Cr As CHARRANGE
      Local Buff As Asciiz * %MAX_PATH, Buffer$
      SendMessage ghWnd_FSCPW_Form1_RichEdit1, %EM_GETSELTEXT, 0, VarPtr(Buff)
      Buffer$ = Buff

    Buffer$ will contain only the first character of the selection...hmmmm curious.

    ian

  • #2
    You can use
    SendMessage (hRichEditCtrl,%EM_SETSEL, 0, -1)
    to select all text, or set 3 and 4 parameter as
    start and end of selection.

    ------------------
    -=Alex=-
    -=Alex=-

    Comment


    • #3
      Yes but doesn't that just select a portion of text?

      I wish to retrieve the text that has already been selected.

      I've done quite a bit with RichEdit controls but funnily enough have never
      needed to actually retrieve the text that was selected

      Imagine I have an application with a RichEdit control on it, the user
      selects a portion of the text with his mouse and then clicks a button.

      I need to be able to retrieve the text that he has selected.

      ian


      [This message has been edited by ian mcallister (edited January 10, 2007).]

      Comment


      • #4
        Proof of concept... using textbox, but could easly transfer text to your label control.

        Code:
        #PBFORMS Created v1.51
        #Compile Exe
        #Dim All
         
        #PBFORMS Begin Includes
        #If Not %Def(%WINAPI)
            #Include "WIN32API.INC"
        #EndIf
        #If Not %Def(%RICHEDIT_INC)
            #Include "RICHEDIT.INC"
        #EndIf
        #Include "PBForms.INC"
        #PBFORMS End Includes
         
        #PBFORMS Begin Constants
        %IDC_BUTTON1   = 1003
        %IDC_RICHEDIT1 = 1001
        %IDC_TEXTBOX1  = 1002
        %IDD_DIALOG1   =  101
        #PBFORMS End Constants
         
        Declare CallBack Function ShowDIALOG1Proc()
        Declare Function ShowDIALOG1(ByVal hParent As Dword) As Long
        #PBFORMS Declarations
         
        Function PbMain()
            PBFormsRichEdit ()      ' Load RichEdit
         
            ShowDIALOG1 %HWND_DESKTOP
         
            PBFormsRichEdit (%TRUE) ' Unload RichEdit
        End Function
         
        CallBack Function ShowDIALOG1Proc()
         
            Select Case As Long CbMsg
                Case %WM_INITDIALOG
         
                Case %WM_NCACTIVATE
                    Static hWndSaveFocus As DWord
                    If IsFalse CbWParam Then
                        hWndSaveFocus = GetFocus()
                    ElseIf hWndSaveFocus Then
                        SetFocus(hWndSaveFocus)
                        hWndSaveFocus = 0
                    End If
         
                Case %WM_COMMAND
                    Select Case As Long CbCtl
                        Case %IDC_RICHEDIT1
         
                        Case %IDC_TEXTBOX1
         
                        Case %IDC_BUTTON1
                            If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
                                'get any selected text from richEdit, goes to clipboard...
                                 SendMessage GetDlgItem(CBHNDL,%IDC_RICHEDIT1), %WM_COPY,0,0
                                'clear textbox before we send new text string...
                                SendMessage GetDlgITem(CBHNDL,%IDC_TEXTBOX1),%EM_SETSEL,0,-1
                                SendMessage GetDlgITem(CBHNDL,%IDC_TEXTBOX1),%WM_CLEAR,0,0
                                'put captured text from clipboard to edit control
                                SendMessage GetDlgITem(CBHNDL,%IDC_TEXTBOX1),%WM_PASTE,0,0
                            End If
         
                    End Select
            End Select
        End Function
         
        Function ShowDIALOG1(ByVal hParent As Dword) As Long
            Local lRslt  As Long
         
        #PBFORMS Begin Dialog %IDD_DIALOG1->->
            Local hDlg   As Dword
            Local hFont1 As Dword
         
            Dialog New hParent, "Dialog1", 245, 90, 322, 121, %WS_POPUP Or %WS_BORDER _
                Or %WS_DLGFRAME Or %WS_THICKFRAME Or %WS_CAPTION Or %WS_SYSMENU Or _
                %WS_MINIMIZEBOX Or %WS_MAXIMIZEBOX Or %WS_CLIPSIBLINGS Or _
                %WS_VISIBLE Or %DS_MODALFRAME Or %DS_3DLOOK Or %DS_NOFAILCREATE Or _
                %DS_SETFONT, %WS_EX_CONTROLPARENT Or %WS_EX_LEFT Or _
                %WS_EX_LTRREADING Or %WS_EX_RIGHTSCROLLBAR, To hDlg
            Control Add PBFormsRichEdit(), hDlg, %IDC_RICHEDIT1, "Select all this " + _
                "text and press button!", 5, 10, 205, 45, %WS_CHILD Or %WS_VISIBLE _
                Or %WS_TABSTOP Or %WS_HSCROLL Or %WS_VSCROLL Or %ES_LEFT Or _
                %ES_MULTILINE Or %ES_AUTOHSCROLL Or %ES_AUTOVSCROLL Or _
                %ES_WANTRETURN, %WS_EX_CLIENTEDGE Or %WS_EX_LEFT Or _
                %WS_EX_LTRREADING Or %WS_EX_RIGHTSCROLLBAR
            Control Add TextBox, hDlg, %IDC_TEXTBOX1, "", 5, 70, 205, 20, %WS_CHILD _
                Or %WS_VISIBLE Or %WS_DISABLED Or %WS_TABSTOP Or %ES_LEFT Or _
                %ES_AUTOHSCROLL, %WS_EX_CLIENTEDGE Or %WS_EX_LEFT Or _
                %WS_EX_LTRREADING Or %WS_EX_RIGHTSCROLLBAR
            Control Add Button,  hDlg, %IDC_BUTTON1, "WM_COPY", 235, 35, 60, 30
         
            hFont1 = PBFormsMakeFont("MS Sans Serif", 12, 400, %FALSE, %FALSE, _
                %FALSE, %ANSI_CHARSET)
         
            Control Send hDlg, %IDC_RICHEDIT1, %WM_SETFONT, hFont1, 0
            Control Send hDlg, %IDC_TEXTBOX1, %WM_SETFONT, hFont1, 0
        #PBFORMS End Dialog
         
            Dialog Show Modal hDlg, Call ShowDIALOG1Proc To lRslt
         
        #PBFORMS Begin CleanUp %IDD_DIALOG1
            DeleteObject hFont1
        #PBFORMS End CleanUp
         
            Function = lRslt
        End Function
        ------------------
        Best regards
        Jules
        www.rpmarchildon.com

        Comment


        • #5
          Ian,

          Maybe RichEdit1_SelChange is firing too soon?
          (Try selecting from other end of text for test).

          You might need to detect mouse button up, then use %EM_GETSELTEXT.

          Rgds Dave

          ------------------
          Rgds, Dave

          Comment


          • #6
            Thanks Jules that solution seems to work though I would rather not
            have to use the clipboard because,,, well because you're not supposed to have to!

            %EM_GETSELTEXT

            should work! but it doesn't in this case.

            Dave, you might have something there although if I do this:

            Code:
               Local selStart As Long, selEnd As Long
               SendMessage ghWnd_FSCPW_Form1_RichEdit1, %EM_GETSEL, VarPtr(selStart), VarPtr(selEnd) 'get caret's positions
               If selEnd > selStart Then 'some text has been selected
            and it is!! I can do a msgbox like:
            msgbox format$(selStart) & " " & format$(selEnd)
            and see that the numbers correspond to whatever I've selected yet I can't get:

            SendMessage ghWnd_FSCPW_Form1_RichEdit1, %EM_GETSELTEXT, 0, VarPtr(Buff)

            to work. I've tried with dynamic strings, ASCIIZ strings etc.
            I can get it to GPF if I use a dynamic string for the buffer but I can't get it to work.

            I did this:

            Code:
               Local a$, b2 As Asciiz * %MAX_PATH
               Local selStart As Long, selEnd As Long
               SendMessage ghWnd_FSCPW_Form1_RichEdit1, %EM_GETSEL, VarPtr(selStart), VarPtr(selEnd) 'get caret's position
               If selEnd > selStart Then 'some text has been selected
                  SendMessage ghWnd_FSCPW_Form1_RichEdit1, %EM_GETSELTEXT, 0, VarPtr(b2) 'please stuff whatever's selected into b2 ... pretty please?     
                  SetWindowText ghWnd_FSCPW_Form1_TextLbl5, b2
                  UpdateWindow ghWndMain  'doh! only the first character has been put into the TextLbl5
               End If
            And guess what it does... yep, puts only the first character of the selection into the label

            Windows eh? who'd have em'

            ian




            [This message has been edited by ian mcallister (edited January 10, 2007).]

            Comment


            • #7
              In a cunning turn of events I studied the master for half an hour.

              Yes Borje.

              And twisticated some of his great code to do what I need.

              Here is my virgin of Borje's code to do what I needed:

              Code:
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              ' Stream out Callback for RichEditStreamGet
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              Function RichEditStreamGetCallback(ByVal dwCookie As DWord, ByVal pbBuffer As Byte Ptr, _
                                                  ByVal cb As Long, pcb As Long) As DWord
                 gRET = gRET + Peek$(pbBuffer, cb)
              End Function
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              ' Stream out Rich Edit's contents to global string, gRET
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              Function RichEditSelectedGet (ByVal hRichEdit As Long) As Long
                Local eStream As EDITSTREAM
              
                gRET = ""
                eStream.dwCookie    = 0
                eStream.dwError     = 0
                eStream.pfnCallback = CodePtr( RichEditStreamGetCallback )
                Call SendMessage (hRichEdit, %EM_STREAMOUT, %SF_TEXT Or %SFF_SELECTION, VarPtr(eStream))
              
                Function = eStream.dwError
              End Function
              
              
              Function FSCPW_Form1_RichEdit1_SelChange _
                 ( _
                 ByVal hWndParent  As DWord, _       ' handle of parent window
                 ByVal ptnmhdr     As NMHDR Ptr, _   ' message information
                       lMsgResult  As Long _         ' value returned to message
                 ) As Long
                 Local a&
                 a& = RichEditSelectedGet(ghWnd_FSCPW_Form1_RichEdit1)
                 If gRET <> "" Then MsgBox gRET
              
              End Function
              .
              .

              oh joy oh joy oh joy oh joy !

              ian

              Comment


              • #8
                SendMessage (EM_GETSELTEXT) returns the number of characters copied to Buff.

                Maybe that could be checked?

                Oh, never mind, Silly me: It's so much 'cooler' to eschew fundamentals.

                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Ian,

                  Here's another cool method to magically grab the selected text - even counts the number of
                  characters - if you need that
                  Code:
                  #Include "win32api.inc"
                  #Include "richedit.inc"
                  
                  %ID_RICHEDIT = 100
                  '------------------/
                   
                  Function PBMain
                   Local hDlg As Dword
                   
                    Dialog New 0, "RichEdit Select Test",,,250,100, %WS_OVERLAPPEDWINDOW To hDlg
                    LoadLibrary "RichEd32.dll"
                    Control Add "RichEdit", hDlg, %ID_RICHEDIT, "Some text for testing", 5, 5, 240, 90, _
                                %WS_CHILD Or %WS_VISIBLE Or %ES_MULTILINE Or %WS_HSCROLL Or %WS_VSCROLL Or _
                                %ES_AUTOVSCROLL Or %ES_NOHIDESEL Or %ES_WANTRETURN Or %ES_SAVESEL, %WS_EX_CLIENTEDGE
                    Control Send hDlg, %ID_RICHEDIT, %EM_SETOPTIONS, %ECOOP_OR, %ECO_SELECTIONBAR   'allows full line selection
                    Control Send hDlg, %ID_RICHEDIT, %EM_SETEVENTMASK, 0, %ENM_SELCHANGE Or %ENM_MOUSEEVENTS
                   
                    Dialog Show Modal hDlg, Call DialogProc
                  End Function
                  '------------------/PBMain
                   
                  CallBack Function DialogProc
                   Local pNmh As NMHDR Ptr, sc As SELCHANGE Ptr, mf As MSGFILTER Ptr
                   Local szText As Asciiz * 600, TextLen As Long
                    Select Case As Long CbMsg
                      Case %WM_INITDIALOG
                        Static hEdit As Dword
                        Control Handle CbHndl, %ID_RICHEDIT To hEdit
                   
                      Case %WM_NOTIFY
                        pNmh = CbLParam                             'pointer to NMHDR structure in WM_NOTIFY msg
                        If @pNmh.hWndFrom = hEdit Then              'hWndFrom member of structure - control that sent msg
                          If @pNmh.code = %EN_SELCHANGE Then        'code member of structure - control specific notification
                            Dialog Set Text CbHndl, "Selection change"
                            sc = CbLParam                           'pointer to SELCHANGE structure in EN_SELCHANGE
                           If (@sc.seltyp And %SEL_TEXT) Then       'test SELCHANGE member (- use AND !)
                              Beep
                              TextLen = SendMessage(hEdit, %EM_GETSELTEXT, 0, VarPtr(szText))
                              MsgBox "Selected:   "+szText+" ("+Str$(TextLen)+" chars )  "
                            End If
                          ElseIf @pNmh.code = %EN_MSGFILTER Then    'keyboard or mouse message
                            mf = CbLParam                           'pointer to MSGFILTER structure in EN_MSGFILTER
                            If @mf.msg = %WM_LBUTTONDOWN Then       'test MSGFILTER member - OK
                              Dialog Set Text CbHndl, "Left button down"
                            ElseIf @mf.msg = %WM_LBUTTONUP Then
                              Dialog Set Text CbHndl, "Left button up" : Sleep 500
                            End If
                          End If
                        End If
                   
                    End Select
                  End Function
                  '------------------/DialogProc
                  'Rgds Dave

                  ------------------
                  Rgds, Dave

                  Comment


                  • #10
                    Thanks Dave!

                    Might be quicker than my method.

                    ian

                    Comment


                    • #11
                      Ian,
                      Here's a modified version of the text grabber that allows for keyboard text selection too.

                      I've dropped the use of %EN_SELCHANGE, as Dominic pointed out a while ago that in later versions of the
                      RichEdit DLL (after RichEdit32), that message fires repeatedly as the mouse is being dragged.
                      In the previous code I relied on it firing only when the button was released.

                      In testing this version though I may have come across your original problem! It seems that if you load the
                      latest version of the DLL (Msftedit.dll) (and use Control Add "RichEdit50W",..) only the first character in the
                      selected text is shown on the label. The number of characters (TextLen) is correctly displayed though ???

                      I checked MSDN's About Rich Edit Controls and they say to use either EM_GETSELTEXT or
                      EM_GETTEXTRANGE to retrieve selected text. However I've tried both methods and get the same result

                      Could it have something to do with Unicode? Maybe there are two Bytes per Character being retrieved and the
                      second is a null or something that I "dinnae ken"?

                      I guess it's not really a problem unless you specifically need some of the newer features in Msftedit.dll
                      and would prefer to load it rather than (the more widely available) RichEdit32.dll?

                      You can test if you get the same results by editting the LoadLibrary call and $Classname below..
                      Code:
                      #Include "win32api.inc"
                      #Include "richedit.inc"
                       
                      %ID_RICHEDIT = 100
                      %LBL_LABEL1  = 101
                      $ClassName   = "RichEdit"       '"RichEdit50W"   '## Shipped with WInXP SP1 +
                      '------------------/
                       
                      Function PBMain
                       Local hDlg As Dword
                       
                        Dialog New 0, "RichEdit Select Test",,,250,160, %WS_OVERLAPPEDWINDOW To hDlg
                        LoadLibrary "RichEd32.dll"    '"Msftedit.dll" 
                        Control Add $ClassName, hDlg, %ID_RICHEDIT, "Some text - select to test", 5, 5, 240, 90, _
                                    %WS_CHILD Or %WS_VISIBLE Or %ES_MULTILINE Or %WS_HSCROLL Or %WS_VSCROLL Or _
                                    %ES_AUTOVSCROLL Or %ES_NOHIDESEL Or %ES_WANTRETURN Or %ES_SAVESEL, %WS_EX_CLIENTEDGE
                        Control Send hDlg, %ID_RICHEDIT, %EM_SETOPTIONS, %ECOOP_OR, %ECO_SELECTIONBAR   'allows full line selection
                        Control Send hDlg, %ID_RICHEDIT, %EM_SETEVENTMASK, 0, %ENM_SELCHANGE Or %ENM_MOUSEEVENTS  OR %ENM_KEYEVENTS
                        Control Add Label, hDlg, %LBL_LABEL1, "Select text with keyboard or mouse", 5, 105, 240, 50
                        Dialog Show Modal hDlg, Call DialogProc
                      End Function
                      '------------------/PBMain
                       
                      CallBack Function DialogProc
                       Local pNmh As NMHDR Ptr, sc As SELCHANGE Ptr, mf As MSGFILTER Ptr
                       Local sTemp As String 
                       Local szText As Asciiz * 600, TextLen As Long 
                       Static ShiftDown, LBtnDown As Long 
                       
                        Select Case As Long CbMsg
                          Case %WM_INITDIALOG
                            Static hEdit As Dword
                            Control Handle CbHndl, %ID_RICHEDIT To hEdit
                       
                          Case %WM_NOTIFY
                            pNmh = CbLParam                             ' pointer to NMHDR structure in WM_NOTIFY msg
                            If @pNmh.hWndFrom = hEdit Then              ' hWndFrom member of structure - control that sent msg
                              Select Case As Long @pNmh.code            ' test the Code member
                                Case %EN_MSGFILTER                      ' = Keyboard or Mouse message
                                  mf = CbLParam                         ' get MSGFILTER structure
                                  Select Case As Long @mf.msg           ' test the Message member
                                    Case %WM_KEYDOWN 
                                      If @mf.wParam = %VK_SHIFT Then 
                                        ShiftDown = %True
                                        Dialog Set Text CbHndl, "Shift Key Down"
                                      End If
                       
                                    Case %WM_KEYUP 
                                      If @mf.wParam = %VK_SHIFT Then
                                        ShiftDown = %False
                                        Dialog Set Text CbHndl, "Shift Key Up"
                                        TextLen = SendMessage(hEdit, %EM_GETSELTEXT, 0, VarPtr(szText))
                                        If TextLen Then 
                                          Control Set Text CbHndl, %LBL_LABEL1, "Last selected: "+$CRLF+ _
                                                                                 szText+"  ( ="+Str$(TextLen)+" chars )  "
                                        End If
                                      End If
                       
                                    Case %WM_LBUTTONDOWN
                                      Dialog Set Text CbHndl, "Left button down"
                                      LBtnDown = %True
                       
                                    Case %WM_LBUTTONUP
                                      LBtnDown = %False
                                      Dialog Set Text CbHndl, "Left button up"
                                      TextLen = SendMessage(hEdit, %EM_GETSELTEXT, 0, VarPtr(szText))
                                      If TextLen Then
                                        Control Set Text CbHndl, %LBL_LABEL1, "Last selected: "+$CRLF+ _
                                                                               szText+"  ( ="+Str$(TextLen)+" chars )  "
                                      End If
                       
                                  End Select
                               End Select 
                            End If
                        End Select
                      End Function
                      '------------------/DialogProc
                      Rgds Dave



                      ------------------
                      Rgds, Dave

                      Comment


                      • #12
                        I wasted time looking for a bug for this message and when instead I should
                        have focused on how to set the right conditions to make it work as advertised.

                        Code:
                        #Compile Exe
                        #Dim All
                         
                        #Include "WIN32API.INC"
                        #Include "RICHEDIT.INC"
                        #Include "PBForms.INC"
                         
                        %IDC_BUTTON1   = 1003
                        %IDC_RICHEDIT1 = 1001
                        %IDD_DIALOG1   =  101
                         
                        Declare CallBack Function ShowDIALOG1Proc()
                        Declare Function ShowDIALOG1(ByVal hParent As Dword) As Long
                         
                        '------------------------------------------------------------------------------
                        '
                        '------------------------------------------------------------------------------
                        Function PbMain()
                            LoadLibrary "RichEd32.dll"
                            ShowDIALOG1 %HWND_DESKTOP
                        End Function
                         
                        '------------------------------------------------------------------------------
                        '
                        '------------------------------------------------------------------------------
                        CallBack Function ShowDIALOG1Proc()
                            Select Case As Long CbMsg
                                Case %WM_INITDIALOG
                                Case %WM_COMMAND
                                    Select Case As Long CbCtl
                                        Case %IDC_BUTTON1
                                            If CbCtlMsg = %BN_CLICKED Or CbCtlMsg = 1 Then
                                               LOCAL seltxt AS STRING
                                               LOCAl lrt AS LONG
                                               seltxt = SPACE$(255) & CHR$(0)  'allow enough buffer for selected text...
                                               lrt = SendMessage( GetDlgItem(CBHNDL, %IDC_RICHEDIT1),%EM_GETSELTEXT,0,BYVAL STRPTR(seltxt))
                                               msgbox "LEN=" & Str$(lrt) & $CRLF & "String= " & seltxt
                                            End If
                                    End Select
                            End Select
                        End Function
                         
                        '------------------------------------------------------------------------------
                        '
                        '------------------------------------------------------------------------------
                        Function ShowDIALOG1(ByVal hParent As Dword) As Long
                            Local lRslt  As Long
                            Local hDlg   As Dword
                            Local hFont1 As Dword
                            Dialog New hParent, "EM_GETSELTEXT MSG TEST", 245, 90, 322, 121, %WS_POPUP Or %WS_BORDER _
                                Or %WS_DLGFRAME Or %WS_THICKFRAME Or %WS_CAPTION Or %WS_SYSMENU Or _
                                %WS_MINIMIZEBOX Or %WS_MAXIMIZEBOX Or %WS_CLIPSIBLINGS Or _
                                %WS_VISIBLE Or %DS_MODALFRAME Or %DS_3DLOOK Or %DS_NOFAILCREATE Or _
                                %DS_SETFONT, %WS_EX_CONTROLPARENT Or %WS_EX_LEFT Or _
                                %WS_EX_LTRREADING Or %WS_EX_RIGHTSCROLLBAR, To hDlg
                            Control Add "RichEdit", hDlg, %IDc_RICHEDIT1, "SELECT YOUR TEXT AND HIT BUTTON!", 5, 10, 200, 70, _
                                      %WS_CHILD Or %WS_VISIBLE Or %ES_MULTILINE Or %WS_HSCROLL Or %WS_VSCROLL Or _
                                      %ES_AUTOVSCROLL Or %ES_NOHIDESEL Or %ES_WANTRETURN Or %ES_SAVESEL, %WS_EX_CLIENTEDGE
                            Control Send hDlg, %IDC_RICHEDIT1, %EM_SETOPTIONS, %ECOOP_OR, %ECO_SELECTIONBAR
                            Control Send hDlg, %IDC_RICHEDIT1, %EM_SETEVENTMASK, 0, %ENM_SELCHANGE Or %ENM_MOUSEEVENTS
                            Control Add Button,  hDlg, %IDC_BUTTON1, "Grab Sel Txt", 235, 35, 60, 30
                            hFont1 = PBFormsMakeFont("MS Sans Serif", 12, 400, %FALSE, %FALSE,%FALSE, %ANSI_CHARSET)
                            Control Send hDlg, %IDC_RICHEDIT1, %WM_SETFONT, hFont1, 0
                            Dialog Show Modal hDlg, Call ShowDIALOG1Proc To lRslt
                            DeleteObject hFont1
                            Function = lRslt
                        End Function
                        Best regards
                        Jules
                        www.rpmarchildon.com

                        Comment


                        • #13
                          The DDT code posted above is using a hard-coded version of the rich edit control.
                          It uses version 1.0 of the control which returns ANSI text for the specified messages.
                          The code will fail for version 4.1(RichEdit50W class in MSFTEDIT.DLL) which returns
                          unicode text. This is the reason why Ian's code did not work.
                          Fail here means that the text gets truncated at the first null byte.


                          ------------------
                          Dominic Mitchell
                          Phoenix Visual Designer
                          http://www.phnxthunder.com
                          Dominic Mitchell
                          Phoenix Visual Designer
                          http://www.phnxthunder.com

                          Comment


                          • #14
                            Sorry Jules,

                            Try your code with "Msftedit.dll" and class name "RichEdit50W" to see the problem.

                            Like Dominic said

                            Rgds Dave

                            ------------------


                            [This message has been edited by Dave Biggs (edited January 13, 2007).]
                            Rgds, Dave

                            Comment


                            • #15
                              Ok, it is do-able

                              To deal with EM_GETSELTEXT returning unicode text, use a string variable (as Jules suggested)
                              instead of asciiz which trips up on the first null byte. Then use ACODE$ to convert it.
                              Something like ..
                              Code:
                                GetClassName(hEdit, szClass, SizeOf(szClass))         ' Check the version of RichEdit in use
                                If Instr(Ucase$(szClass), "RICHEDIT50W") > 0 Then RichEdit50W = %True
                              ..
                                SendMessage hEdit,%EM_EXGETSEL,0,VarPtr(Cr)           ' Cr As CHARRANGE
                                TextLen = Cr.cpMax - Cr.cpMin
                                sTemp = SPACE$((TextLen * 2) + 1)                     ' allow for double byte Unicode
                                SendMessage(hEdit, %EM_GETSELTEXT, 0, StrPtr(sTemp))
                                 If RichEdit50W Then                                  ' Unicode version of RichEdit
                                   Control Set Text CbHndl, %LBL_LABEL1, "Selected text: " + ACode$(sTemp)
                                 Else 
                                   Control Set Text CbHndl, %LBL_LABEL1, "Selected text: " + sTemp
                                 End If
                              Rgds Dave

                              ------------------


                              [This message has been edited by Dave Biggs (edited January 14, 2007).]
                              Rgds, Dave

                              Comment


                              • #16
                                >>>but for some reason it only seems to return the first character of the selection.

                                >>SendMessage (EM_GETSELTEXT) returns the number of characters copied to Buff.

                                >Fail here means that the text gets truncated at the first null byte.

                                I think it means A) the text was actually retrieved in its entirety; B) only the portion retrieved up to the first null was <U>displayed</U> (versus <U>retrieved</U>); C) testing the number of return characters would have saved a lot of angst; D) when compilable code demonstrating a problem is not posted everyone is limited to crapshooting; E) someone was lucky (or not) to not get a GPF since the size of the buffer provided to EM_GETSELTEXT should have been measured with EM_EXGETSEL message because the maximum text length was not limited with the EM_SETLIMITTEXT message (versus use of various 'fixed buffer length' code), and if Unicode text is in the controls, each character requires two bytes and a buffer overrun was a distinct possiblility.

                                MCM
                                Michael Mattias
                                Tal Systems (retired)
                                Port Washington WI USA
                                [email protected]
                                http://www.talsystems.com

                                Comment

                                Working...
                                X