No announcement yet.

Friendly Name Hyperlinks - RichEdit

  • Filter
  • Time
  • Show
Clear All
new posts

  • Friendly Name Hyperlinks - RichEdit

    The links here and here talk about creating a "friendly name hyperlink" in a RichEdit control.

    I'd have sworn I opened a thread on the topic but cannot find it now. I do see that in a recent thread Steve mentioned the desire to use a friendly name hyperlink, but he just didn't mention it by that terminology.

    Have anyone given it a try?

    The links above talks about it as though it requires modification of the RichEdit RTF content, although I'll admit I don't have a clear picture of what the article suggests as a way to implement a friendly name hyperlink. But I am encouraged that it seems to be possible.

  • #2

    I got it to work in my RTF editor but richedit will not save it as RTF so it was still useless. This is the code I ended up testing but its a dead end. You select the RTF you want in the editor and click a button that runs this code and it will underline and the cursor will change to a hand but there seems to be no option to change the default behaviour of rich edit.

              Case 71
                cfm.cbSize      = SIZEOF(cfm)
                cfm.dwMask      = %CFM_BOLD or %CFM_UNDERLINE or %CFM_LINK  ''' or %CFM_PROTECTED
                cfm.dwEffects   = %CFE_LINK
                cfm.crTextColor = &H0000FF00
                SendMessage hEdit,%EM_SETCHARFORMAT,%SCF_WORD or %SCF_SELECTION,ByVal VarPtr(cfm)
    hutch at movsd dot com
    The MASM Forum


    • #3
      Howdy Steve!
      Well, that's a bummer. You wouldn't think MS would create such a limited capability. As minimal as is the documentation I've been able to find, perhaps there are some options yet to see the light of day!


      • #4
        Hey Gary,

        You are right, Microsoft did not create the "friendly hyperlink" with such a limited capability.
        Friendly Name Hyperlinks are usefull, working well and can easily be streamout saved as RTF file.

        As your link RichEdit Friendly Name Hyperlinks says, in RichEdit 4.1, a string like...
        "{\field{\*\fldinst{HYPERLINK""""}}{\fldrslt{\ul\cf2 MSN \cf0\ul0}}}"
        will show the friendly hyperlink name "MSN" and jump to "" if invoked.

        Do you think you can handle from here?


        • #5
          Let me play with it some before I answer the question! I understand the concept, but very rarely deal with RTF files. If I have text I want to put in a RichEdit control, you're saying I have to first put it in the RichEdit, then extract the RTF content, then figure out where the RTF insertion should go, insert it, then save the file as RTF and then load it back into the RichEdit. Then, I cannot save the context as text? That's a bummer for me because I much prefer saving content as a text file. But, it the friendly name hyperlink requires working solely with the RTF, then I don't have any choice.

          What about when a user is typing in content, the implication is that they cannot insert a friendly name hyperlink, correct?


          • #6

            Ok, in the hope to be clear, let's start this from the beginning...

            Rich text usually have some normal text and some embedded code that is invisible in the editor.
            The way this code is hidden is mostly, in our present context, via the use of the "" back slash character.

            For instance to set a phrase in bold, a phrase must be preceeded by "\b" and have "\b0" after to end bolding.
            You can not in a RichEdit editor directly type "/b" or "/b0" and expect to create bold section.
            Usually, you select some text and press a "Bold" button.

            In the same way, to insert a "friendly name hyperlink", you can not type directly the needed escape characters sequence.
            You will need some kind of button, or a special key, calling for code that will insert the sequence programmatically as you do for bold.

            Once done, to save or load RTF text, you have to use some EDITSTREAM / EditStreamCallback
            with EM_STREAMIN / EM_STREAMOUT in SF_RTF mode.
            Doing so, the "friendly name hyperlink", like bold text, will be preserved.

            RTF is powerfull, Rich Text Format Specification
            Last edited by Pierre Bellisle; 26 Dec 2018, 12:18 PM.


            • #7
              Hi Pierre!
              Thanks for the additional reply!

              Yes, I think what you said matches my understanding. You have to work entirely in RTF to get the desired result. Yes, you can type text into a RichEdit, but to make it "friendly" will require coding.

              I suppose it can be done automatically by responding to the enlink notifications, which arrive in the Callback as the URL is typed, but the result must still be saved in RTF.


              • #8
                I got an example for xmas if you want it, it's still hot!


                • #9
                  Cookies warm from the oven always taste better!


                  • #10
                    Try this...

                    Click image for larger version  Name:	HyperLink5.png Views:	1 Size:	63.8 KB ID:	777401

                    #COMPILE EXE '#Win 9.07#
                    #DIM ALL
                    #INCLUDE ""
                    #INCLUDE ""
                    #INCLUDE ""
                    #RESOURCE "D:\Basic\Bas\~~PbrDefault00.pbr"
                    '#RESOURCE "YourResource.pbr"
                    %RichEdit01                    = 101
                    %ButtonRtfText                 = 201
                    %ButtonFriendlyHyperlinkInsert = 202
                    %EditFriendlyHyperLinkName     = 301
                    %EditFriendlyHyperLinkLink     = 302
                    GLOBAL hDlg        AS DWORD
                    GLOBAL hRichEdit01 AS DWORD
                    FUNCTION richeditDllVersionGet(zClassName AS ASCIIZ) AS STRING
                     LOCAL FileVersionInfoSize AS LONG
                     LOCAL Ignored             AS LONG
                     LOCAL pLang               AS DWORD POINTER
                     LOCAL sBuffer             AS STRING
                     LOCAL sLanguage           AS STRING
                     LOCAL pzBuffer            AS ASCIIZ POINTER
                     LOCAL LenPath             AS LONG
                     LOCAL zPath               AS ASCIIZ * %MAX_PATH
                     LenPath = GetSystemDirectory(zPath, %Max_Path + 1) 'System32
                     SELECT CASE LCASE$(zClassName)
                       CASE "richedit"     : zPath &= "\RichEd32.dll"
                       CASE "richedit20a"  : zPath &= "\RichEdit20A.dll"
                       CASE "richedit50w"  : zPath &= "\MsftEdit.dll"
                       CASE ELSE           : zPath &= "\MsftEdit.dll"
                     END SELECT
                     FileVersionInfoSize = GetFileVersionInfoSize(zPath, Ignored)
                     IF FileVersionInfoSize THEN
                       sBuffer = NUL$(FileVersionInfoSize)
                       IF GetFileVersionInfo(zPath, Ignored, FileVersionInfoSize, BYVAL STRPTR(sBuffer)) THEN
                         IF VerQueryValue(BYVAL STRPTR(sBuffer), "\VarFileInfo\Translation", pLang, Ignored) THEN
                           sLanguage = HEX$(LOWRD(@pLang), 4) + HEX$(HIWRD(@pLang), 4)
                           sLanguage = "040904E4" 'American English/ANSI
                         END IF
                         IF VerQueryValue(BYVAL STRPTR(sBuffer), "\StringFileInfo\" & sLanguage & "\FileDescription", pzBuffer, Ignored) THEN
                           FUNCTION = @pzBuffer & $CRLF & zPath
                         END IF
                       END IF
                     END IF
                    END FUNCTION
                    FUNCTION richeditVersionGet(hRichEdit AS DWORD) AS STRING
                     LOCAL zClass       AS ASCIIZ * 50
                     LOCAL OsVersionInf AS OSVERSIONINFO
                     GetClassName(hRichEdit, zClass, SIZEOF(zClass))
                     OsVersionInf.dwOSVersionInfoSize = SIZEOF(OSVERSIONINFO)
                     FUNCTION = FORMAT$(OsVersionInf.dwMajorVersion) & "." & FORMAT$(OsVersionInf.dwMinorVersion) & _
                                $SPC & zClass & $CRLF & richeditDllVersionGet(zClass)
                    END FUNCTION
                    FUNCTION WinError$(BYVAL ErrorCode AS DWORD) AS STRING
                     LOCAL pzError  AS ASCIIZ POINTER 'Max is 64K
                     LOCAL ErrorLen AS DWORD
                                              BYVAL %NULL, ErrorCode, %NULL, BYVAL VARPTR(pzError), %NULL, BYVAL %NULL)
                     IF ErrorLen THEN
                       FUNCTION = "Error" & STR$(ErrorCode) & " (0x" & HEX$(ErrorCode) & ") : " & @pzError
                       FUNCTION = "Unknown error" & STR$(ErrorCode) & " (0x" & HEX$(ErrorCode) & ")"
                     END IF
                    END FUNCTION
                    FUNCTION reRichEditFromStringCallBack(BYVAL pDwordArray AS DWORD POINTER, BYVAL pRichEditBuffer AS DWORD, _
                                                          BYVAL cb AS LONG, BYREF pcb AS LONG) AS LONG
                     'pDwordArray     = Address of a two dword array used by application to send a string pointer and a string lenght
                     'pRichEditBuffer = Address of the rich edit buffer who will receive the string data
                     'cb              = Maximum byte count that the richEdit control could accept
                     'pcb             = Bytes count of the buffer that was pushed successfully at pRichEditBuffer by the application
                     pcb = MIN(@pDwordArray[1], cb)
                     IF pcb > 0 THEN
                       CopyMemory(pRichEditBuffer, @pDwordArray[0], pcb)
                       @pDwordArray[0] = @pDwordArray[0] + pcb
                       @pDwordArray[1] = @pDwordArray[1] - pcb
                     END IF
                    END FUNCTION
                    '____ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ____
                    FUNCTION reRichEditFromStringReplace(BYVAL hRichEdit AS DWORD, BYVAL rtfText AS STRING) AS LONG 'Send rtf String to a RichEdit
                     LOCAL EditStreamInfo AS EDITSTREAM
                     DIM dwArray(0 TO 1)  AS DWORD
                     dwArray(0)                 = STRPTR(rtfText)
                     dwArray(1)                 = LEN(rtfText)
                     EditStreamInfo.dwCookie    = VARPTR(dwArray(0))
                     EditStreamInfo.dwError     = 0
                     EditStreamInfo.pfnCallback = CODEPTR(reRichEditFromStringCallBack)
                     FUNCTION = SendMessage(hRichEdit, %EM_STREAMIN, %SF_RTF OR %SFF_PLAINRTF OR %SFF_SELECTION, VARPTR(EditStreamInfo))
                     'FUNCTION = SendMessage(hRichEdit, %EM_STREAMIN, %SF_RTF OR %SFF_SELECTION, VARPTR(EditStreamInfo))
                     IF EditStreamInfo.dwError THEN
                       'WinBeep(1500, 100) : WinBeep(1500, 100)
                         '0xfffffff0 (-16) passed blank string, or plaintext, or invalidly formatted rtf.
                         '0x80030070 Insufficient disk space to complete operation. This happens if rtf LimitText is too small (default is 32k!)
                         '0x80070026 (-2147024858) Reached the end of the file. This happens if you don't have a closing brace at the end of the file,
                         '                         or there's a null byte in the text somewhere.
                       MessageBox(hDlg, WinError$(EditStreamInfo.dwError), "reRichEditFromStringReplace", %MB_OK OR %MB_TOPMOST)
                     END IF
                    END FUNCTION
                    FUNCTION reRichEditToStringCallBack(BYVAL pString AS STRING POINTER, BYVAL pRichEditBuffer AS DWORD, _
                                                        BYVAL cb AS LONG, BYREF pcb AS LONG) AS LONG
                     'pString         Application dynamic string pointer
                     'pRichEditBuffer Address of the rich edit buffer who will give the string data
                     'cb              Number of bytes written at pRichEditBuffer
                     'pcb             Bytes count of the buffer that was pushed successfully at pRichEditBuffer by the application
                     LOCAL StringPreviousLen AS DWORD
                     StringPreviousLen = LEN(@pString)
                     @pString          = @pString & NUL$(cb)
                     pcb               = cb 'Needed to avoid a EditStreamInfo.dwError like 0x80070026 (-2147024858)
                     CopyMemory(STRPTR(@pString) + StringPreviousLen, pRichEditBuffer, cb)
                    END FUNCTION
                    '____ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ____
                    FUNCTION reRichEditToString(BYVAL hRichEdit AS DWORD) AS STRING 'Get selected text string from a RichEdit
                     LOCAL EditStreamInfo AS EDITSTREAM
                     LOCAL sBuffer        AS STRING
                     EditStreamInfo.dwCookie    = VARPTR(sBuffer)
                     EditStreamInfo.dwError     = 0
                     EditStreamInfo.pfnCallback = CODEPTR(reRichEditToStringCallBack)
                     SendMessage(hRichEdit, %EM_STREAMOUT, %SF_RTF OR 0 OR 0, VARPTR(EditStreamInfo)) '_ 'Returns characters written count
                     IF EditStreamInfo.dwError THEN
                       MessageBox(hDlg, sBuffer & $CRLF & WinError$(EditStreamInfo.dwError), "reRichEditToString", %MB_OK OR %MB_TOPMOST)
                     END IF
                     FUNCTION = sBuffer
                    END FUNCTION
                    FUNCTION reUrlGet(BYVAL pEnLink AS ENLINK POINTER) AS STRING
                     LOCAL TxtRange AS TEXTRANGE
                     LOCAL sUrl     AS STRING
                     sUrl               = NUL$((@pEnLink.chrg.cpMax - @pEnLink.chrg.cpMin) * 2 + 2)
                     TxtRange.lpstrText = STRPTR(sUrl)
                     TxtRange.chrg      = @pEnLink.chrg
                     SendMessage(@pEnLink.nmhdr.hwndFrom, %EM_GETTEXTRANGE , 0, VARPTR(TxtRange))
                     FUNCTION = RTRIM$(ACODE$(sUrl), $NUL)
                    END FUNCTION
                    CALLBACK FUNCTION DlgProc() AS LONG
                     LOCAL  pNMHDR        AS NMHDR  POINTER
                     LOCAL  pEnLink       AS ENLINK POINTER
                     LOCAL  rtfPrefix     AS STRING
                     LOCAL  rtfText       AS STRING
                     LOCAL  rtfPostfix    AS STRING
                     STATIC sUrl          AS STRING
                     STATIC sFriendlyName AS STRING
                     SELECT CASE CBMSG
                       CASE %WM_INITDIALOG
                         CONTROL SET TEXT hDlg, %EditFriendlyHyperLinkName, "PowerBASIC"
                         CONTROL SET TEXT hDlg, %EditFriendlyHyperLinkLink, ""
                         'A RTF file need some header, modify to your need...
                         rtfPrefix =  "{\rtf1\ansi{\*\generator Msftedit;}\lang1033"
                         'RTF text & link
                         rtfText =    "This is a RichEdit Friendly Name Hyperlinks! \par \par " & _
                                      "Double click on link... " & _
                                      "{\field{\*\fldinst{HYPERLINK " & $DQ & "" & $DQ & _
                                      "}}{\fldrslt{\ul\cf2 " & "MSN" & "}}}" & _
                                      "\par \par " & _
                                      "Above MSN will link to \par \par "
                         'RTF end }
                         rtfPostfix = "\n\par }"
                         reRichEditFromStringReplace(hRichEdit01, rtfPrefix & rtfText & rtfPostfix)
                         SendMessage(hRichEdit01, %EM_SETSEL, -1, -1)
                       CASE %WM_COMMAND
                         SELECT CASE CBCTL
                           CASE %ButtonRtfText
                             IF CBCTLMSG = %BN_Clicked OR CBCTLMSG = 1 THEN
                               rtfText = reRichEditToString(hRichEdit01)
                               MessageBox(hDlg, (rtfText), "RTF text to save as a file", %MB_OK OR %MB_TOPMOST)
                             END IF
                           CASE %ButtonFriendlyHyperlinkInsert
                             IF CBCTLMSG = %BN_Clicked OR CBCTLMSG = 1 THEN
                               CONTROL GET TEXT hDlg, %EditFriendlyHyperLinkName TO sFriendlyName
                               CONTROL GET TEXT hDlg, %EditFriendlyHyperLinkLink TO sUrl
                               rtfText = "{\rtf1{\colortbl;\red0\green0\blue255;}{\field{\*\fldinst{HYPERLINK " & $DQ & sUrl & $DQ & _
                                         "}}{\fldrslt{\ul\cf1 " & sFriendlyName & "}}}}"
                               reRichEditFromStringReplace(hRichEdit01, rtfText) 'Send rtf String to a RichEdit
                             END IF
                       END SELECT
                       CASE %WM_NOTIFY
                         pNMHDR = CBLPARAM
                         IF @pNMHDR.idFrom = %RichEdit01 THEN
                           SELECT CASE CBNMCODE
                             CASE %EN_LINK 'Action detected on hyperlink
                               pEnLink = CBLPARAM
                               SELECT CASE @pEnLink.msg
                                 CASE %WM_LBUTTONDBLCLK
                                   sUrl = reUrlGet(pEnLink)
                                   ShellExecute(%NULL, "open", (sUrl), "", "", %SW_SHOW)
                                   FUNCTION = %TRUE
                               END SELECT
                           END SELECT
                         END IF
                       CASE %WM_SIZE
                         IF CBWPARAM <> %SIZE_MINIMIZED THEN
                           MoveWindow(hRichEdit01, 5, 35, LO(WORD, CBLPARAM) - 10 , HI(WORD, CBLPARAM) - 40, %TRUE)
                           MoveWindow(GetDlgItem(hDlg, %EditFriendlyHyperLinkLink), 400, 8, LO(WORD, CBLPARAM) - 406, 24, %TRUE)
                         END IF
                     END SELECT
                    END FUNCTION
                    FUNCTION PBMAIN () AS LONG
                     LOCAL sCueBannerUnicode AS STRING
                     LOCAL hIcon             AS DWORD
                     LOCAL hLib              AS DWORD
                     hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294) 'o
                     DIALOG FONT "Segoe UI", 9
                     DIALOG NEW %HWND_DESKTOP, "RichEdit friendly name hyperlink", , , 350, 180, _
                     CONTROL ADD BUTTON, hDlg, %ButtonRtfText, "RTF text", 4, 4, 35, 13
                     CONTROL ADD BUTTON, hDlg, %ButtonFriendlyHyperlinkInsert, "Insert Friendly HyperLink", 40, 4, 85, 13
                     CONTROL ADD TEXTBOX, hDlg, %EditFriendlyHyperLinkName, "", 126, 4, 100, 13
                     sCueBannerUnicode = UCODE$("Friendly hyper link name")
                     SendDlgItemMessage(hDlg, %EditFriendlyHyperLinkName, %EM_SETCUEBANNER, 0, STRPTR(sCueBannerUnicode))
                     CONTROL ADD TEXTBOX, hDlg, %EditFriendlyHyperLinkLink, "", 228, 4, 228, 13
                     sCueBannerUnicode = UCODE$("Friendly hyper link URL")
                     SendDlgItemMessage(hDlg, %EditFriendlyHyperLinkLink, %EM_SETCUEBANNER, 0, STRPTR(sCueBannerUnicode))
                     hLib = LoadLibrary("MsftEdit.dll") 'MsftEdit.dll, RichEdit 4.1, RichEdit50W
                     CONTROL ADD "RichEdit50W", hDlg, %RichEdit01, "", 4, 15, 450, 150, _
                     hRichEdit01 = GetDlgItem(hDlg, %RichEdit01)
                     MessageBox(hDlg, richeditVersionGet(hRichEdit01), "RichEdit version", %MB_OK OR %MB_TOPMOST)
                     SendDlgItemMessage(hDlg, %RichEdit01, %EM_AUTOURLDETECT, %TRUE, 0)
                     SendDlgItemMessage(hDlg, %RichEdit01, %EM_SETEVENTMASK, 0, %ENM_LINK OR %ENM_PROTECTED)
                     SetClassLong(hDlg, %GCL_HICONSM, hIcon)
                     SetClassLong(hDlg, %GCL_HICON,   hIcon)
                     DIALOG SHOW MODAL hDlg CALL DlgProc
                    END FUNCTION
                    Last edited by Pierre Bellisle; 27 Dec 2018, 05:24 PM.


                    • #11
                      Thanks, Pierre!
                      Off to take a look ...


                      • #12
                        Howdy, Pierre!
                        Thanks again for the post. Here's some of what I found ...

                        When I double-click on "MSN", nothing happens here. Also, as I move the mouse over "MSN", the cursor does not change to indicate a link, as it does with ""

                        Also, when I press Insert Friendly a link appears, but it also does not respond to single or double clicking.

                        I notice that the original embedded link around MSN has no quotes around Are they optional? The page I gave a link to included single quotes.

                        "{\field{\*\fldinst{HYPERLINK""}}{\fldrslt{\ul\cf2 MSN \cf0\ul0}}}"
                        But I see that your Insert Friendly button does include the $DQ for use with the Insert Friendly button.

                        Is the above code the latest? When I press Insert Friendly and take a look at the RTF, it does not match what you show in your picture above. The word "Inserted:" and other pieces of what you shown in the image are not in my popup.

                        Click image for larger version  Name:	pb_2085.jpg Views:	1 Size:	30.3 KB ID:	777411


                        • #13
                          This might be another Windows 10 gift. I will test...
                          Yep, it is, I will see what can be done...

                          [Even more later]
                          Under Windows 10, ITextRange2::SetURL(BSTR bstr) method coud be used.
                          But it won't be available under Seven RichEdit 4.1. Good news is that a "RichEdit Friendly Name Hyperlink" created under 10 work fine under Seven. So a little reverse engineering is needed. Maybe I'll have time tomorrow...
                          {\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Courier New;}}
                          {\*\generator Msftedit;}\viewkind4\uc1\pard\lang1033\b\f0\fs22 123\b0\par
                          {\field{\*\fldinst {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2895153  HYPERLINK "" }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid2895153 {\*\datafield
                          }{\fldrslt {\rtlch\fcs1 \af31507 \ltrch\fcs0 \cs15\ul\cf17\insrsid2895153\charrsid2895153 PowerBASIC}}}
                          Windows 07 MsftEdit.dll v4.1 for RichEdit50w v6.1
                          Windows 10 MsftEdit.dll v10. for RichEdit50w v7.5

                          A start...
                          \field    Introduces a field destination that contains the text of fields. Fields have the following syntax:
                          \fldinst  Field instructions. This is a destination control word.
                          \fldrslt  Most recent calculated result of the field. This is a destination control word.
                          \rtlch    The character data following this control word will be treated as a right-to-left run.
                          \ltrch    The character data following this control word will be treated as a left-to-right run (the default).
                          \fcsN     N = 1 means South East Asian complex script; N = 0 means not South East Asian script    
                          \afN      Associated font number (the default is 0).
                          \csN      Designates character style. If a character style is specified,
                                    style properties must be specified with the character run.
                                    N refers to an entry in the style tab
                          \ul       Continuous underline. \ul0 turns off all underlining.
                          \cfN      Foreground color (the default is 0).
                          \insrsidN   Revision tracking
                          \charrsidN  RSID value identifying when character formatting was changed.
                          [Going betta and betta...]
                          Down to...
                          {\field{\*\fldinst{HYPERLINK ""}}{\fldrslt{\ul\cf4 PowerBASIC-Test}}}
                          Where \cf is the color index...
                          Last edited by Pierre Bellisle; 27 Dec 2018, 04:39 PM.


                          • #14
                            What if you try the updated code above...


                            • #15
                              Hey Pierre!
                              Kids over right now ... will test when they go to bed. Thanks!


                              • #16
                                Hey, Pierre, it works here! Both the originally embedded and inserted friendly URL's call up the browser at the indicated URL.


                                • #17
                                  Good, that was the intention. :-)

                                  P.S.: Putting the kids to bed so you can have fun coding is not fair play. ;-)


                                  • #18
                                    So, Pierre, your solution/example has several parts.

                                    1. The actual RTF code that provides the friendly URL

                                    {\field{\*\fldinst{HYPERLINK " & $Dq & "" & $Dq & "}}{\fldrslt{\ul\cf2 " & "MSN" & "}}}
                                    2. One function to extract the complete RTF from the RichEdit

                                    3. One function to put RTF into the RichEdit (replaces the selection. if nothing selected, inserts the RTF at the caret)

                                    To give the user the ability to type in a friendly user name for a URL, the user would type in the "friendly part", then select it, then right mouse click and select a context menu item "Insert Hyperlink" in the same fashion as MS Word uses. A popup dialog would be presented to the user, allowing them to type in the URL. The plain text selection would then be replaced by the magic RTF string.

                                    Very cool beans! Thank you for the effort to make the working example!


                                    • #19
                                      Well, now I have the wife to contend with. The kids will have stressed her out and now I have to get her chilled out. A coding grandpa's task is not an easy one!


                                      • #20
                                        Because of the way the RichEdit control creates RTF, I gather that we cannot simply extract the RTF corresponding to the selected text, then replace it. Instead, we must extract the entire RTF on which to perform the replacement. Is that true?

                                        If the RichEdit contains a 10MB+ file, that seems like another place where MS ought to have created an API that enables us to get the job done without manhandling the entire content of the file.

                                        ... added ... I don't think I read your code correctly. On second look, it does seem like the API just send the replacement RTF code, but it still seems that you've read out the entire RTF content. Perhaps you can clarify?