No announcement yet.

Friendly Name Hyperlinks - RichEdit

  • Filter
  • Time
  • Show
Clear All
new posts

  • #21

    The function to extract the complete RTF was meanly to show how to save to a file.

    You can extract selected text only, in either RTF or Text format.


    • #22
      Hi Pierre!
      Sorry, cross-posted. You answered the question for me, thanks! I tried to read too much into the extraction of the whole RTF


      • #23
        For the record: Why Windows 10 did not worked on the original code is that Windows 7 RichEdit 4.1 accept a "HYPERLINK" keyword without an ending space while newer RichEdit version don't. Wich is good.


        • #24
          Hi Pierre!

          So, if I have a RichEdit control that has this in it already ..


          ... I have to decide on what the friendly name should be.

          As best I know there is no universal standard on how to shorten a URL, similar to how there is an API to get a short name. But, I do wonder if the algorithm is available, and useful. Otherwise I'll just have to invent something myself.

          PathName$(NameX... would work for URLs with a filename on the end. But the friendly name for a URL that represents site "" might be just the 2 rightmost parts of the name. Coming up with a friendly name generator might be a work in progress for a while


          • #25

            I have eventually decyphered how to do user selected link names but its done like the prebuilt link names in richedit where you process the text like its a button. I am using this in a hyperlink engine for help files for my MASM project.

            The sequence is like this.
            1. The raw link = <\\Your Link Text>
            2. Set the "\\" as hidden text = <Your Link Text>
            3. Set the angle brackets to the same background colour = Your Link Text
            The link and background colour options are very limited for the link text, bright white on black OR a dull blue on any other colour.

            You set SendMessage hEdit,%EM_SETEVENTMASK,0,%ENM_LINK and SendMessage hEdit,%EM_AUTOURLDETECT,1,0 for the rich edit control.

            You process the WM_NOTIFY message to get the string from the link, strip the leading double slash and point the result string to a sub/function that uses a Select Case for string data.

            If you can use this technique, I will send it to you.
            hutch at movsd dot com
            The MASM Forum



            • #26
              Hi Steve, and thanks very much for the offer!

              My immediate need is that in an email client I've written, the incoming email body may include links. The idea is to replace the long link text with an active link whose visible text is a much shorter friendly name. Ideally the friendly name needs to let the user recognize the link, or at least to get some idea of where the link points. Friendly names like "Link1", "Link2", ... wouldn't give the user any information about the link target.

              I'm not clear on how your suggestion creates a shorter, informative friendly name. What am I missing?

              I'd certainly like to take you up on the offer. Perhaps it will clear things up for me.


              • #27

                It will depend on how the text is to be entered, I am using a dedicated RTF editor that I wrote and putting in a link is no more that selecting the link text I require and clicking a button that does the transformation shown above. Now I left the option of splitting the complete link from a link text and a display text something like this.
                The WRITE operation
                Raw link = <\\TheFullLinkRequired#The Display Data>
                Set "\\TheFullLinkRequired#" as hidden text so you only display the data you require.
                The READ operation
                In the WndProc processing the WM_NOTIFY message you get the original raw link.
                Parse everything up the the # char, remove the double slash and you have your link.
                Richedit also supports a list of internet prefixes like www, ftp and so on which you can do much the same thing with the link.

                Here is the WM_NOTIFY processing code I am using.
                      ' |||||||||||||||||||||||||||||||||||||||||||||||||||||
                        dim enl(0) as ENLINK at lParam                      ' overlay ENLINK at lParam
                          Select Case enl(0).nmhdr.hwndFrom                 ' select the sender's handle
                            Case hEdit
                              Select Case enl(0).nmhdr.code                 ' the notification code
                                Case %EN_LINK
                                  If enl(0).msg = %WM_LBUTTONDOWN Then      ' the sender's message
                                    cpMin = enl(0).chrg.cpMin
                                    cpMax = enl(0).chrg.cpMax
                                    tlen = cpMax - cpMin
                                    tbuf$ = space$(tlen)
                                    SendMessage hEdit,%EM_EXSETSEL,0,ByVal VarPtr(enl(0).chrg)
                                    SendMessage hEdit,%EM_GETSELTEXT,0,StrPtr(tbuf$)
                                    tbuf$ = right$(tbuf$,-2)                ' remove the left side notation "\\"
                                    Replace "#" with chr$(0) in tbuf$
                                    tbuf$ = ztrim$(tbuf$)
                                  ' *****************************************
                                    LoadRtfPage tbuf$                       ' a remote proc so you don't
                                                                            ' have a mess in your WndProc
                                  ' *****************************************
                                  End If
                              End Select
                          End Select
                        erase enl()
                      ' |||||||||||||||||||||||||||||||||||||||||||||||||||||
                This is the code in the RTF editor that converts selected text to a link that can be read by the above code.
                        ' ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                          Case 71
                            SendMessage hEdit,%EM_EXGETSEL,0,VarPtr(cr)
                            cpMin = cr.cpMin                                        ' copy the CHARRANGE members
                            cpMax = cr.cpMax                                        ' to variables
                            ! mov eax, cpMax                                        ' calculate selected length
                            ! sub eax, cpMin
                            ! test eax, eax                                         ' test for zero
                            ! jz pastit                                             ' exit if zero length
                            ! mov slen, eax
                            sbuf$ = space$(slen)
                            SendMessage hEdit,%EM_GETSELTEXT,0,StrPtr(sbuf$)        ' get the selected text
                            sbuf$ = "<\\"+sbuf$+">"                                 ' constructed link from string
                            cr.cpMax = cr.cpMin+len(sbuf$)                          ' set the insertion length
                            SendMessage hEdit,%EM_REPLACESEL,%TRUE,StrPtr(sbuf$)    ' replace original with raw link
                            cr.cpMin = cr.cpMin+1                                   ' modify CHARRANGE values
                            cr.cpMax = cr.cpMin+2                                   ' to select the "\\" pair
                            SendMessage hEdit,%EM_EXSETSEL,0,VarPtr(cr)             ' set the "\\" pair as hidden text
                            cfm.cbSize    = SIZEOF(cfm)
                            cfm.dwMask    = %CFM_HIDDEN
                            cfm.dwEffects = %CFE_HIDDEN
                            SendMessage hEdit,%EM_SETCHARFORMAT,%SCF_WORD or %SCF_SELECTION,ByVal VarPtr(cfm)
                            cr.cpMin = cr.cpMin-1                                   ' get the opening "<"
                            cr.cpMax = cpMax+4                                      ' get the closing ">"
                            SendMessage hEdit,%EM_EXSETSEL,0,VarPtr(cr)             ' select both < > in string
                            rtf_color(&H00000000)                                   ' set them to background colour
                        ' ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

                hutch at movsd dot com
                The MASM Forum



                • #28
                  Q> ... I have to decide on what the friendly name should be.

                  A simple way...

                  #COMPILE EXE '#Win 9.07 (D:\Basic\Bas\Jose Roca\Forum\Jose\Windows API Headers\1.19 (PB9.x)\uz)#
                  #DIM ALL
                  #INCLUDE ""
                  FUNCTION PBMAIN() AS LONG
                   LOCAL sUrl         AS STRING
                   LOCAL sFriendly    AS STRING
                   LOCAL PosEnd       AS LONG
                   LOCAL PosStart     AS LONG
                   LOCAL PrevNotAlpha AS LONG
                   LOCAL pByte        AS BYTE POINTER
                   'sUrl = ""
                   'sUrl = ""
                   sUrl = ""
                   'sUrl = "file:///HTMLPart01.htm"
                   'sUrl = "file:///aRt01.htm"
                   'sUrl = "pb_2091"
                   'Build friendly name
                   PosStart  = INSTR(-1, sUrl, "/") + 1
                   PosEnd    = INSTR(-1, sUrl, ".")
                   IF PosEnd = 0 THEN PosEnd = LEN(sUrl) + 1
                   sFriendly = MID$(sUrl, PosStart, PosEnd - PosStart)
                   'Optionnal capitalisation, check if already mixed case
                   pByte        = STRPTR(sFriendly)
                   LOCAL CharLo AS LONG
                   LOCAL CharUp AS LONG
                   FOR pByte = pByte TO pByte + LEN(sFriendly) 'Check lower and upper case characters count.
                     IF IsCharAlpha(@pByte) THEN
                       IF IsCharLower(@pByte) THEN
                         INCR CharLo
                       ELSE 'IsCharUpper()
                         INCR CharUp
                       END IF
                     END IF
                   'Optionnal capitalisation, if no mixed case then capitalize
                   IF CharLo * CharUp = 0 THEN 'All characters are of the same case. Not already capitalized.
                     PrevNotAlpha = %TRUE
                     pByte        = STRPTR(sFriendly)
                     FOR pByte = pByte TO pByte + LEN(sFriendly)
                       IF IsCharAlpha(@pByte) THEN
                         IF PrevNotAlpha THEN
                           CharUpperBuff(BYVAL pByte, 1)
                           PrevNotAlpha = %FALSE
                           CharLowerBuff(BYVAL pByte, 1)
                         END IF 'PRINT CHR$(ASC(sFriendly, PosStart))
                         PrevNotAlpha = %TRUE
                       END IF
                   END IF
                   MessageBox(%HWND_DESKTOP, sUrl & $CRLF & $CRLF & sFriendly, "Friendly", %MB_OK OR %MB_TOPMOST)
                  END FUNCTION


                  • #29
                    Hey Pierre!
                    Yes, using the name part of the NameX is a good start. However, this URL (from the forums) doesn't fit the mold as well ...



                    • #30
                      The idea is to replace the long link text with an active link whose visible text is a much shorter friendly name.
                      However, this ... doesn't fit the mold as well.

                      Automate the extraction of a "friendly name" from something that does not have anything meaningful is of course not possible.

                      If you do it by code as above, it will give result from "fair" to "not so bad" to "nonsense".
                      To always get good result you will have to use a human brain or a really impressive piece of code that will analyze the URL/FileName, read it's content and understand the context, then choose some meaningful words related to the global idea of it. Not an easy task.

                      If what you want is meant for PowerBASIC forum only and the problem is ending stuff like "/pageX" then it's of course no big deal.
                      Maybe the question is too large for a precise suggestion.


                      • #31
                        When the link is unrecognizable to the point that makes it difficult to build a friendly name or it is not in a previously generated table why not use a generic name "Link 01" or "Link 02" or "Link 03" as the friendly name and show the full link when the user's mouse cursor is over the generic friendly name.