WebGadget: Directly insert code and catch link clicks.

Share your advanced PureBasic knowledge/code with the community.
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

Thanks for taking the effort to make this work in PB. :)

Unfortunately it chrashes every time I click one of the links in the sample code. :?

I'm using XP Home/SP2, PB 3.93.
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

Ehhrmm, Am I the only one that experience problems with this code?? Does it work as advertised for the rest of you ?? :?:
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

I just installed 3.94 and the problems went away. It works perfectly !! Thanks for the code, Freak!! :)
Brice Manuel

Post by Brice Manuel »

I am using 3.94.1 with no issues, but I am just using it to write to the web gadget.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Num3 wrote: I seem to have some troubles...

This code doesn't work with mozilla firefox activeX :shock:
Freak wrote: i have posted a lot of code to interface with the Document Object Model of IE or the WebGadget.
:)

Anyways, that write command is excellent for users creating a chat/im proggie using the webgadget.
Ramihyn
New User
New User
Posts: 1
Joined: Fri Oct 21, 2005 11:24 am
Location: Germany

Post by Ramihyn »

Nice code - thanks a lot. That saved me quite some time :)

I did a quick hack using this code and the fixed "GetURLParts.pb" routines from the PureArea.net Codearchive to do a "Client" for a browser-based game called Planetarion. It opens a window with only a resizeable webarea, connects to www.planetarion.com and runs all clicked URLs through the "LinkCallBack" procedure where they are rewritten (in this case they get an additional "machineID" appended as parameter).

Since this is probably something of use for others too and at the very least it is a easy sample of how to use the WebGadgetsExtras routines:

the source code of my little hack is here:
http://www.reconstructor.com/paclient/paclient.pb
http://www.reconstructor.com/paclient/p ... nstants.pb
http://www.reconstructor.com/paclient/p ... Windows.pb
http://www.reconstructor.com/paclient/W ... tExtras.pb

The compiled client is here:
http://www.reconstructor.com/paclient/paclient.zip

Remove the PVDynamic_ calls if you dont have the PureVisionXP Gadgets library.

I had to add some code to the webgadgets routine "IDispatch_Invoke" so it delivers the Link the user clicked and not the resource link of the object firing the event (like a "img" resource or a "strong" tag inside a "<a href>" tag). Thats why i added the the following lines to get the parent tag in case the Element isnt a "a" tag:

Code: Select all

