Web Canvas Image by Seth Willits
09-17-03
For some reason, I have a nasty habit of referring to each tutorial as "this week's," so if I do say "week," just smile and nod and know that I mean "this tutorial." With that in mind...
In this tutorial we're going to learn how to use the HTTPSocket class, a new feature in REALbasic 5.0, to show an image that we're going to download from the web in a canvas. As you might think, this is actually quite simple, but by no means is the HTTPSocket class "simple." Simple to use maybe, but what you can do with it is for the most part limitless. (We'll explore the HTTPSocket class in future tutorials.)
The first step is to create a new project and drag a canvas to the window. Next, Control-Click or Right-Click on the main window. (Didn't know that contextual menu was there, did you?) Select "HTTPSocket" from "Add Control->Any->Socket Core...->TCPSocket...". After that, add two properties "Image as picture" .
The HTTPSocket class allows your REALbasic application to connect to a web site, or more accurately, an HTTP server and send requests such as downloading a file or submitting a form. The HTTPSocket class has two settable properties, Address and Port, but since we're going to be using the Get method of the HTTPSocket class which requires an absolute URL anyway, we only need to be concerned about the port which is nearly always 80. So go ahead and put in 80 as the Port value for HTTPSocket1.
For our project we're going to download an image from the ResExcellence website, located at "/realbasic/articles/old_articles/images_02/rbnewslogo.jpg". We're going to request the image from within the Open event of the canvas and then upon receiving it, we'll refresh the canvas so that it draws.
The HTTPSocket.Get method requires only one parameter, an absolute URL to a file on the web site (and in our case this will be the URL in the previous paragraph), but it also has an optional parameter of type FolderItem which specifies a file to download the requested file to. If we don't supply a folderItem to the Get method, then REALbasic puts the data returned by the HTTP server into a string and calls the PageReceived event. On the contrary, if we do specify a file, the DownloadComplete event is fired which has - among others - a "file" parameter which is the file we specified in the Get call.
Here's the one line of code for the Open event of the canvas. This line requests the image and downloads it to the "rbnewslogo.jpg" file in the "Temporary Items" folder.
Sub Open()
HTTPSocket1.Get "/realbasic/articles/old_articles/images_02/rbnewslogo.jpg ", TemporaryFolder.Child("rbnewslogo.jpg")
End Sub
It's important that you specify an absolute URL whenever you use the Get method because if you don't you'll get an error code "103", but note that the file we download and the file we download it to do not have to have the same name.
The DownloadComplete event will only be called if there was a successful connection to the web site, but it doesn't guarantee that the request was fulfilled. For example, if you typed "/rb_knews.jpg" as the file name in the URL parameter of the Get method, the DownloadComplete event would be called, but the httpStatus parameter would be 404 signaling that the file could not be found. With that in mind, in our DownloadComplete event, we're going to test whether the file exists (because if it does then the request was fulfilled), open the file as a picture, put it into our "Image" property, and then call the Refresh method of the canvas so the image will be drawn.
Sub DownloadComplete(url as string, httpStatus as integer, headers as dictionary, file as folderItem)
if file <> nil then
Image = file.OpenAsPicture
Canvas1.refresh
end if
End Sub
The last bit is to actually draw the image into the canvas via the Paint event:
Sub Paint(g As Graphics)
if Image <> nil then
g.drawpicture Image, 0, 0
end if
End Sub
(We test for nil because the canvas may try to draw itself before we've downloaded the image, and drawing nil images is bad.)
Now in a real application, we'd want to handle errors because the real world is never perfect. We can test for a connection error using the Error event:
Sub Error(code as integer)
MsgBox "Error" + chr(13) + chr(13) + str(code)
End Sub
And we can test for HTTP errors in the DownloadComplete event.
Sub DownloadComplete(url as string, httpStatus as integer, headers as dictionary, file as folderItem)
if file <> nil then
Image = file.OpenAsPicture
Canvas1.refresh
elseif httpStatus = 404 then
MsgBox "The file does not exist."
end if
End Sub
That's all for this week's...err... tutorial.... You know what I mean. :-)