InunoTaishou

RichEdit Hyperlinks (Friendly)

2 posts in this topic

#1 ·  Posted (edited)

I think RichEdit has been my favorite thing I've ever discovered on AutoIt lol. In my quest to add in more html tags to my _StringToRichEditArray I needed a way to do href! There was an example I found that I followed but it didn't format correctly and didn't work 100% but it gave me a good base. Think I'll tackle inserting an image next, not looking forward to that. If anyone has an idea on how to do it let me know.

Known issues (these will cause the hyperlink to lose the +li attribute after the RichEdit is updated):

  1. The hyperlink and friendly text are appended/inserted (directly adjacent to a non whitespace) but the hyperlink is not a valid hyperlink.
  2. Changing the char color for the control causes the hyperlink to lose it's hyperlink color (the light blue).

Fix for Issue 1:

  • Use the full URL for the hyperlink (https://www.autoitscript.com/site/ instead of www.autoitscript.com/site)
  • Use any hyperlink with any friendly text that does not have www at the beginning (Hyperlink: www.google.com, Friendly Text: google.com)
  • Use any hyperlink with any, or no, friendly text, but have a whitespace to the left of the hyperlink.

Fix for Issue 2:

  • I have no fix.

Updated RichEdit Hyperlink.au3

Spoiler
#include-once
#include <GUIRichEdit.au3>

; Valid URL schemes
Global Const $RTF_SCHEME_URL_ARRAY[] = ["http:", "file:", "mailto:", "ftp:", "https:", "gopher:", "nntp:", "prospero:", "telnet:", "news:", "wais:"]
; Friendly text color (friendly text has the default $hWnd char color when inserted, this changes it to look the same as a normal URL)
Global Const $COLOR_HYPERLINK = 0xCC6600
; Struct used to change the text color without changing the text color for all of the $hWnd
Global $__tCharFormat = DllStructCreate($tagCHARFORMAT)
DllStructSetData($__tCharFormat, 1, DllStructGetSize($__tCharFormat))
DllStructSetData($__tCharFormat, 2, $CFM_COLOR)

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlRichEdit_InsertHyperlink
; Description ...: Inserts a hyplink at the current caret position for a RichEdit control.
; Syntax.........: _GUICtrlRichEdit_InsertHyperlink(Const ByRef $hWnd, Const ByRef $sHyperLink, $sFriendly = "", Const $bRemoveScheme = True, Const $bRemoveLeadSlash = True)
; Parameters ....: $hWnd                - Handle to the RichEdit control
;                  $sHyperLink          - The hyperlink URL (https://www.autoitscript.com/"
;                  $sFriendly           - [optional] Friendly string that is displayed instead of the hyperlink URL.
;                  $bRemoveScheme       - [optional] Remove the scheme in the friendly string (one of the schcmes in the $RTF_SCHEME_URL_ARRAY). (https://www.google.com/)
;                  $bRemoveLeadSlash    - [optional] Remove the two leading slash(es) in the friendly string. (//www.google.com)
; Return values .: Success - Returns True
;                  Failure - Returns False and sets @Error to a non-zero.
;                       |101 = _GUICtrlRichEdit_InsertText: $hWnd is not a handle
;                       |102 = $sHyperLink = ""
;                       |103 = _GUICtrlRichEdit_InsertText: Cannot bet set
; Author ........: InunoTaishou
; Example .......: _GUICtrlRichEdit_InsertHyperlink($hWnd, "https://www.autoitscript.com/site/", "AutoIt Website")
; ===============================================================================================================================
Func _GUICtrlRichEdit_InsertHyperlink(Const ByRef $hWnd, Const ByRef $sHyperLink, $sFriendly = "", Const $bRemoveScheme = True, Const $bRemoveLeadSlash = True)
    Local $__hl_insert
    If ($sHyperLink = "") Then Return SetError(102, 0, False)
    If ($sFriendly = "" Or $sFriendly = Default) Then
        $sFriendly = $sHyperLink
        For $_scheme_index = 0 To UBound($RTF_SCHEME_URL_ARRAY) - 1
            If (StringLeft($sHyperLink, StringLen($RTF_SCHEME_URL_ARRAY[$_scheme_index])) = $RTF_SCHEME_URL_ARRAY[$_scheme_index]) Then ExitLoop
        Next
        If ($_scheme_index < UBound($RTF_SCHEME_URL_ARRAY)) Then
            If ($bRemoveScheme) Then $sFriendly = StringReplace($sFriendly, $RTF_SCHEME_URL_ARRAY[$_scheme_index], "")
            If ($bRemoveLeadSlash) Then $sFriendly = StringRegExpReplace($sFriendly, "^/{1,2}", "")
        EndIf
    EndIf
    $sFriendly = StringRegExpReplace($sFriendly, "\\", "\\\\")  ; convert single slash to escape character slash
    $__hl_insert = '{\rtf{\field{\*\fldinst{HYPERLINK "' & $sHyperLink & '"}{\fldrslt{\ul ' & $sFriendly & '}}}}}'
    DllStructSetData($__tCharFormat, 6, $COLOR_HYPERLINK)   ; set text color to $COLOR_HYPERLINK
    _SendMessage($hWnd, $EM_SETCHARFORMAT, $SCF_SELECTION, DllStructGetPtr($__tCharFormat)) ; send color change to $hWnd without changing all other text color
    Return _GUICtrlRichEdit_InsertText($hWnd, $__hl_insert)
EndFunc   ;==>_GUICtrlRichEdit_InsertHyperlink

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlRichEdit_AppendHyperlink
; Description ...: Appends a hyperlink to the RichEdit control.
; Syntax.........: _GUICtrlRichEdit_AppendHyperlink(Const ByRef $hWnd, Const ByRef $sHyperLink, $sFriendly = "", Const $bRemoveScheme = True, Const $bRemoveLeadSlash = True)
; Parameters ....: $hWnd                - Handle to the RichEdit control
;                  $sHyperLink          - The hyperlink URL (https://www.autoitscript.com/"
;                  $sFriendly           - [optional] Friendly string that is displayed instead of the hyperlink URL.
;                  $bRemoveScheme       - [optional] Remove the scheme in the friendly string (one of the schcmes in the $RTF_SCHEME_URL_ARRAY).
;                  $bRemoveLeadSlash    - [optional] Remove the two leading slash(es) in the friendly string.
; Return values .: Success - Returns True
;                  Failure - Returns False and sets @Error to a non-zero.
;                       |101 = _GUICtrlRichEdit_InsertText: $hWnd is not a handle
;                       |102 = $sHyperLink = ""
;                       |103 = _GUICtrlRichEdit_InsertText: Cannot bet set
; Author ........: InunoTaishou
; Example .......: _GUICtrlRichEdit_AppendHyperlink($hWnd, "https://www.autoitscript.com/site/", "AutoIt Website")
; ===============================================================================================================================
Func _GUICtrlRichEdit_AppendHyperlink(Const ByRef $hWnd, Const ByRef $sHyperLink, $sFriendly = "", Const $bRemoveScheme = True, Const $bRemoveLeadSlash = True)
    _GUICtrlRichEdit_SetSel($hWnd, -1, -1)
    _GUICtrlRichEdit_InsertHyperlink($hWnd, $sHyperLink, $sFriendly, $bRemoveScheme, $bRemoveLeadSlash)
    Return (@Error ? SetError(@Error, 0, False) : True)
EndFunc   ;==>_GUICtrlRichEdit_AppendHyperlink

 

Demo

Spoiler
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIRichEdit.au3>
#include "RichEdit Hyperlink.au3"

AutoItSetOption("MouseCoordMode", 2)

Global $rtf_msg = "Hyperlink Example." & @CRLF & "Friendly text is an optional field. If it is blank then the hyperlink is used as the text." & @CRLF & @CRLF & _
"If the hyperlink is used as the text then the _GUICtrlRichEdit_AppendHyperlink and _GUICtrlRichEdit_InsertHyperlink will remove the url scheme and leading // (by default, optional arguments)" & @CRLF & @CRLF & _
"Knowns issues: The hyperlink and friendly text are appended/inserted (directly adjacent to a non whitespace) but the hyperlink is not a valid hyperlink." & @CRLF & @TAB & _
"How to solve this issue:" & @CRLF & @TAB & _
"1. Use the full URL for the hyperlink (https://www.autoitscript.com/site/ instead of www.autoitscript.com/site)" & @CRLF & @TAB & _
"2. Use any hyperlink with any friendly text that does not have www at the beginning (Hyperlink: www.google.com, Friendly Text: google.com)" & @CRLF & @TAB & _
"3. Use any hyperlink with any, or no, friendly text, but have a whitespace to the left of the hyperlink." & @CRLF & _
"A friendly text hyperlink will be inserted || in this line" & @CRLF & _
"The best search engine around: "
Global $frmHyperlink = GUICreate("Hyperlink Example", 600, 320)
Global $rtfRichEdit = _GUICtrlRichEdit_Create($frmHyperlink, "", 10, 10, 580, 150, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
Global $inpHyperlink = GUICtrlCreateInput(@DesktopDir, 10, 195, 580, 25, -1, $WS_EX_CLIENTEDGE)
GUICtrlSetFont(-1, 12, 400, 0, "Times New Roman")
GUICtrlSetTip(-1, "Hyperlink to insert or append")
Global $inpFriendly = GUICtrlCreateInput("Desktop", 10, 250, 580, 25, -1, $WS_EX_CLIENTEDGE)
GUICtrlSetFont(-1, 12, 400, 0, "Times New Roman")
GUICtrlSetTip(-1, "Friendly text to display instead of the link")
GUICtrlCreateLabel("Hyperlink", 10, 170, 100, 20, -1, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Segoe UI")
GUICtrlSetBkColor(-1, "-2")
GUICtrlSetTip(-1, "Hyperlink to insert or append")
GUICtrlCreateLabel("Friendly Text", 10, 225, 100, 20, -1, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Segoe UI")
GUICtrlSetBkColor(-1, "-2")
GUICtrlSetTip(-1, "Friendly text to display instead of the link")
Global $btnInsert = GUICtrlCreateButton("Insert Hyperlink", 10, 285, 285, 25, -1, -1)
GUICtrlSetFont(-1, 10, 400, 0, "Segoe UI")
Global $btnAppend = GUICtrlCreateButton("Append Hyperlink", 305, 285, 285, 25, -1, -1)
GUICtrlSetFont(-1, 10, 400, 0, "Segoe UI")
GUICtrlSetTip(-1, "Append hyperlink to end of Rich Edit")

_GUICtrlRichEdit_SetText($rtfRichEdit, $rtf_msg)
_GUICtrlRichEdit_SetSel($rtfRichEdit, 0, -1, True)
_GUICtrlRichEdit_SetFont($rtfRichEdit, 8.5, "Segoe UI")
_GUICtrlRichEdit_SetSel($rtfRichEdit, -1, -1, False)
_GUICtrlRichEdit_AutoDetectURL($rtfRichEdit, True)
_GUICtrlRichEdit_SetEventMask($rtfRichEdit, $ENM_LINK)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $frmHyperlink)

If (MsgBox($MB_YESNO + $MB_ICONQUESTION, "Example", "Would you like to see the example in action?" & @CRLF & "" & @CRLF & "(_Example() will move your mouse for a second and the example GUI will be disabled during the duration)") = 6) Then
    GUISetState(@SW_DISABLE, $frmHyperlink)
    _Example()
    GUISetState(@SW_ENABLE, $frmHyperlink)
EndIf

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            _GUICtrlRichEdit_Destroy($rtfRichEdit)
            GUIDelete($frmHyperlink)
            Exit 0
        Case $btnInsert
            _GUICtrlRichEdit_InsertHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
            If (@error) Then Report(@error)
            _WinAPI_SetFocus($rtfRichEdit)
        Case $btnAppend
            _GUICtrlRichEdit_AppendHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
            If (@error) Then Report(@error)
            _WinAPI_SetFocus($rtfRichEdit)
    EndSwitch
WEnd

Func _Example()
    WinSetTitle($frmHyperlink, "", "Hyperlink Example (_GUICtrlRichEdit_InsertHyperlink)")
    Local $caret_pos = StringInStr(_GUICtrlRichEdit_GetText($rtfRichEdit), "|| in this line")
    Local $pos = _GUICtrlRichEdit_GetXYFromCharPos($rtfRichEdit, $caret_pos)
    If Not @error Then MouseMove($pos[0] + 12, $pos[1] + 18, 15)
    _GUICtrlRichEdit_SetSel($rtfRichEdit, $caret_pos, $caret_pos)
    MoveAndSetData($inpHyperlink, "https://www.autoitscript.com/site/", 50, 205, 500)
    MoveAndSetData($inpFriendly, "AutoIt Script", 50, 260, 300)
    MoveAndSetData(0, "", 100, 295, 300, 200)
    _GUICtrlRichEdit_InsertHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
    WinSetTitle($frmHyperlink, "", "Hyperlink Example (_GUICtrlRichEdit_AppendHyperlink)")
    MoveAndSetData($inpHyperlink, "https://www.google.com/", 50, 205, 500)
    MoveAndSetData($inpFriendly, "Google", 50, 260, 300)
    MoveAndSetData(0, "", 400, 295, 300, 200)
    _GUICtrlRichEdit_AppendHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
    MoveAndSetData($inpHyperlink, "www.google.com", 50, 205, 1000)
    MoveAndSetData($inpFriendly, "", 50, 260, 300)
    MoveAndSetData(0, "", 400, 295, 300, 200)
    _GUICtrlRichEdit_AppendText($rtfRichEdit, @CRLF & "(On this line)No friendly text used (Space directly to the left of my URL): ")
    WinSetTitle($frmHyperlink, "", "Hyperlink Example (_GUICtrlRichEdit_AppendHyperlink No Friendly Text)")
    _GUICtrlRichEdit_AppendHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
    Sleep(500)
    _GUICtrlRichEdit_AppendText($rtfRichEdit, @CRLF & "In the next line, same Hyperlink and Friendly Text used but there is no space to the left")
    _GUICtrlRichEdit_AppendText($rtfRichEdit, @CRLF & "(On this line)No friendly text used (No space directly to the left of my URL):")
    _GUICtrlRichEdit_AppendHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
    Sleep(500)
    WinSetTitle($frmHyperlink, "", "Hyperlink Example")
EndFunc   ;==>_Example

Func MoveAndSetData($ctrlId, $sText, $iX, $iY, $iSleepDelay, $iSleepDelay2 = 0)
    Sleep($iSleepDelay)
    MouseMove($iX, $iY)
    If ($ctrlId) Then GUICtrlSetData($ctrlId, $sText)
    If ($iSleepDelay2) Then Sleep($iSleepDelay2)
EndFunc

Func Report($iErrorCode)
    Local $error_msg = ""
    Switch ($iErrorCode)
        Case 101
            $error_msg = "_GUICtrlRichEdit_InsertText: $hWnd is not a handle"
        Case 102
            $error_msg = '$sHyperLink = ""'
        Case 103
            $error_msg = "_GUICtrlRichEdit_InsertText: Cannot bet set"
    EndSwitch
    _GUICtrlRichEdit_AppendText($rtfRichEdit, @CRLF & $error_msg & @CRLF)
EndFunc   ;==>Report

Func WM_NOTIFY($hWndFrom, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $tEnLink = DllStructCreate($tagENLINK, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam)
    
    Switch (DllStructGetData($tNMHDR, "hWndFrom"))
        Case $rtfRichEdit
            Switch (DllStructGetData($tNMHDR, "Code"))
                Case $EN_LINK
                    If DllStructGetData($tMsgFilter, "msg") = $WM_LBUTTONUP Then
                        ShellExecute(_GUICtrlRichEdit_GetTextInRange($rtfRichEdit, DllStructGetData($tEnLink, "cpMin"), DllStructGetData($tEnLink, "cpMax")))
                    EndIf
            EndSwitch
    EndSwitch
    
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

Original Post, outdated: Had a problem with inserting/appending hyperlinks that pointed to the local computer. (C:\Windows\)

Spoiler

"RichEdit Hyperlink.au3"

#include-once
#include <GUIRichEdit.au3>

; Offset number when inserting/appending a hyperlink. My guess is there's some characters in the rtf that aren't displayed but are counted.
Global Const $RTF_HYPERLINK_MAGIC_OFFSET = 12
Global Const $RTF_SCHEME_URL_ARRAY[] = ["http:", "file:", "mailto:", "ftp:", "https:", "gopher:", "nntp:", "prospero:", "telnet:", "news:", "wais"]

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlRichEdit_InsertHyperlink
; Description ...: Inserts a hyplink at the current caret position for a RichEdit control.
; Syntax.........: _GUICtrlRichEdit_InsertHyperlink(Const ByRef $hWnd, Const ByRef $sHyperLink, $sFriendly = "", Const $bRemoveScheme = True, Const $bRemoveLeadSlash = True)
; Parameters ....: $hWnd                - Handle to the RichEdit control
;                  $sHyperLink          - The hyperlink URL (https://www.autoitscript.com/"
;                  $sFriendly           - [optional] Friendly string that is displayed instead of the hyperlink URL.
;                  $bRemoveScheme       - [optional] Remove the scheme in the friendly string (one of the schcmes in the $RTF_SCHEME_URL_ARRAY).
;                  $bRemoveLeadSlash    - [optional] Remove the two leading slash(es) in the friendly string.
; Return values .: Success - Returns True
;                  Failure - Returns False and sets @Error to a non-zero.
;                       @Error -1   - Could not find the string used to detect where to insert the URL in the rtf stream.
;                       |101 = $hWnd is not a richedit handle.
;                       |103 = Could not insert the text used to delimit where to insert the hyperlink.
;                       |1041 = _GUICtrlRichEdit_StreamToVar: $SFF_PLAINRTF is invalid for a text file.
;                       |1042 = _GUICtrlRichEdit_StreamToVar: $opts: invalid option.
;                       |1043 = _GUICtrlRichEdit_StreamToVar: $SF_UNICODE is only valid for a text file.
;                       |700 = _GUICtrlRichEdit_StreamToVar: internal error.
; Author ........: InunoTaishou
; Example .......: _GUICtrlRichEdit_InsertHyperlink($hWnd, "https://www.autoitscript.com/site/", "AutoIt Website")
; ===============================================================================================================================
Func _GUICtrlRichEdit_InsertHyperlink(Const ByRef $hWnd, Const ByRef $sHyperLink, $sFriendly = "", Const $bRemoveScheme = True, Const $bRemoveLeadSlash = True)
    If ($sFriendly = "" Or $sFriendly = Default) Then
        For $_scheme_index = 0 To UBound($RTF_SCHEME_URL_ARRAY) - 1
            If (StringLeft($sHyperLink, StringLen($RTF_SCHEME_URL_ARRAY[$_scheme_index])) = $RTF_SCHEME_URL_ARRAY[$_scheme_index]) Then ExitLoop
        Next
        $sFriendly = $sHyperLink
        If ($_scheme_index < UBound($RTF_SCHEME_URL_ARRAY)) Then
            If ($bRemoveScheme) Then $sFriendly = StringReplace($sFriendly, $RTF_SCHEME_URL_ARRAY[$_scheme_index], "")
            If ($bRemoveLeadSlash) Then $sFriendly = StringRegExpReplace($sFriendly, "^/{1,2}", "")
        EndIf
    EndIf
    
    Local Const $__string_replace = '{\field{\*\fldinst{HYPERLINK "' & $sHyperLink & '"}}{\fldrslt{\ul ' & $sFriendly & '}}}\cf0\ulnone\f0 '
    Local Const $__hyper_length = StringLen($sHyperLink) + $RTF_HYPERLINK_MAGIC_OFFSET
    Local Const $__friendly_length = StringLen($sFriendly)
    Local $__sel_range = _GUICtrlRichEdit_GetSel($hWnd)
    If (@error) Then Return SetError(@error, 0, False)

    _GUICtrlRichEdit_PauseRedraw($hWnd)
    _GUICtrlRichEdit_InsertText($hWnd, " [gcreihl] ")
    
    Local $__rtf_stream = _GUICtrlRichEdit_StreamToVar($hWnd)
    Local $__rtf_stream_backup = $__rtf_stream
    If (@error) Then
        _GUICtrlRichEdit_ResumeRedraw($hWnd)
        Return SetError(@error, 0, False)
    EndIf
    
    $__rtf_stream = StringReplace($__rtf_stream, " [gcreihl] ", $__string_replace, 1)
    If (Not @extended) Then
        _GUICtrlRichEdit_SetText($hWnd, $__rtf_stream_backup)
        _GUICtrlRichEdit_ResumeRedraw($hWnd)
        Return SetError(-1, 0, False)
    EndIf
    
    _GUICtrlRichEdit_SetText($hWnd, $__rtf_stream)
    _GUICtrlRichEdit_SetSel($hWnd, $__sel_range[0], $__sel_range[0] + $__friendly_length + ($sFriendly = $sHyperLink ? 0 : $__hyper_length))
    _GUICtrlRichEdit_SetCharColor($hWnd, 0xCC6600)
    _GUICtrlRichEdit_SetCharAttributes($hWnd, "+li")
    _GUICtrlRichEdit_Deselect($hWnd)
    _GUICtrlRichEdit_SetCharAttributes($hWnd, "-li")
    _GUICtrlRichEdit_ResumeRedraw($hWnd)
EndFunc   ;==>_GUICtrlRichEdit_InsertHyperlink

; #FUNCTION# ====================================================================================================================
; Name...........: _GUICtrlRichEdit_AppendHyperlink
; Description ...: Sets caret in the RichEdit control to the end and calls _GUICtrlRichEdit_InsertHyperlink
; Syntax.........: _GUICtrlRichEdit_AppendHyperlink(Const ByRef $hWnd, Const ByRef $sHyperLink, $sFriendly = "", Const $bRemoveScheme = True, Const $bRemoveLeadSlash = True)
; Parameters ....: $hWnd                - Handle to the RichEdit control
;                  $sHyperLink          - The hyperlink URL (https://www.autoitscript.com/"
;                  $sFriendly           - [optional] Friendly string that is displayed instead of the hyperlink URL.
;                  $bRemoveScheme       - [optional] Remove the scheme in the friendly string (one of the schcmes in the $RTF_SCHEME_URL_ARRAY).
;                  $bRemoveLeadSlash    - [optional] Remove the two leading slash(es) in the friendly string.
; Return values .: Success - Returns True
;                  Failure - Returns False and sets @Error to a non-zero.
;                       @Error -1   - Could not find the string used to detect where to insert the URL in the rtf stream.
;                       |101 = $hWnd is not a richedit handle.
;                       |103 = Could not insert the text used to delimit where to insert the hyperlink.
;                       |1041 = _GUICtrlRichEdit_StreamToVar: $SFF_PLAINRTF is invalid for a text file.
;                       |1042 = _GUICtrlRichEdit_StreamToVar: $opts: invalid option.
;                       |1043 = _GUICtrlRichEdit_StreamToVar: $SF_UNICODE is only valid for a text file.
;                       |700 = _GUICtrlRichEdit_StreamToVar: internal error.
; Author ........: InunoTaishou
; Example .......: _GUICtrlRichEdit_AppendHyperlink($hWnd, "https://www.autoitscript.com/site/", "AutoIt Website")
; ===============================================================================================================================
Func _GUICtrlRichEdit_AppendHyperlink(Const ByRef $hWnd, Const ByRef $sHyperLink, $sFriendly = "", Const $bRemoveScheme = True, Const $bRemoveLeadSlash = True)
    _GUICtrlRichEdit_SetSel($hWnd, -1, -1)
    _GUICtrlRichEdit_InsertHyperlink($hWnd, $sHyperLink, $sFriendly, $bRemoveScheme, $bRemoveLeadSlash)
    Return (@error ? SetError(@error, 0, False) : True)
EndFunc   ;==>_GUICtrlRichEdit_AppendHyperlink

And a demo to go with it!

#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GUIRichEdit.au3>
#include "RichEdit Hyperlink.au3"

AutoItSetOption("MouseCoordMode", 2)

Global $rtf_msg = "Hyperlink Example." & @CRLF & "Friendly text is an optional field. If it is blank then the hyperlink is used as the text." & @CRLF & @CRLF & _
        "If the hyperlink is used as the text then the _GUICtrlRichEdit_AppendHyperlink and _GUICtrlRichEdit_InsertHyperlink will remove the url scheme and leading // (by default)" & @CRLF & @CRLF & _
        "Knowns issues: The hyperlink and friendly text are appended/inserted (directly adjacent to a non whitespace) but upon editing the richedit, they lose the +li attribute" & @CRLF & _
        @TAB & "How to solve this issue: Use the full URL for the hyperlink, Use any hyperlink with any friendly text," & @TAB & _
            "use any hyperlink, no friendly text, but have a whitespace to the left of the hyperlink" & @CRLF & _
        "A friendly text hyperlink will be inserted || in this line" & @CRLF & _
        "The best search engine around: "
Global $frmHyperlink = GUICreate("Hyperlink Example (_GUICtrlRichEdit_InsertHyperlink)", 600, 320)
Global $rtfRichEdit = _GUICtrlRichEdit_Create($frmHyperlink, "", 10, 10, 580, 150, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
Global $inpHyperlink = GUICtrlCreateInput("https://www.google.com/?gws_rd=ssl", 10, 195, 580, 25, -1, $WS_EX_CLIENTEDGE)
GUICtrlSetFont(-1, 12, 400, 0, "Times New Roman")
GUICtrlSetTip(-1, "Hyperlink to insert or append")
Global $inpFriendly = GUICtrlCreateInput("Google", 10, 250, 580, 25, -1, $WS_EX_CLIENTEDGE)
GUICtrlSetFont(-1, 12, 400, 0, "Times New Roman")
GUICtrlSetTip(-1, "Friendly text to display instead of the link")
GUICtrlCreateLabel("Hyperlink", 10, 170, 100, 20, -1, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Segoe UI")
GUICtrlSetBkColor(-1, "-2")
GUICtrlSetTip(-1, "Hyperlink to insert or append")
GUICtrlCreateLabel("Friendly Text", 10, 225, 100, 20, -1, -1)
GUICtrlSetFont(-1, 12, 400, 0, "Segoe UI")
GUICtrlSetBkColor(-1, "-2")
GUICtrlSetTip(-1, "Friendly text to display instead of the link")
Global $btnInsert = GUICtrlCreateButton("Insert Hyperlink", 10, 285, 285, 25, -1, -1)
GUICtrlSetFont(-1, 10, 400, 0, "Segoe UI")
Global $btnAppend = GUICtrlCreateButton("Append Hyperlink", 305, 285, 285, 25, -1, -1)
GUICtrlSetFont(-1, 10, 400, 0, "Segoe UI")
GUICtrlSetTip(-1, "Append hyperlink to end of Rich Edit")

_GUICtrlRichEdit_SetText($rtfRichEdit, $rtf_msg)
_GUICtrlRichEdit_SetSel($rtfRichEdit, 0, -1, True)
_GUICtrlRichEdit_SetFont($rtfRichEdit, 8.5, "Segoe UI")
_GUICtrlRichEdit_SetSel($rtfRichEdit, -1, -1, False)
_GUICtrlRichEdit_AutoDetectURL($rtfRichEdit, True)

GUISetState(@SW_SHOW, $frmHyperlink)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
_GUICtrlRichEdit_SetEventMask($rtfRichEdit, $ENM_LINK)

If (MsgBox($MB_YESNO + $MB_ICONQUESTION, "Example", "Would you like to see the example in action?" & @CRLF & "" & @CRLF & "(_Example() will move your mouse for a second and the example GUI will be disabled during the duration)") = 6) Then
    GUISetState(@SW_DISABLE, $frmHyperlink)
    _Example()
    GUISetState(@SW_ENABLE, $frmHyperlink)
EndIf
WinSetTitle($frmHyperlink, "", "Hyperlink Example")

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            _GUICtrlRichEdit_Destroy($rtfRichEdit)
            GUIDelete($frmHyperlink)
            Exit 0
        Case $btnInsert
            _GUICtrlRichEdit_InsertHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
            If (@error) Then Report(@error)
        Case $btnAppend
            _GUICtrlRichEdit_AppendHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
            If (@error) Then Report(@error)
    EndSwitch
WEnd

Func _Example()
    Local $caret_pos = StringInStr(_GUICtrlRichEdit_GetText($rtfRichEdit), "|| in this line")
    Local $pos = _GUICtrlRichEdit_GetXYFromCharPos($rtfRichEdit, $caret_pos)
    If Not @error Then MouseMove($pos[0] + 8, $pos[1] + 16, 15)
    _GUICtrlRichEdit_SetSel($rtfRichEdit, $caret_pos, $caret_pos)
    MoveAndSetData($inpHyperlink, "https://www.autoitscript.com/site/", 50, 205, 500)
    MoveAndSetData($inpFriendly, "AutoIt Script", 50, 260, 300)
    MoveAndSetData(0, "", 100, 295, 300, 200)
    _GUICtrlRichEdit_InsertHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
    WinSetTitle($frmHyperlink, "", "Hyperlink Example (_GUICtrlRichEdit_AppendHyperlink)")
    MoveAndSetData($inpHyperlink, "https://www.google.com/", 50, 205, 500)
    MoveAndSetData($inpFriendly, "Google", 50, 260, 300)
    MoveAndSetData(0, "", 400, 295, 300, 200)
    _GUICtrlRichEdit_AppendHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
    MoveAndSetData($inpHyperlink, "www.google.com", 50, 205, 1000)
    MoveAndSetData($inpFriendly, "", 50, 260, 300)
    MoveAndSetData(0, "", 400, 295, 300, 200)
    _GUICtrlRichEdit_AppendText($rtfRichEdit, @CRLF & "(On this line)No friendly text used (Space directly to the left of my URL): ")
    WinSetTitle($frmHyperlink, "", "Hyperlink Example (_GUICtrlRichEdit_AppendHyperlink No Friendly Text)")
    _GUICtrlRichEdit_AppendHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
    Sleep(500)
    _GUICtrlRichEdit_AppendText($rtfRichEdit, @CRLF & "In the next line, once you edit this RichEdit the google URL will lose the +li attribute because there is no space to the left of it")
    _GUICtrlRichEdit_AppendText($rtfRichEdit, @CRLF & "(On this line)No friendly text used (No space directly to the left of my URL):")
    _GUICtrlRichEdit_AppendHyperlink($rtfRichEdit, GUICtrlRead($inpHyperlink), GUICtrlRead($inpFriendly))
    Sleep(500)
EndFunc   ;==>_Example

Func MoveAndSetData($ctrlId, $sText, $iX, $iY, $iSleepDelay, $iSleepDelay2 = 0)
    Sleep($iSleepDelay)
    MouseMove($iX, $iY)
    If ($ctrlId) Then GUICtrlSetData($ctrlId, $sText)
    If ($iSleepDelay2) Then Sleep($iSleepDelay2)
EndFunc

Func Report($iErrorCode)
    Local $error_msg = ""
    Switch ($iErrorCode)
        Case -1
            $error_msg = "(StringReplace)Could not remove string used to detect insertion point in the rtf formatted string"
        Case 101
            $error_msg = "(All RichEdit function calls)$hWnd is not a handle"
        Case 103
            $error_msg = "_GUICtrlRichEdit_InsertText: Cannot be set"
        Case 1041
            $error_msg = "_GUICtrlRichEdit_StreamToVar: $SFF_PLAINRTF is invalid for a text file"
        Case 1042
            $error_msg = "_GUICtrlRichEdit_StreamToVar: $opts: invalid option"
        Case 1043
            $error_msg = "_GUICtrlRichEdit_StreamToVar: $SF_UNICODE is only valid for a text file"
        Case 700
            $error_msg = "_GUICtrlRichEdit_StreamToVar: internal error"
    EndSwitch
    _GUICtrlRichEdit_AppendText($rtfRichEdit, @CRLF & $error_msg & @CRLF)
EndFunc   ;==>Report

Func WM_NOTIFY($hWndFrom, $iMsg, $wParam, $lParam)
    #forceref $hWndFrom, $iMsg, $wParam
    Local $tEnLink = DllStructCreate($tagENLINK, $lParam)
    Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam)
    
    Switch (DllStructGetData($tNMHDR, "hWndFrom"))
        Case $rtfRichEdit
            Switch (DllStructGetData($tNMHDR, "Code"))
                Case $EN_LINK
                    If DllStructGetData($tMsgFilter, "msg") = $WM_LBUTTONUP Then
                        ShellExecute(_GUICtrlRichEdit_GetTextInRange($rtfRichEdit, DllStructGetData($tEnLink, "cpMin"), DllStructGetData($tEnLink, "cpMax")))
                    EndIf
            EndSwitch
    EndSwitch
    
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

 

 

Edited by InunoTaishou
1 person likes this

Share this post


Link to post
Share on other sites



Updated. Didn't realize that local paths for the hyperlink weren't being set correctly. This works with website URLs and local paths. Also severely shortened the Insert function and took out a lot of things that could cause errors, now there's only 3 possible @Error codes, and only one is an actual RichEdit error.

If anyone is ever looking for inserting an image into a RichEdit control (which I mentioned I was going to attempt to do), UEZ has pretty much done all the necessary code. I did change a couple of things to it to clean it up and will be adding the option to pass an $hBitmap or a file path but I see no point in re-releasing existing, working code, with small tweaks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • loganizzi
      By loganizzi
      If you look at the help file for the above command, you'll see that it states that it only works for certain zoom values (100 and 200 to 6400).   I assume that this is due to an issue in an MSDN library that the command relies on.
      After doing some investigating, I noticed that the GUIRichEdit.au3 library file contains the following code:
      ; #FUNCTION# ==================================================================================================================== ; Authors........: Chris Haslam (c.haslam) ; Modified ......: ; =============================================================================================================================== Func _GUICtrlRichEdit_SetZoom($hWnd, $iPercent) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, False) If Not __GCR_IsNumeric($iPercent, ">0") Then Return SetError(1021, 0, False) Local $iNumerator, $iDenominator Select Case Not ($iPercent = 100 Or ($iPercent >= 200 And $iPercent < 6400)) Return SetError(1022, 0, False) Case $iPercent >= 100 $iNumerator = 10000 $iDenominator = 10000 / ($iPercent / 100) Case Else $iNumerator = 10000 * ($iPercent / 100) $iDenominator = 10000 EndSelect Return _SendMessage($hWnd, $EM_SETZOOM, $iNumerator, $iDenominator) <> 0 EndFunc ;==>_GUICtrlRichEdit_SetZoom Which ensures that values are only within the bounds specified in the help file.    I found that if I comment out the portion of the code that limits the values, the function works fine for most (if not all) values.   I changed the code in the library file to this by simply commenting out the restricting lines of code:
      ; #FUNCTION# ==================================================================================================================== ; Authors........: Chris Haslam (c.haslam) ; Modified ......: ; =============================================================================================================================== Func _GUICtrlRichEdit_SetZoom($hWnd, $iPercent) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, False) If Not __GCR_IsNumeric($iPercent, ">0") Then Return SetError(1021, 0, False) Local $iNumerator, $iDenominator Select ; Case Not ($iPercent = 100 Or ($iPercent >= 200 And $iPercent < 6400)) ; Return SetError(1022, 0, False) Case $iPercent >= 100 $iNumerator = 10000 $iDenominator = 10000 / ($iPercent / 100) Case Else $iNumerator = 10000 * ($iPercent / 100) $iDenominator = 10000 EndSelect Return _SendMessage($hWnd, $EM_SETZOOM, $iNumerator, $iDenominator) <> 0 EndFunc ;==>_GUICtrlRichEdit_SetZoom  
      I assume whatever windows bug existed at the time this was created, no longer exists so there is no need to restrict the values.   
      Just wanted to point this out if anyone else is using this part of the library and required this functionality like I did.
       
    • AndreyS
      By AndreyS
      Tell me, please, how to set / change the cursor over RichEdit (created with _GUICtrlRichEdit_Create)?
    • StMaSi
      By StMaSi
      Two questions...
      When presenting a form containing a richedit control, is there any way to make the displayed text, within said richedit control, non-selectable?
      In addition, is there any way to hide the vertical line cursor, within said richedit control?
      Thanx.
    • TheSaint
      By TheSaint
      I've finally come up with some simple solutions for dragging & dropping a URL onto a control.
      There have been many requests here for this over the years.
      I do have an issue though, with my second code example solution as is mentioned here.
      The issue relates to working in Win 7 (and no doubt newer Windows).
      As I state there, failure is no doubt due to 'MSCOMCT2.OCX' missing from the System32 folder, at the very least.
      Not sure if it would be wise to just dump 'MSCOMCT2.OCX' from WinXP into the Win 7 System32 folder. I expect not.
      I imagine there is a better solution available in Win 7. Maybe a different OCX file, and perhaps a different Class of object etc.
      Any help would be greatly appreciated.
      Code is here (second example).
      EDIT
      Okay, I have rediscovered that 'MSCOMCT2.OCX' is a VB6 ActiveX control. So while I could dig up a copy and register it, that would probably not be helpful to everyone.
      And registering it didn't help. Possibly other dependencies are also needed?
      When running the script, it is clear going by the error reported, that Object is not being created.
    • AndreyS
      By AndreyS
      Please tell me, who knows how to apply and cancel styles in RTF?
      The following code does not work:
      #include <GuiRichEdit.au3> #include <WindowsConstants.au3> $hGUI = GUICreate("RichEdit Style", 500, 500, -1, -1) $hRichEdit = _GUICtrlRichEdit_Create($hGui, "Test", 20,40,460,400) GUISetState(@SW_SHOW, $hGUI) Sleep(3000) GUICtrlSetStyle($hRichEdit, $ES_RIGHT) Sleep(3000) GUICtrlSetStyle($hRichEdit, -1) Sleep(3000) Thanks!