Skip to main content

Develop a web browser in PowerBuilder.

The inclusion of the new Chromium Web Browser control in PowerBuilder 2019R2 gave us the possibility to develop our own web browser in PowerBuilder. We could have done this already with the MS Web Browser control but we would have had to accept the limitation of IE. With the new PowerBuilder control, we know that we'll have maximum compatibility with the most up to date web sites. Microsoft even accepts this after converting Edge to use Chromium. 

So the big question, why? The short answer to that is... to learn something new. I've been developing software for 20 years. In those years I've developed countless of useless applications just for the sake of learning (I once developed a fully functional version of Mine Sweeper in Silverlight).

Below is what we'll create. We'll use the PB Chromium Web Browser control with the Ultimate Suite for PowerBuilder Tabbed Caption window.



Some things we'll accept right away; 1) This browser is extremely basic so we won't have all the great features of the big players. 2) All our pages are single threaded so if one page crashes, our whole app crashes. 3) No dev tools.

Sounds pretty compelling so far, doesn't it? What we will learn is how simple it is to use the new Web Browser control and we'll learn how to get an image from the web (the favicon that we see in the tabs).

To get started create a new application and add the Ultimate Suite PBD's or PBL's (if you have) to your library list.

advguibase.pbd
advguicontrols.pbd
advguiobjects.pbd
advguicharts.pbd
advguithemes.pbd

Inherit a new main window from w_pbus_spa_tab. This will be our main browser window.

Create a new user objected called u_cst_web. This will have all our web browser related controls on it. Add buttons for back, forward, and refresh. Add an input to allow users to enter a URL. Add the PB Web Browser controls to display the entered URL. Add code to your resize event to make everything size properly.

The buttons we added will contain very little code. All we'll do is call the appropriate web browser function:

Back: wb_1.GoBack()
Forward: wb_1.GoForward()
Refresh: wb_1.Refresh()
Stop: wb_1.StopNavigation()
Navigate: wb_1.Navigate("https://www.powertothebuilder.com")

Back to our main window; In the AddTabButtonClicked event, we will open a new browser window.

u_cst_web l_web
of_OpenTab(l_web,  "New Tab", "newtab.png")

When we navigate to a URL, we want to get the favicon for the site and display it in our browser tab. Review the following code for an example of how we can do this by using a service provided by Google:

Integer li_rc, li_StatusCode
String ls_ContentType, ls_body, ls_string
String ls_file
Blob lblb_blob
HttpClient lnv_HttpClient
lnv_HttpClient = CREATE HttpClient

// Send request using GET method
li_rc = lnv_HttpClient.SendRequest("GET","https://www.google.com/s2/favicons?domain=" + as_url)

// Obtain the response message
IF li_rc = 1 THEN
    // Obtain the response status
    li_StatusCode = lnv_HttpClient.GetResponseStatusCode()
    IF li_StatusCode = 200 THEN
        // Obtain the header
        ls_ContentType = lnv_HttpClient.GetResponseHeader("Content-Type")

        // Obtain the response data
        lnv_HttpClient.GetResponseBody(lblb_blob)
  
        Long ll_file, ll_FileLen, ll_Loops, ll_Step

        n_cst_pbus_string lnv_string
        ls_file = lnv_string.of_GlobalReplace(as_url, "/", "_")
        ls_file = lnv_string.of_GlobalReplace(ls_file, ".", "_")
        ls_file = lnv_string.of_GlobalReplace(ls_file, "?", "_")
        ls_file = lnv_string.of_GlobalReplace(ls_file, "&", "_")
        ls_file = lnv_string.of_GlobalReplace(ls_file, "=", "_")
        ls_file = lnv_string.of_GlobalReplace(ls_file, "\", "_")
        ls_file = lnv_string.of_GlobalReplace(ls_file, ":", "_")
        ls_file = lnv_string.of_GlobalReplace(ls_file, "%", "_")
  
        ls_ContentType = Lower(ls_ContentType)
  
        IF Pos(ls_ContentType, "png", 1) > 0 THEN
    ls_file = ls_file + ".png"
        ELSEIF Pos(ls_ContentType, "jpg", 1) > 0 OR Pos(ls_ContentType, "jepg", 1) > 0 THEN
            ls_file = ls_file + ".jpg"
        ELSEIF Pos(ls_ContentType, "ico", 1) > 0 THEN
    ls_file = ls_file + ".ico"
        END IF

        ls_file = "C:\Users\your user id\Documents\" + ls_file

        ll_file = FileOpen(ls_file, StreamMode!, Write!, LockWrite!, Append!)
  
        IF ll_file > 0 THEN
            // Determine how many times to call FileWrite
            ll_FileLen = Len(lblb_blob)
            IF ll_FileLen > 32765 THEN
                IF Mod(ll_FileLen, 32765) = 0 THEN
                    ll_Loops = ll_FileLen/32765
                ELSE
                    ll_Loops = (ll_FileLen/32765) + 1
                END IF
            ELSE
                ll_Loops = 1
            END IF

            FOR ll_Step = 1 To ll_Loops
                FileWrite(ll_file,BlobMid(lblb_blob,((ll_Step - 1)*32765) + 1, 32765))
            NEXT
        ELSE
            //log the error, or handle
        END IF
        
        FileClose(ll_file)
  
    END IF
END IF

DESTROY lnv_HttpClient

RETURN ls_file

ls_file will return a file name that we can use in the main tab. We change the image on the main windows tab by calling the of_SetImage function. We can do all this in the AddressChange event of the web browser control.

w_main.of_SetImage(PARENT, ls_file)

PARENT is a reference to the u_cst_web control that the web browser is sitting on.

We can also use the TitleTextChanged event to get any new titles for the tab:

w_main.of_SetText(PARENT, titletext)
w_main.of_SetTipText(PARENT,titletext)

In a nutshell, that's pretty much it. The Ultimate Suite w_pbus_spa_tab object does all the heavy lifting on the UI side. The PB Web Browser control does it's thing by reliably displaying the web site. Lastly, using the HTTPClient object, we can successfully get a sites favicon.

Comments