Obtaining our news with XMLHTTP
If you haven't used the XMLHTTP library before, you should have a quick read
of this article first: http://www.devarticles.com/content.php?articleId=25.
We will create a function named LoadNews. LoadNews will handle all of the background
work (retrieving and displaying the news items), while still updating the progress
bar on our actual ActiveX control.
Our LoadNews function will accept a reference to a string variable (byref),
and return a Boolean value, indicating the success/failure of the function as
a whole. If an error occurs, its description will be stored in the string variable
passed as a reference. The declaration of the LoadNews function looks like this:
Private Function LoadNews(ByRef msg As String) As Boolean
The LoadNews function is declared as private, so that when it comes time to
compile and distribute our ActiveX control, only the control itself can call
the LoadNews function. Several objects from the MSXML 4 library are also created,
as well as two string variables and one integer variable. These will be used
to hold the details of each news item:
Dim objXMLHTTP As New MSXML2.XMLHTTP40
Dim objXML As New MSXML2.DOMDocument40
Dim objXML_Root
Dim strURL As String
Dim strHeadLine As String
Dim counter As Integer
Next, we set the URL of the XML news page we will be retrieving. If you visit
http://w.moreover.com/categories/category_list_xml.html,
you will see a list of news topics. At the time of writing, there were 334 available.
I have created a constant string variable in the general declarations section
to hold the name of our news category, like this:
Const NewsCategory As String = "Videogame news"
This is used to form the URL of the XML page to retrieve, as shown below:
strURL = "http://p.moreover.com/cgi-local/page?c=" & NewsCategory & "&o=xml"
Next, we use the Open and Send methods of our XMLHTTP object to actually retrieve
the page. We are using the "GET" HTTP protocol, and have set asynchronous mode
to false, meaning that our XML document MUST be downloaded before we can continue:
objXMLHTTP.open "GET", strURL, False
objXMLHTTP.send
We also update the loading message and progress bar:
lblLoading.Caption = "Loading XML news feed..."
pbProgress.Value = pbProgress.Value + 1
Once the request method of the XMLHTTP object has returned, we try and load
its text (available as the responseText variable) into our XML document object.
If an error occurs, the function is aborted and the value of the string-referenced
variable is set to the errors description:
objXML.loadXML (objXMLHTTP.responseText)
'Make sure that valid XML was returned
If objXML.parseError.errorCode <> 0 Then
msg = objXML.parseError.reason
LoadNews = False
Exit Function
End If
At this point, if the function hasn't encountered any errors, then the XML
has been loaded successfully, and we are ready to extract each news item. We
obtain the root element of the XML document into the objXML_Root object, and
use its getElementsByTagName function to make sure it only contains
elements:
Set objXML_Root = objXML.documentElement
objXML_Root.getElementsByTagName ("article")
Our ActiveX control will display the top five items in the XML document (The
MoreOver.com XML document returns twenty by default). We use a simple "for" loop
to extract them from our XML document. Once a loop is complete, the status message
and progress bar are also updated:
For counter = 1 To 5
lblLoading.Caption = "Loading news item " & counter & "..."
pbProgress.Value = pbProgress.Value + 1
The URL of each item is extracted into the strURL variable. The headline and
source of each news item are also extracted into the strHeadLine variable:
strURL = objXML_Root.childNodes(counter).childNodes(0).firstChild.Text
strHeadLine = objXML_Root.childNodes(counter).childNodes(1).firstChild.Text &
" [Source: " & objXML_Root.childNodes(counter).childNodes(2).firstChild.Text
& "]"
Under the general declarations section of our ActiveX control, I have created
an array that will hold each of the links to the news items:
Dim arrLinks(5) As String
When a user clicks on a label containing the details of a news item, the items
link (contained in the arrLinks string array) is executed using the ShellExecute
API function (more on this later). We simply set the value of each items URL
to its index in the arrLinks array, like this (we use "counter-1" because arrays
are indexed from 0 onwards):
arrLinks(counter - 1) = strURL
We also set the caption of the link to the headline:
Select Case counter
Case 1
lblLink1.Caption = strHeadLine
Case 2
lblLink2.Caption = strHeadLine
Case 3
lblLink3.Caption = strHeadLine
Case 4
lblLink4.Caption = strHeadLine
Case 5
lblLink5.Caption = strHeadLine
End Select
Lastly, we make sure that all of the labels are visible, destroy all of the
XML objects, and return true, indicating that the function succeeded:
'Hide the status label and progress bar
lblLoading.Visible = False
pbProgress.Visible = False
'Make sure the labels are visible
lblLink1.Visible = True
lblLink2.Visible = True
lblLink3.Visible = True
lblLink4.Visible = True
lblLink5.Visible = True
'Kill the XML objects
Set objXMLHTTP = Nothing
Set objXML_Root = Nothing
Set objXML = Nothing
LoadNews = True
Exit Function
The LoadNews function takes care of retrieving, extracting and displaying
our news links. Let’s take a look at how the ActiveX control will actually display
the link.