WebGadget: Directly insert code and catch link clicks.

Share your advanced PureBasic knowledge/code with the community.
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

WebGadget: Directly insert code and catch link clicks.

Post by freak »

As some of you may have followed the thread here viewtopic.php?t=16737 ,
i have posted a lot of code to interface with the Document Object Model of IE or the WebGadget.

Since such things (catching links and writing code to it) have been
requested for quite a while, i decided to put it into some simple functions
for easy usage. As you can see from the example below, there is no
knowledge of COM or Interfaces needed.
If you want to do more specific things than these functions allow, i suggest
you have a close look on the above mentioned thread. It has examples
of how to get individual html elements and setting up various event callbacks.

Its all one includefile. You can get it here:
http://freak.purearea.net/code/WebGadgetExtras.pb

Procedure description:

WebGadget_IsLoaded(#Gadget)
Returns 1 if the page has finished loading and 0 if not. This must be
checked before setting up the links callback. (as it requires the page to be fully loaded)
This is only needed if the page is loaded from a file or from the web.
(not needed the code is directly written with the procedures below)

WebGadget_CatchLinks(#Gadget, @Callback())
This sets up a callback that will receive all link clicks in this page.
It must be called when the page is fully loaded. The link callback is set
for the currently present links only. If the page is reloaded, or the contents
are changed (new page), you have to call this again!
Currently the page may not contain frames for this to work.
The callback must look like this:

Code: Select all

Procedure LinkCallback(Gadget, Link$, Text$, ID$, Class$)

  ProcedureReturn 0
EndProcedure
Gadget : Gadget number of the WebGadget
Link$ : receives the target set by the "href" attribute.
Text$ : receives the displayed text.
ID$ : receives the ID attribute of the link.
Class$ : receives the classname for the link.

If you return 0 from the callback, the link will not be executed. If you return
a non-zero value, then the link will be executed. (the target file will be loaded.)

WebGadget_Open(#Gadget, AddHistory)
Opens the WebGadget to write new code into it. Set AddHistory to non-zero
if you want the new page to be a new entry in the history. Set it to 0
if the new content should just replace the old page.

WebGadget_Write(String$)
Writes the given string into a previously opened WebGadget.

WebGadget_Close()
Completes the writing of new code into the WebGadget.


Ok, finally a short example for the usage. Its really quite simple:

Code: Select all

XIncludeFile "WebGadgetExtras.pb"

#WebGadget = 0

Procedure LinkCallback(Gadget, Link$, Text$, ID$, Class$)

  Debug "Link: "+Link$
  Debug "Text: "+Text$
  Debug ""

  ProcedureReturn 0 ; prevent link from executing
EndProcedure

If OpenWindow(0, 0, 0, 800, 600, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "WebGadget example")
  If CreateGadgetList(WindowID())
    
    WebGadget(#WebGadget, 0, 0, 800, 600, "")    
            
    If WebGadget_Open(#WebGadget, 0)
    
      WebGadget_Write("<html><body><center><br>")
      WebGadget_Write("<a href="+Chr(34)+"http://www.purebasic.com"+Chr(34)+">PureBasic.com</a><br>")
      WebGadget_Write("<a href="+Chr(34)+"http://forums.purebasic.com"+Chr(34)+">Forum</a><br>")      
      WebGadget_Write("</center></body></html>")
    
      WebGadget_Close()
    EndIf
    
    WebGadget_CatchLinks(#WebGadget, @LinkCallback())            
    
    Repeat
    Until WaitWindowEvent() = #PB_Event_CloseWindow    
    
  EndIf
EndIf
Comments and Questions are welcome...
Last edited by freak on Thu Oct 19, 2006 11:57 pm, edited 1 time in total.
quidquid Latine dictum sit altum videtur
Brice Manuel

Post by Brice Manuel »

This is EXACTLY what I needed for a project I am working on.

Thank you :D
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Post by ricardo »

Great! You are a genious and a very nice guy! :)
ARGENTINA WORLD CHAMPION
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Ace!

Edit:

Thank you, thank you, thank you!
@}--`--,-- A rose by any other name ..
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Hi, a question.

How should browsing be handled?

I'm doing this:

Code: Select all

Global flg

Procedure LinkCallback(Gadget, Link$, Text$, ID$, Class$)
  Debug "Link="+Link$+", Text="+Text$+", ID="+ID$+", class="+Class$
  SetGadgetText(Gadget,Link$)
  flg=0
  ProcedureReturn 0 ; prevent link from executing
EndProcedure
and

Code: Select all

...
    WebGadget_CatchLinks(#WebGadget, @LinkCallback())
    flg=1

    Repeat
      If WebGadget_IsLoaded(#WebGadget)<>0 And flg=0
        flg=1
        WebGadget_CatchLinks(#WebGadget, @LinkCallback())           
      EndIf
    Until WaitWindowEvent() = #PB_Event_CloseWindow

I can use this to browse the forums, but it will not browse the purebasic site: Obviously I have not understood how to use it. :?


PS: Also a right-click and open in new window does not get caught, so the page escapes from the PB browser and flees into IE.


Thanks again Freak. :)
@}--`--,-- A rose by any other name ..
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Very useful.

Many thanks for sharing this.
Blade
Enthusiast
Enthusiast
Posts: 362
Joined: Wed Aug 06, 2003 2:49 pm
Location: Venice - Italy, Japan when possible.
Contact:

Post by Blade »

It's just me?
[ERROR] Invalis memory access
(line 489)
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

Thank you very much :D
Maybe these functions (and others :twisted: ) will be standard Purebasic functions in the future ?
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Made sticky because this is a major tip. :)

Web functions are a big part of today's applications and this tip is a good way
to start learning about interacting with web-based projects. Thanks, Freak!
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

Freak for president!!! :lol:
Nik
Addict
Addict
Posts: 1017
Joined: Fri May 13, 2005 11:45 pm
Location: Germany
Contact:

Post by Nik »

Genious
thanks a lot 8)
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Great Code!!! :shock:
--Kale

Image
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

How can I get the html source thats been loaded?
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Post by Num3 »

I seem to have some troubles...

This code doesn't work with mozilla firefox activeX :shock:
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Post by ricardo »

dracflamloc wrote:How can I get the html source thats been loaded?

Code: Select all

If Document2\get_body(@Body.IHTMLElement) = #S_OK 
    Body\get_innerHTML(@bstr_code) = #S_OK  
    Html$ = ReadBSTR(bstr_code) ;Html$ stores the code
    SysFreeString_(bstr_body)
EndIf
You can try with get_outerHTML and should work okay too.

Remember you may need to set the string size bigger or maybe best store it into a memory to avoid crashes if its bigger than 64 k.
ARGENTINA WORLD CHAMPION
Post Reply