How to create an IE toolbar step-by-step. This page is
intended to explain the toolbar development process
step-by-step. As you will see we will not try to construct an
actually useful IE toolbar application, instead we will try to
follow the way almost any IE ScriptBar application would follow
and deviate a little from the straight line so we can pay more
attention to some basic techniques which are useful for a big
number of applications. To avoid mixing everything up this page
doesn't discuss the IE ScriptBar's menu system. After reading
this article you can move on to the menu
system chapter.
How to proceed.
If you have a start-up package received with the license install it
and go to the installation directory (Program Files\<Company
name>\<TB name>). It will be convenient to create a
shortcut to this directory on your desktop so that you can get
quickly there the next time you need to continue your work. If
you are working with the demo version go to its install
directory (Program Files\newObjects\ScriptBarDemo) and do the
same. All the work you are going to do with the demo can be just
moved to the licensed version and used without changes, so you
can start over the demo version and purchase license in the way
and continue.
In the install directory you will see the following files:
toolbar.cfg - the toolbar
configuration.
newObjectsIEScriptBar.DLL - the toolbar core DLL
toolbar.htm - The toolbar
user interface HTML. This file is almost empty and is there
as placeholder only. You can overwrite it with the file you will
create
logo.gif - an image shown in the above file (remove it
when no longer needed).
toolbar.vbs and toolbar.js - two template files
for the toolbar script.
The both files contain a few comments and empty prototypes for
all the events that can be possibly handled.
Note: It is not recommended to work over one of the samples,
get the demo version of the start-up package instead. The
samples come with configurations and surrounding files designed
to fit the sample's needs. Therefore they may differ from what
you read on this page. Furthermore, to avoid making the code too
complex this page does not include any code related to the Menu
system. You can see how to create and show menus on the IE
ScriptBar menus page.
Step 1:
Create a directory where you will edit and create files. Copy
all the files from the install directory except the DLL. Work
only in this especially created directory in order to avoid
mistakes that will overwrite your files when you come to the
installation testing phases. Whenever you want to test your
application - copy the current files from your working directory
to the toolbar install directory and open a new browser to see
how it works with them. If you want you can create a BAT file
that does this.
Step 2:
Decide what scripting language you will use for your
toolbar script and change the settings in the Scripts
section of toolbar.cfg. E.g. change the script language and
the script file. You can specify one of the template files (toolbar.js
or toolbar.vbs) there or specify a new file name and rename
the template that corresponds to the selected script language
if you want to use it as a starting point. Remove the unneeded
script file - for the language you wont use.
Step 3:
Determine how the toolbar user interface will
be loaded. We will assume Direct below. But if you are
going to use the ScriptBar and ALP together you can also
specify ALP instead. If you want to use different name for the
toolbar UI HTML file (e.g. different from toolbar.htm) set it
in the Control
setting of the toolbar.cfg and create that file (or rename the
dummy file supplied for a start).
Strep 4:
Design the toolbar user interface. Assuming that in step 2
you chose toolbar.htm open it in a HTML editor or edit it in a
text editor (as preferred).
Make sure that it has <BASE HREF="%BASE%">
in its HEAD area (Assuming the Direct method is used for
load). For example:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Toolbar</title>
<BASE HREF="%BASE%">
... something else if needed ...
</head>
Take care to specify color and margin settings for the page
body. Using the IE defined color names to match the current
Windows color scheme is a good approach if you are not going
to use image for the background. A good choice will be
something like this:
<body bgcolor="buttonface" text="buttontext" topmargin="0" leftmargin="0" SCROLL="NO">
Create a style sheet. You can embed it into the HTML file
or create a separate file and use a LINK tag to link it into
the HTML file. It is a good idea to define font sizes for the
body the links and the other elements you are going to use. In
general you will return to the style sheet and add more styles
as needed. Use pixels (px) to specify font sizes because the toolbar
size is calculated in pixels on the screen. This way you
will know for certain that your texts on the toolbar will
always occupy the same areas whatever is the configuration on
the user's PC. For example you can start with some styles like
these:
body { font-family: Arial; font-size: 11px }
td { font-family: Arial; font-size: 10px }
Design the body. Here you should use tables (TABLE),
divisions (DIV) and other elements structured in such a
fashion that will guarantee that the height of the content
will be easy to control and limit. Here is one example
structure without actual content:
<table border="0" cellspacing="0" cellpadding="1" width="100%" height="24">
<tr>
<td valign="middle" align="center" width="24" height="24">
...
</td>
...
<td valign="middle" align="center" width="100%" height="24">
...
</td>
...
<td valign="middle" align="center" width="24" height="24">
...
</td>
</tr>
</table>
The above sample uses a table with several cells on the
left with explicitly specified sizes and several cells on the
right and a cell in the middle that will extend to fill the
gap between them. Design the images to match the chosen height
and put them in the same directory or create a subdirectory
for them.
When the design begins to take a shape you can start
writing your scripts in it (if any are needed at this time). For example you may want to
implement several simple routines that change images as the
mouse hovers over them, some routines to hide/show some parts
of the HTML and so on.
When the design reaches usable form you can start writing
routines that intercept onClick events for example and call
from them prospective functions from the toolbar script. For
example if you put an image in your toolbar and you want that
clicking it the user must invoke something you can do it this
way:
<SCRIPT>
...
function MyImg1() {
external.MyRoutine(some_parameters);
}
....
</SCRIPT>
...
<IMG SRC="myimg.gif" ALT="tool tip text" onClick="MyImg1()">
The toolbar script
is accessible for you through the external property. In
the above sample we assume that in the toolbar.vbs (or
toolbar.js if you decided to use JScript for the toolbar
script) you have implemented a Function or Sub named MyRoutine.
It may have as many parameters as needed you just need to
call it with all of them. Thus you can access any of your
routines in the toolbar script by calling external.<routine
name>(... parameters ...).
Better keep the code in the HTML page dedicated explicitly
to UI effects and initial invocation of actions but do not
implement anything related to the actual work in it. This will
keep it clean and easy to work with. Another reason for this
is that your actual work will require state variables and
other resources, spreading the work in two files will only
make the access to them difficult and even impossible
sometimes.
Step 5:
When the UI is prepared enough to allow testing you can
start writing the toolbar script. It is a plain script file.
In the template files (toolbar.vbs or toolbar.js) you have
empty prototypes for all the events that may occur. You will
not need them all - even the most complicated toolbars will
need approximately 1/5 of them. However better leave all the
prototypes for the initial phase of the development so that
you can use them as the need arises. When it becomes
clear which will not be needed you can delete them. By
deleting the unused event handlers you will speed up the
performance drastically.
Under or above the event handlers make space for the
routines you will implement for your own usage. You can split
them in two parts (with appropriate comments and empty lines
for example): One part for the routines called from the
toolbar UI (see the previous step) and the rest routines used only internally.
If you have some initialization work to be done when the
toolbar loads implement it in the beginning outside any Sub or
Function. If you need to pack part of this work in Sub-s or
Functions place them before the code that calls them!
If you have a corresponding clean up tasks needed when the
toolbar unloads from the computer's memory implement them in the
OnUnload
event handler prototype.
Lets try to do something for an example. We will
implement something very simple - search google for pages
referring the page currently viewed in the browser. To this we
need the following:
- A button or image that invokes the action
- A routine that asks the browser what is displayed in it and
forces it to navigate to Google with appropriate parameters.
So lets begin with the UI HTML. In the file toolbar.htm
(assuming you didn't change its name) we put this for example:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Toolbar</title>
<BASE HREF="%BASE%">
<STYLE>
body { font-family: Arial; font-size: 11px }
td { font-family: Arial; font-size: 10px }
</STYLE>
</head>
<body bgcolor="buttonface" text="buttontext" topmargin="0" leftmargin="0" SCROLL="NO">
<IMG SRC="srchgoogle.gif" STYLE="cursor:hand" onClick="external.SearchGoogle()">
</body>
The page for the toolbar user interface is very simple. It
contains only one image and we are calling a routine from the
toolbar script when it is clicked. All the important elements
for the toolbar design are bolded in the sample HTML above.
Now we need to implement that SearchGoogle routine which is
called when the image is clicked. Thus our toolbar.vbs may
look like this:
Sub SearchGoogle
' First we need to learn the URL of the page currently
viewed by the user
Dim url
url = Browser.LocationURL
' Then we need to compose a correct search url for
Google.
url = "http://www.google.com/search?q=link:"
& url
' And now navigate there
Browser.Navigate2 url
End Sub
Step 6:
Now, lets write a bit more code and handle some events.
Usually the toolbar application handles the browser events as
part of its main functionality. Depending on the goal this may
be simple or very complex - it can collect information,
interfere with the navigation, automate tasks and so on. It is
hard to devise an example that will show interesting specifics
for the all imaginable applications, but there is one area
which deserves special attention.
In many applications the developer may face the need to
implement controlled navigation - for example navigating to a
given URL, detecting that the navigation is complete and doing
something with the page. Do not associate this with tasks
automation applications only - the need of such an operation
may arise in many cases. The problem is that you cannot be
sure that the browser will go exactly where you want. What may
happen? In the first place the WEB site may use redirection,
the target URL may be invalid at the moment, an error may
occur on the server side and so on. Checking for all the
possible problems is quite difficult and there is considerable
chance that you will forget something or that the site
structure may change. So, the best approach is to do this in
much simpler way:
What we need to do:
1. Determine how the recognize the final page where we want to
go.
2. Implement a code that will allow the application to recycle
if something goes wrong.
We can recognize the final page in many ways - we can dig
into its object model and search for certain elements, texts
or other elements that are expected to be there, or we can
simply identify the right page by using a part of its URL.
What is the right way depends on the site structure, your
control over it, the way the site is maintained. In other
words you must find out what will identify the target page
today and if possible even after some site changes. In most
cases using part of the URL is good enough because the URL is
usually related to the page functionality.
So, we will do this: navigate the browser to the target
page, init a timeout, and handle two events - OnDocumentComplete
and OnTimeout. In the first event handler we will
implement page recognition code which will check for two
things - if we are really in a process of navigation to that
page and if that is so check if the just completed page is the
page we want to go to. In the second event handler (OnTimeout)
we will wait for the expiration of the timeout we have set. So, if the
timeout elapses before we can recognize the page we
assume that something wrong has happened and we cannot perform
the operation. Of course, we can add more code - recognize
more pages - such as an error page (if the operation depends
on some parameters entered into the toolbar by the user at
some point we may want to handle the error page shown on the
site in such a case), but generally we should
implement the event handlers in question to guarantee that the
application will know if something is wrong even if it has
failed to recognize what is happening - everything else will be a
plus which will improve the work of the application but will
not be crucial for its functionality.
First let us declare a global variable and init it - the
variable will hold the id of the timeout we will use.
Dim MyTimeout
MyTimeout = 0 ' The actual timeout id-s are always non-zero, so we can use 0 to indicate non-initialized state.
Starting the navigation. Assume that the routine below is
invoked in response to an user action over the toolbar (button
click, menu item click or something else).
Sub MyStartNav(MyURL)
MyTimeout = Host.Timeout(60)
' We set the timeout to 60 seconds
Browser.Navigate2 MyURL
' We start the navigation here.
End Sub
For the sake of the example lets assume that we can
recognize the target page by using something specific in its
URL. If, for instance, the page to which we are directing the
browser is some kind of a login page it may have a parameter
"ShowLogin=1" or something like that. Over that assumption we can write the
following code in the OnDocumentComplete event handler:
Sub OnDocumentComplete(frame,url)
If MyTimeout <> 0 And Instr(url,"ShowLogin=1") > 7 Then
Host.DiscardTimeout MyTimeout
MyTimeout = 0
' Our first job is to discard the timeout because we assume the navigation has completed successfully
' This is the page we look for, lets fill the login form in it
If IsObject(Browser.document.forms("loginform")) Then
Dim form
Set form = Browser.document.forms("loginform")
form.Username.value = MyUserName
form.PassKey.value = MyPassword
MyTimeout2 = Host.Timeout(60)
form.SubmitBtn.click()
End If
End If
End Sub
The above code uses the timeout id for an indicator value
for the current navigation task. A little digression - if this was a frameset page
and we have started more than one navigations in different
frames we would have needed one timeout for each navigation.
This way we could have put very similar If .. Then
constructions one after another in the OnDocumentComplete
event handler and each of them would have depended on the
timeout id assigned to the particular navigation task. Using
the timeout id values to distinguish different tasks that need
some code in the same even handler is very convenient practice
because it is guaranteed that the id-s of the active timeouts
are unique for the application. Otherwise we would need
separate variables which indicate that the corresponfing navigation task
has been initiated. So, using the timeout id for the purpose
allows us to use it for the both purposes - recognizing the
task and handling total failure events (see below).
The code in blue above is a bit of digression. It assumes
that the page to which we have navigated is a login form with
a form named "loginform", fields for username and
password and a button. The code uses the botton's
click() method to submit the form and initiate a new
navigation (which is not considered further in this example
code, but it can be handled in a much similar manner). It is
possible to use the Browser.Navigate2 to start a navigation
which will be packed as form post. Then why use the click()
method? The answer is quite simple the click() method of a
button imitates a mouse click over the button and the browser
will think that the user has actually clicked the button. In
browsing automation tasks this is a good way to follow because
we cannot be sure about the additional processing the DHTML
page may implement in a javascript attached to the form submit
or even the button's OnClick events. So, this way we are sure
the browser will do whatever the DHTML page is programmed to
do without need to dig deeper in its structure. The usefulness
of a similar technique depends on how well you know the site over
which the toolbar will implement browsing automation tasks -
if the site is entirely under your control you can choose the
technique you use more freely and even adapt the site to the
toolbar. If the site is not yours you would want to stick to
the techniques that will work even if considerable changes are
made to the site in future and avoid any risks that may arise
if your code depends on too much specific details.
Now, lets handle the OnTimeout event.
Sub OnTimeout(id)
If id = MyTimeout Then
Host.MsgBox "The toolbar is unable to recognize the page or a network error has occured"
End If
End Sub
As we said you can add code in the OnDocumentComplete to
recognize some of the error pages. Still, there is no
guarantee that you will not miss some of them or that they
will never change. Thus the timeout gives us the ultimate
ability to catch the failure even if we cannot recognize it.
In the OnDocumentComplete we discard the timeout if an
expected page is recognized (not only thepage we expect, but
we can do so also for the error pages we handle) and the
timeout would never occur. If nothing is recognized the
OnTimeout event allows us to clean up or at least tell the
user that we are unable to proceed further. In the real world
this navigation process may be part of something more
sophisticated - we may have an open database or files for
instance. Having the ability to catch the failure in any
possible case gives us the opportunity to clean up the
application state and may be restart the process or ask the
user for some data that may be relevant to the navigation
process and then retry it.
The above technique is perhaps the most effective way to
program navigation automation tasks in the IE ScriptBar. It
allows the developer to implement minimal functionality and
then (optionally) add some smarter event handling. Thus the
developer can test the navigation process without need to take
care about everything and then if it is possible to improve it
in order to avoid long timeouts wherever possible.
Step 7:
The previous step illustrated how to construct something
simple, where to put the code and how to test it. Most likely
your application will do much more. For the purpose it will
need to use objects from the toolbar run-time library. We are
listing below some hints about which objects to use for a
particular purpose in the toolbar script (toolbar.vbs in this
example). Still this step is only a hint - there are much more
objects in the run-time library.
Accessing files:
You can use the SFMain
object. Create it like this:
Set sf = Host.CreateObject("newobjects.utilctls.SFMain")
Here the Host namespace represents the internal
ScriptBar's object which provides several utility methods you
can use in your toolbar script.
To open a file you can use the OpenFile method of the just
created SFMain object:
Set file = sf.OpenFile( Settings("BasePath") &
"myfile.txt,&40)
The files and the other streams (file-like resources) are
represented by SFStream
objects. I.e. the file variable in the above code receives one
such object which drives the opened file.
Reading from a file in text mode:
str = file.ReadText(-1)
and so on.
You can find the full description of all the file, stream,
storage oriented objects and their methods in the Storages
and Files section of this documentation.
Using the embedded SQL database engine.
You use the SQLite COM object to work with it:
Set db = Host.CreateObject("newObjects.sqlite.dbutf8")
Open a database:
db.Open Settings("BasePath")
& "mydb.db"
Execute a query:
Set res = db.Execute("SELECT
* FROM MYTABLE")
See the SQLite COM
documentation.
To establish TCP/IP or IRDA communication with other
computers and applications you use the NetStreams
objects
When needed you can run part of your application in
background thread(s). See COMScriptThread
object. This may be needed in any scenario that
involves slow operations that do not need the constant user's
attention. For example synchronization, checking/downloading
resources from the network, data analysis and mining,
resources indexing and many other cases. Note that the
COMScriptThread object allows you create customized
environment for the script running in the thread - you are
free to define global namespaces in it - such that would suit
it best. All this requires just a few lines and saves a lot of
dirty work.
When working with databases or textual data that needs
formatting you can use the StringUtilities
object to compose strings from constant and variable
data with minimum effort.
You can transfer data between your application and others
or just save restore structured data using the ConfigFile
object. This technique is in many respects similar to
XML, but in contrast it is more efficient. It supports both
inter-machine/inter-application format and human readable
format. You can use it to read maintain your own configuration
files, transfer data, exchange data with servers and so on.
There are various utility objects such as the VarDictionary
which provides you with collection/dictionary object capable
not only to store keyed values, but also convenient for
complex tree-like structures where the
dictionaries/collections can be nested in each other. As it is
also used by many other objects as medium through it you can
simplify many of the data transfer tasks - see ConfigFile,
SQLite COM, SFMain and so on.
Step 8:
After finishing the application you must prepare its setup
package. Lets list the tasks you need to do:
- Create a copy of the development template setup package
in a new directory.
- Copy all the files that form your application in the
appropriate location in it and remove the unneeded files
from the template package.
- Edit carefully the setup.cfg to include all the files
your application uses and inspect and change as needed
some of the setup settings.
- Test the setup. You may use another machine or uninstall
(and clean up) the template from your development
workstation.
Now lets consider each step in more details. We will assume
that you will not change the setup structure drastically -
which is not needed for the most applications. You may need to
change the setup structure if the application you are building
is very complex and certainly if you are going to distribute
it together or as part of a bigger project. However, this is
out of the scope of this step--by-step guide.
1. We will assume that the directory in which we will
create the setup package is C:\MyToolbar
Our first task is to copy/unpack the original setup package
from the development template. Doing so we preserve its
structure (i.e. subfolders and so on).
2. We need to copy our files from the work directory. This
is the directory named "tb". Copy the files
from your work location there replacing the files from the
template with your files. If you have created subdirectories
under it copy them too. After that you can take a look and
clean up any unnecessary files - for example files from the
template package you are not going to use.
Before continuing check the toolbar.cfg to make sure
everything is ok. Redesign the AutoShow.htm if you are going
to use it - this is the page that shows your toolbar
automatically after the setup (unless the user security
settings are too high). Check if you have the introductory
pages in place (one often forgets these) - this can be
combined in the AutoShow page if the instructions are not too
big. Anyway it is a good idea to explain what the toolbar does
to the user and show this after the setup. Today's concerns
about the security are making this very important - you must
gain the user's trust by telling him/her what your toolbar
does and how to work with it from the beginning. Failing to do
so may cause many users to disable or even uninstall it very
soon as they would prefer to avoid something they do not
understand! This is very important for IE plug-ins because in
contrast to the other applications the IE toolbars are with
the user almost all the time.
3. The most important step - the setup.
|