Parse for web link in text string

Just starting out? Need help? Post your questions and find answers here.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Parse for web link in text string

Post by rsts »

Hard to believe this hasn't already been done, but maybe my search skills have failed me yet again.

I'm looking to recognize links in a text string and highlight them in an editor gadget to provide a user mechanism to launch them in a browser via ShellExecute_. I know that they're recognized in a web gadget but was looking for a way to recognize them in an editor.

Probably not a tremendous deal to write one, just wondering if it's already been done or if anyone knows of an API to accomplish it.

cheers
dell_jockey
Enthusiast
Enthusiast
Posts: 767
Joined: Sat Jan 24, 2004 6:56 pm

Post by dell_jockey »

rsts,

a couple of weeks ago I had a similar need (URL's & email addresses), but didn't implement it (and consequently got side-tracked...).
I did make some notes though, about implementing this using regular expressions to filter out an URL, as a regex would allow to refactor similar stuff done in Perl and other script languages that are used on the web. There is a regex lib available for PB somewhere, just search the forum.
cheers,
dell_jockey
________
http://blog.forex-trading-ideas.com
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Re: Parse for web link in text string

Post by gnozal »

rsts wrote:Hard to believe this hasn't already been done, but maybe my search skills have failed me yet again.

I'm looking to recognize links in a text string and highlight them in an editor gadget to provide a user mechanism to launch them in a browser via ShellExecute_. I know that they're recognized in a web gadget but was looking for a way to recognize them in an editor.

Probably not a tremendous deal to write one, just wondering if it's already been done or if anyone knows of an API to accomplish it.
I have no experience with an EditorGadget (RichEdit) but it works well with the Scintilla control (see jaPBe V3 sources).
I 'simply' detect the 'http://...' string in the editor text during the syntax coloring process and then I set a special 'URL' style with the 'HotSpot' property. When the user clicks on the hotspot, scintilla generates a special event so I can start the browser.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Something with #CFM_LINK (=$00000020) and #ENM_LINK (=$04000000)?
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Trond wrote:Something with #CFM_LINK (=$00000020) and #ENM_LINK (=$04000000)?
That's worth investigating. Thanks. :)

Have you used it, by any chance?

cheers
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

Try this:

Code: Select all

#ENM_LINK = $04000000
#CFM_LINK = $00000020
#EN_LINK  = 1803

Procedure Callback(Window, Message, wParam, lParam)

  ; WM_NOTIFY can only be caught in the callback, not in the main loop
  ;
  If Message = #WM_NOTIFY
    *hdr.NMHDR = lParam    
   
    ; ensure it is the right message and gadget
    ;     
    If *hdr\hwndFrom = GadgetID(0) And *hdr\code = #EN_LINK
      *link.ENLINK = lParam
    
      ; react only to the button release part.
      ;
      If *link\msg = #WM_LBUTTONUP
      
        ; Show also the range of text that was clicked
        ;
        MessageRequester("", "click! (" + Str(*link\chrg\cpMin) + ", " + Str(*link\chrg\cpMax) + ")")
      EndIf
      
    EndIf    
  EndIf

  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 400, 400, "Links", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  CreateGadgetList(WindowID(0))
  SetWindowCallback(@Callback())  
  EditorGadget(0, 10, 10, 380, 380)
    
  ; Enable the link message
  SendMessage_(GadgetID(0), #EM_SETEVENTMASK, 0, #ENM_LINK)
  
  ; This enables autodetect of url text
  ; must be before the SetGadgettext.
  SendMessage_(GadgetID(0), #EM_AUTOURLDETECT, #True, 0)
  
  SetGadgetText(0, "There is a link in here." + Chr(13) + "http://www.purebasic.com/")
  
  ; To manually set a text as an url, select it and use the charformat message:    
  format.CHARFORMAT2\cbSize = SizeOf(CHARFORMAT2)
  format\dwMask = #CFM_LINK
  format\dwEffects = #CFM_LINK
  SendMessage_(GadgetID(0), #EM_SETSEL, 11, 15)  
  SendMessage_(GadgetID(0), #EM_SETCHARFORMAT, #SCF_SELECTION, @format)
  
  ; deselect the text
  SendMessage_(GadgetID(0), #EM_SETSEL, 0, 0)

  Repeat
  Until WaitWindowEvent() = #PB_Event_CloseWindow  
EndIf
quidquid Latine dictum sit altum videtur
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Dammit, beaten to the punch!

Code: Select all

Procedure CallBack(hwnd, msg, wparam, lparam) 
  result = #PB_ProcessPureBasicEvents 
  If msg = #WM_NOTIFY 
    *nc.ENLINK = lparam 
    If *nc\nmhdr\code = 1803 ; en_link 
      If *nc\wparam ; 1 indicates click event
        SendMessage_(*nc\nmhdr\hwndfrom, #EM_EXSETSEL, 0,*nc\chrg) 
        buf.s = Space(#MAX_PATH) 
        SendMessage_(*nc\nmhdr\hwndfrom, #EM_GETSELTEXT,0,@buf) 
        RunProgram(buf) 
      EndIf 
    EndIf 
  EndIf 
  ProcedureReturn result 
EndProcedure  

OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
SetWindowCallback(@CallBack()) 
eg=EditorGadget(0,0,0,640,480) 

SendMessage_(eg,#EM_SETEVENTMASK,0,$04000000) ; enm_link 
SendMessage_(GadgetID(0), #EM_AUTOURLDETECT, 1, 0) 

AddGadgetItem(0,-1, "Hello rsts, how are you today? ") 
AddGadgetItem(0, -1, "Would you like To visit http://www.lloydsplace.com on this fine day?") 
AddGadgetItem(0, -1, "There are certainly more boring things to do!") 
Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow
Last edited by netmaestro on Wed Jun 25, 2014 5:27 am, edited 2 times in total.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

netmaestro wrote:Dammit, beaten to the punch!
:)

I was beaten as well - by about 2 minutes!

Must be getting slow in my old age! 8)
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Well, post yours anyway, it's probably better than mine.
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Old age? Hmmm - maybe that's why I'm "slow"?

Thanks guys, let me see what I can make out of these.

cheers
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

haha, i win! whats the price? :)
quidquid Latine dictum sit altum videtur
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I'll donate a slice of pizza and send it out right away parcel post. It should arrive in about 2-3 weeks. Congratulations!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I'm still waiting for the loose women that fangbeast promised!

I'll donate one of those as a prize if you like? :)

@netmaestro: unable to post as I deleted it on seeing that Freak's did everything that mine did - and more. All mine did was intercept a link click in an editor gadget and redirect a web gadget accordingly. Nothing fancy.
I may look like a mule, but I'm not a complete ass.
User avatar
ar-s
Enthusiast
Enthusiast
Posts: 344
Joined: Sat Oct 06, 2007 11:20 pm
Location: France

Post by ar-s »

netmaestro wrote:Dammit, beaten to the punch!

Code: Select all

Procedure CallBack(hwnd, msg, wparam, lparam) 
  result = #PB_ProcessPureBasicEvents 
  If msg = #WM_NOTIFY 
    *nc.ENLINK = lparam 
    If *nc\nmhdr\code = 1803 ; en_link 
      If *nc\wparam ; 1 indicates click event
        SendMessage_(*nc\nmhdr\hwndfrom, #EM_EXSETSEL, 0,*nc\chrg) 
        buf.s = Space(#MAX_PATH) 
        SendMessage_(*nc\nmhdr\hwndfrom, #EM_GETSELTEXT,0,@buf) 
        RunProgram(buf) 
      EndIf 
    EndIf 
  EndIf 
  ProcedureReturn result 
EndProcedure  

OpenWindow(0,0,0,640,480,"",$cf0001) 
SetWindowCallback(@CallBack()) 
CreateGadgetList(WindowID(0)) 
eg=EditorGadget(0,0,0,640,480) 

SendMessage_(eg,#EM_SETEVENTMASK,0,$04000000) ; enm_link 
SendMessage_(GadgetID(0), #EM_AUTOURLDETECT, 1, 0) 

AddGadgetItem(0,-1, "Hello rsts, how are you today? ") 
AddGadgetItem(0, -1, "Would you like To visit http://www.networkmaestro.com on this fine day?") 
AddGadgetItem(0, -1, "There are certainly more boring things to do!") 
Repeat: Until WaitWindowEvent() = #WM_CLOSE
(another) Great code ! :D

When a link has been clicked in the editorgadget, how could we open it in a webgadget from the same program ?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Add a webgadget to the code and replace the RunProgram() with a SetGadgetText() directed at the webgadget.
I may look like a mule, but I'm not a complete ass.
Post Reply