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.
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 to our main window; In the AddTabButtonClicked event, we will open a new browser window.
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_StatusCodeString ls_ContentType, ls_body, ls_stringString ls_fileBlob lblb_blobHttpClient lnv_HttpClientlnv_HttpClient = CREATE HttpClient// Send request using GET methodli_rc = lnv_HttpClient.SendRequest("GET","https://www.google.com/s2/favicons?domain=" + as_url)// Obtain the response messageIF li_rc = 1 THEN// Obtain the response statusli_StatusCode = lnv_HttpClient.GetResponseStatusCode()IF li_StatusCode = 200 THEN// Obtain the headerls_ContentType = lnv_HttpClient.GetResponseHeader("Content-Type")// Obtain the response datalnv_HttpClient.GetResponseBody(lblb_blob)Long ll_file, ll_FileLen, ll_Loops, ll_Stepn_cst_pbus_string lnv_stringls_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 THENls_file = ls_file + ".png"ELSEIF Pos(ls_ContentType, "jpg", 1) > 0 OR Pos(ls_ContentType, "jepg", 1) > 0 THENls_file = ls_file + ".jpg"ELSEIF Pos(ls_ContentType, "ico", 1) > 0 THENls_file = ls_file + ".ico"END IFls_file = "C:\Users\your user id\Documents\" + ls_filell_file = FileOpen(ls_file, StreamMode!, Write!, LockWrite!, Append!)IF ll_file > 0 THEN// Determine how many times to call FileWritell_FileLen = Len(lblb_blob)IF ll_FileLen > 32765 THENIF Mod(ll_FileLen, 32765) = 0 THENll_Loops = ll_FileLen/32765ELSEll_Loops = (ll_FileLen/32765) + 1END IFELSEll_Loops = 1END IFFOR ll_Step = 1 To ll_LoopsFileWrite(ll_file,BlobMid(lblb_blob,((ll_Step - 1)*32765) + 1, 32765))NEXTELSE//log the error, or handleEND IFFileClose(ll_file)END IFEND IFDESTROY lnv_HttpClientRETURN 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.
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:
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.