Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Hyperlinks in ChatBox (no Hyperlink.ocx)
#1
Hyperlinks


Info
Tutorial: BrandiniMP
Difficulty: 2/5 (C&P)


Description
you can create URLs in the chat box and click them to open default browser

tested with Elysium Debugged

[Image: hyperexuj1.png]

1. make a new module and put the below text into it (or ad it to an existing module)

Code:
Option Explicit

Private Type NMHDR
    hWndFrom As Long
    idFrom As Long
    code As Long
End Type

Private Type CHARRANGE
    cpMin As Long
    cpMax As Long
End Type

Private Type ENLINK
    hdr As NMHDR
    msg As Long
    wParam As Long
    lParam As Long
    chrg As CHARRANGE
End Type

Private Type TEXTRANGE
    chrg As CHARRANGE
    lpstrText As String
End Type

'Used to change the window procedure which kick-starts the subclassing
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" ( _
ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long

'Used to call the default window procedure for the parent
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( _
ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, _
ByVal msg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long

'Used to set and retrieve various information
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long

'Used to copy... memory... from pointers
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
Destination As Any, _
Source As Any, _
ByVal Length As Long)

'Used to launch the URL in the user's default browser
Private Declare Function ShellExecute Lib "shell32" Alias "ShellExecuteA" ( _
ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long

Const WM_NOTIFY = &H4E
Const EM_SETEVENTMASK = &H445
Const EM_GETEVENTMASK = &H43B
Const EM_GETTEXTRANGE = &H44B
Const EM_AUTOURLDETECT = &H45B
Const EN_LINK = &H70B

Const WM_LBUTTONDBLCLK = &H203
Const WM_LBUTTONDOWN = &H201
Const WM_LBUTTONUP = &H202
Const WM_MOUSEMOVE = &H200
Const WM_RBUTTONDBLCLK = &H206
Const WM_RBUTTONDOWN = &H204
Const WM_RBUTTONUP = &H205
Const WM_SETCURSOR = &H20

Const CFE_LINK = &H20
Const ENM_LINK = &H4000000
Const GWL_WNDPROC = (-4)
Const SW_SHOW = 5

Dim lOldProc As Long 'Old windowproc
Dim hWndRTB As Long 'hWnd of RTB
Dim hWndParent As Long 'hWnd of parent window


Public Sub DisableURLDetect()

'Don't want to unsubclass a non-subclassed window

    If lOldProc Then
        'Stop URL detection
        SendMessage hWndRTB, EM_AUTOURLDETECT, 0, ByVal 0
        'Reset the window procedure (stop the subclassing)
        SetWindowLong hWndParent, GWL_WNDPROC, lOldProc
        'Set this to 0 so we can subclass again in future
        lOldProc = 0
    End If

End Sub

Public Sub EnableURLDetect(ByVal hWndTextbox As Long, _
                           ByVal hWndOwner As Long)

'Don't want to subclass twice!

    If lOldProc = 0 Then
        'Subclass!
        lOldProc = SetWindowLong(hWndOwner, GWL_WNDPROC, AddressOf WndProc)
        'Tell the RTB to inform us when stuff happens to URLs
        SendMessage hWndTextbox, EM_SETEVENTMASK, 0, ByVal ENM_LINK Or SendMessage(hWndTextbox, EM_GETEVENTMASK, 0, 0)
        'Tell the RTB to start automatically detecting URLs
        SendMessage hWndTextbox, EM_AUTOURLDETECT, 1, ByVal 0
        hWndParent = hWndOwner
        hWndRTB = hWndTextbox
    End If

End Sub

Public Function IsDebug() As Boolean

    On Error GoTo ErrorHandler
    Debug.Print 1 / 0
    IsDebug = False

Exit Function

ErrorHandler:
    IsDebug = True

End Function

Public Function WndProc(ByVal hwnd As Long, _
                        ByVal uMsg As Long, _
                        ByVal wParam As Long, _
                        ByVal lParam As Long) As Long

Dim uHead As NMHDR
Dim eLink As ENLINK
Dim eText As TEXTRANGE
Dim sText As String
Dim lLen  As Long

    'Which message?
    Select Case uMsg
    Case WM_NOTIFY
        'Ooo! A notify message! Something exciting must be happening...
        'Copy the notification header into our structure from the pointer
        CopyMemory uHead, ByVal lParam, Len(uHead)
        'Peek inside the structure
        If uHead.hWndFrom = hWndRTB Then
            If uHead.code = EN_LINK Then
                'Yay! Some kind of kinky linky message.
                'Now that we know its a link message, we can copy the whole ENLINK structure
                'into our structure
                CopyMemory eLink, ByVal lParam, Len(eLink)
                'What kind of message?
                Select Case eLink.msg
                Case WM_LBUTTONUP
                    'Clicked the link!
                    'Set up out TEXTRANGE struct
                    With eText
                        .chrg.cpMin = eLink.chrg.cpMin
                        .chrg.cpMax = eLink.chrg.cpMax
                        .lpstrText = Space$(1024)
                        'Tell the RTB to fill out our TEXTRANGE with the text
                    End With 'eText
                    lLen = SendMessage(hWndRTB, EM_GETTEXTRANGE, 0, eText)
                    'Trim the text
                    sText = Left$(eText.lpstrText, lLen)
                    'Launch the browser
                    ShellExecute hWndParent, vbNullString, sText, vbNullString, vbNullString, SW_SHOW
                    'Other miscellaneous messages
                Case WM_LBUTTONDOWN
                Case WM_LBUTTONDBLCLK
                Case WM_RBUTTONDBLCLK
                Case WM_RBUTTONDOWN
                Case WM_RBUTTONUP
                Case WM_SETCURSOR
                End Select
            End If
        End If
    End Select
    sText = vbNullChar
    'Call the stored window procedure to let it handle all the messages
    WndProc = CallWindowProc(lOldProc, hwnd, uMsg, wParam, lParam)

End Function




2. goto frmmirage and on form_load add

Code:
If IsDebug = False Then
    EnableURLDetect txtChat.hWnd, Me.hWnd
End If


3. now goto form_unload and add

Code:
If IsDebug = False Then
    DisableURLDetect
End If

and thats it.

Notes
this will not work when running in VB6, you need to compile it first, because if enable hyperlinks in vb6 it likes to close VB6 down, that is why there is the "IsDebug" part, to make sure you arent in VB6, otherwise it works great.

Side effects

Will not disply links in VB6 IDE (when you click Run).
Reply
#2
oooh indented code, big whoop, if its that important il do it then
Reply
#3
Whats next? You want him to make comments explaining what each word does? Have him color each letter in a different shade to provide users with a color code to help them follow each line as it comes. LOL. Its a fricken code, Quit your bitching
Reply
#4
lol uarepoo2... you obviously don't know your place in the community..
Reply
#5
I agree 100% with Dave. Nesting is important, otherwise some people will get lost and most won't bother to look at it. Just noobs, like pooface over there will.

Also, it helps when troubleshooting your code. If you're source is riddled with code like this, you fail.
Reply
#6
my code is indented and ordered perfectly, its easily readable, this is an old tutorial by me, i just didnt bother to indent it, and the unneeded "case"'s are there to give people more options, and i use them myself, i pretty much ripped this from my old code.
Reply
#7
I'll mess with it if I have time this weekend. I'll throw a tutorial up if it's successful.

--edit
I just read the part bout not running in the vb6 ide, so im thinkin that i wont be messing with it. don ask why im just lazy Tongue
Reply
#8
i know this post is a little late, but i havent been round MS much, after reading your posts ive started working on a better hyperlink tut for yall, using a diff method Big Grin
Reply
#9
This would be easier for fools to easily be scammed by those cons.
Reply
#10
I made a few changes and got it to run in the ide fine.

First remove the following:

Code:
Public Function IsDebug() As Boolean

    On Error GoTo ErrorHandler
    Debug.Print 1 / 0
    IsDebug = False

Exit Function

ErrorHandler:
    IsDebug = True

End Function

On the form_load in frmmirage you just need:
Code:
EnableURLDetect txtChat.hWnd, Me.hWnd

In modGameLogic - GameDestory add before the End
Code:
DisableURLDetect

This worked for me, dunno if it will work for anyone else.

*Edit*
If you use the Stop button in the IDE it will probably still crash out. Make sure to quit from the game to stop debugging.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)