If Element\get_tagName(@bstr_tagName) = #S_OK
          length = WideCharToMultiByte_(#CP_ACP, 0, bstr_tagName, -1, 0, 0, 0, 0)
          tagName$ = Space(length)
          WideCharToMultiByte_(#CP_ACP, 0, bstr_tagName, -1, @tagName$, length, 0, 0)
          SysFreeString_(bstr_tagName)

          If (LCase(tagName$) <> "a")
            Element\get_parentElement(@Element.IHTMLElement)

            If Element\get_tagName(@bstr_tagName) = #S_OK
              length = WideCharToMultiByte_(#CP_ACP, 0, bstr_tagName, -1, 0, 0, 0, 0)
              tagName$ = Space(length)
              WideCharToMultiByte_(#CP_ACP, 0, bstr_tagName, -1, @tagName$, length, 0, 0)
              SysFreeString_(bstr_tagName)
            EndIf
          EndIf
        EndIf
Children beware - its dirty code not checking if "Element\get_parentElement()" actually succeeded :) Also it implies that only the "a" tag leads to a external resource plus that the parent of any other tag actually is the "a" tag. Since this was done as "proof of concept" and works for the given site, it was good enough for me :)

I used the OLE/COM Object viewer and the ITypeLib Viewer from Visual Studio to understand the interfacing code.

Hope this sample helps :)

ps: i forgot that i also changed the Procedure WebGadget_IsLoaded(Gadget) to return the status code instead of a 0 or 1 as i used the status code during my debugging because at first the "IsLoaded()" never showed a 1 :(
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Replace this code

Code: Select all

          If (LCase(tagName$) <> "a")
            Element\get_parentElement(@Element.IHTMLElement)

            If Element\get_tagName(@bstr_tagName) = #S_OK
              length = WideCharToMultiByte_(#CP_ACP, 0, bstr_tagName, -1, 0, 0, 0, 0)
              tagName$ = Space(length)
              WideCharToMultiByte_(#CP_ACP, 0, bstr_tagName, -1, @tagName$, length, 0, 0)
              SysFreeString_(bstr_tagName)
            EndIf
          EndIf
With the following code

Code: Select all

          While (LCase(tagName$) <> "a")
           If Element\get_parentElement(@Element.IHTMLElement) = #S_OK
             If Element\get_tagName(@bstr_tagName) = #S_OK
               length = WideCharToMultiByte_(#CP_ACP, 0, bstr_tagName, -1, 0, 0, 0, 0)
               tagName$ = Space(length)
               WideCharToMultiByte_(#CP_ACP, 0, bstr_tagName, -1, @tagName$, length, 0, 0)
               SysFreeString_(bstr_tagName)
             Else
              Break
             EndIf
           Else
            Break
           EndIf
          Wend
And it should (at least it does here) iterate upwards until it finds a anchor or it fails to get a parent any more.
I'm not sure if this is the correct method to do it, but it seems to work.
It handles "A" tags just like normaly, it handles nested tags lik a IMG inside A,
or messy ones like a IMG inside B inside A tags etc.
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Some more usefull code, this adds a new procedure/function.

Code: Select all

Enumeration 1 
  #OLECMDID_OPEN 
  #OLECMDID_NEW 
  #OLECMDID_SAVE 
  #OLECMDID_SAVEAS 
  #OLECMDID_SAVECOPYAS 
  #OLECMDID_PRINT 
  #OLECMDID_PRINTPREVIEW 
  #OLECMDID_PAGESETUP 
  #OLECMDID_SPELL 
  #OLECMDID_PROPERTIES 
  #OLECMDID_CUT 
  #OLECMDID_COPY 
  #OLECMDID_PASTE 
  #OLECMDID_PASTESPECIAL 
  #OLECMDID_UNDO 
  #OLECMDID_REDO 
  #OLECMDID_SELECTALL 
  #OLECMDID_CLEARSELECTION 
  #OLECMDID_ZOOM 
  #OLECMDID_GETZOOMRANGE 
  #OLECMDID_UPDATECOMMANDS 
  #OLECMDID_REFRESH 
  #OLECMDID_STOP 
  #OLECMDID_HIDETOOLBARS 
  #OLECMDID_SETPROGRESSMAX 
  #OLECMDID_SETPROGRESSPOS 
  #OLECMDID_SETPROGRESSTEXT 
  #OLECMDID_SETTITLE 
  #OLECMDID_SETDOWNLOADSTATE 
  #OLECMDID_STOPDOWNLOAD 
EndEnumeration 

Enumeration 0 
  #OLECMDEXECOPT_DODEFAULT 
  #OLECMDEXECOPT_PROMPTUSER 
  #OLECMDEXECOPT_DONTPROMPTUSER 
  #OLECMDEXECOPT_SHOWHELP 
EndEnumeration 

;Note! Not all the constants above work as some require
;a VARIANT structure and a bit more to work properly.
;However, for "fire and forget" commands this procedure works great though!
Procedure WebGadget_Exec(Gadget,command,option)
 Browser.IWebBrowser2 = GetWindowLong_(GadgetID(Gadget), #GWL_USERDATA)
 If Browser
  If Browser\ExecWB(command, option, 0, 0) = #S_OK
   ProcedureReturn 1
  EndIf
 EndIf
ProcedureReturn 0
EndProcedure
As an example, imagine the user press a link/image link to print the current page,
you catch the url/link, and do the following:

WebGadget_Exec(#WebGadget,#OLECMDID_PRINTPREVIEW,#OLECMDEXECOPT_DODEFAULT)
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

How do one get the contents of a form the user click submit or press enter in?

If someone could figure that out, then that along with the code previously in this thread should be enough to do application interfaces using webgadget and html, ala QHTM and similar solutions.
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

I think the contents are appended to the end of the nav url if yor post method is 'get' instead of 'post'.
If so Freaks code is all you need. I'm not at all shure about this, but I'll check it out.

Code: Select all

S=S+"<html><head><meta http-equiv='MSThemeCompatible' content='yes'></head>"+Lf
	 S=S+"<body scroll=auto link=blue vlink=blue alink=green>"+Lf 
   S=S+"<form method='post' action=submit>"+Lf+Lf
b1be
User
User
Posts: 25
Joined: Sat Mar 19, 2005 5:47 pm

Post by b1be »

aaaaaaa... back on topic ... how can i make this code to work on more than one webgadget? ...

Edit:
My problem lies here

Code: Select all

->Shared<- WebGadget_Document.IHTMLDocument2_FIXED
on Webgadget_Open/Write/Close Procedures

i tried Unsucessfully with LinkedLists .. (and that's kind'a what i need)

2nd problem .. not loading the page ...
Calling that later on main loop seems to solve the problem ... dont know why

Code: Select all

SetGadgetText(Window()\WebGadget,WebPath$+"Logs/"+Window()\FileName$)
Thanks ..
Last edited by b1be on Wed Nov 02, 2005 4:02 pm, edited 1 time in total.
Nik
Addict
Addict
Posts: 1017
Joined: Fri May 13, 2005 11:45 pm
Location: Germany
Contact:

Post by Nik »

Ok i found a problem with the catch Links function. If I close the window containing the webgadget and reopen it IE sometimes doesn't open a Webgadget but trys to download the page which should be shown in the webgadget. If you want I can send you an example code but it's 250 lines of code.(contact me on PM)

bye Nik
yabune
User
User
Posts: 65
Joined: Mon Aug 22, 2005 2:31 pm

Post by yabune »

Freak, is there a way to use your code but with an html file already written?
I mean, doesn't have to write every line of the html.. Just load the file.

I tried to open the file and write each line with your functions, but the css isn't rendered..

I did this:

Code: Select all

  If WebGadget_Open(#WebGadget, 0)
    If PureFILE_ReadTextFile(#PB_Any, "page.html")
      While PureFILE_NotEof()
        WebGadget_Write(PureFILE_ReadString())
      Wend
      PureFILE_CloseFile()
    EndIf
    WebGadget_Close() 
  EndIf
  WebGadget_CatchLinks(#WebGadget, @LinkCallback())
I also tried to code this:

Code: Select all

WebGadget(#WebGadget,20,20,400,300,"page.html")
WebGadget_CatchLinks(#WebGadget, @LinkCallback())
but nothing shows up in the webgadget.

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

Post by freak »

To use this with real files, you have to check with the WebGadget_IsLoaded() in a loop until it returns 1,
before you set the links callback.
quidquid Latine dictum sit altum videtur
yabune
User
User
Posts: 65
Joined: Mon Aug 22, 2005 2:31 pm

Post by yabune »

freak wrote:To use this with real files, you have to check with the WebGadget_IsLoaded() in a loop until it returns 1,
before you set the links callback.
Can you give me an example?

I tried this but it didn't work (stays forever in the loop):

Code: Select all

WebGadget(#WebGadget,20,20,400,300,"page.html")
Repeat
Until WebGadget_IsLoaded(#WebGadget)
WebGadget_CatchLinks(#WebGadget, @LinkCallback())
Thanks!
Post Reply