This page explains the general concepts behind the newObjects
VisiLabel connectivity and provides the details you need to know.
If you want to skip directly to a specific section click the link
below:
Overview: How newObjects Active Label is loaded/saved from/to an URL and
how graphical elements that need external data load and save it.
newObjects Active Label ActiveX uses the URL Monikers Windows API to
implement all the connectivity it needs. The URL Moniker API is the
client side of an abstract mechanism which has Asynchronous Pluggable
Protocols on the other side. This API offers an abstract layering on the
local machine in which the applications and components that need high
level networking operations can work without respect to the specifics of
the particular protocol and media over which the data is received/sent. Assume
that the figure above represents a process of an application. If part of
it or a component hosted in the application needs to download data it
creates an URL moniker pointing the resource. When the component
initiates the download the URL Moniker invokes an Asynchronous Pluggable
Protocol (APP) component appropriate for the URL of the resource and
performs the operation. The figure above is too simplified, in the
reality there is more to it - data can be uploaded, the components in
the application may host each other and want to provide services that
will allow a hosted component to refer resources relatively to the base
location of its host and so on. The best example of an application
that uses this technique is Microsoft Internet Explorer. The ActiveX
controls designed for it should do this too and newObjects Active Label ActiveX does. The fact that this is abstract layering opens various
opportunities. For example the Windows HTML Help is actually an APP that
serves pages from a help archive (a .chm file), our product Active Local
Pages processes ASP pages and executes CGI in-place etc. Thus the
applications that use this technology are capable to work over many
different protocols using the same code. We should say "in
theory", because there are specific features in all the protocols.
However this "in theory" is not such a problem as you may
expect. HTTP-like behavior became a de facto standard for the most high
level protocols, thus the majority shares the same base traits and there
are no significant problems. Especially for data download any protocol
that works with URL or URL-like resource addresses will work fine with
any such application. However not all APP support data upload/send. In
most cases it is pretty obvious if an APP would support data upload or
not - lets take for an example the HTML Help - there is no point in
allowing uploads in it. But the real catch is that the data upload is
not like saving a file, there could be different kind of processing on
the other side and the parameters you send the way the data is packed
may not fit a particular APP. The best example is a comparison between
FTP and HTTP, in FTP you specify the URL where the data is to be saved,
in HTTP you send it to an URL but where it will actually be saved
depends on the server side application/script which receives it. In
newObject Active Label ActiveX The root object VisiLabel and the
Image and
Text box elements have a property Src. This property behaves just
like the Src property of an image in a HTML page. It can be
changed in any moment and this will load the resource pointed by the URL
set in it into the corresponding object. For example if you change the Src
of the VisiLabel object this will effectively open the label pointed by
the URL (if there is one there, of course). In this respect you can work
with the control the same way you work with elements in a HTML page. As
we mentioned newObject Active Label ActiveX also supports upload, the same
objects have also Dst, PostParams and PostVerb
properties to support this. While Dst is actually the reverse of
Src (i.e. setting the Dst property to an URL sends the data of the
object to it), the other two properties are needed because the upload in
contrast to the download can be done in different ways and may need
different parameters depending on what kind of application or script
receives it on the other side (the server side). Usually you would write
the both sides, so you would know the requirements. The actual need is
that you need some standard characteristics of the uploaded data. For
example what is it - an image, text or the label design definition. To
eliminate the need to implement code that marks everything with
appropriate parameters, the control generates some standard parameters
for each upload. See the Standard parameters section for the details.
Additionally the objects that can be uploaded has a method PostData that
invokes upload without need to change the Dst property.
As we said in other places the newObjects Active Label ActiveX
behaves much like a browser. Aside of the rest there are two very
important reasons for that behavior: Natural integration in HTML pages
and means to obtain the data for the label elements from the same source
from which the WEB page obtains its own resources. These features are
crucial for WEB based business applications and at least important in
typical Windows desktop applications. Without this kind of connectivity
any application that wants to keep the label designs on anything
different from the local hard drive would need to implement countless
tricks and this would increase not only the development effort but would
involve also additional permanent support tasks. Let's take a
quick view over the way the ActiveX is used on WEB pages. If we assume
that it is embedded on the page like this: <object classid="clsid:09A02CEE-410B-47BA-A837-E62C9C8D70BF"
id="VisiLabel" width="300" height="200"></object> it is
embedded without initialization. The defaults take effect and a usually
the WEB page contains some Javascript that interacts with the control.
For example to load a label the script on that page can execute the
following statement: VisiLabel.Src = "/labels/mylabel.activelabel";
Which uses a virtual path to point a static label file residing on
the same WEB site. Of course also a relative path can be used:
VisiLabel.Src = "/labels/getlabel.asp?LabelID=123"
Again virtual path but to an ASP page that extracts the label data
from a database or another repository managed by the WEB application on
the server. VisiLabel.Src = "mylabel.activelabel";
The label is in the same directory where the page resides.
VisiLabel.Src = "getlabel.asp?LabelName=My label";
The ASP page that fetches the label is in the same directory. Or a
full URL can be used id the label is to be obtained from a different WEB
site or even from different kind of location: VisiLabel.Src =
"http://anotherserver/labels/somelabel.activelabel";
or
VisiLabel.Src = "http://anotherserver/getlabel.jsp?LabelID=1234";
Another WEB site
VisiLabel.Src = "C:\\Labels\somelabel.activelabel";
From the local hard drive of the client machine
VisiLabel.Src = "alp://C:/labelapp/getlabel.asp?LabelID=1234";
The label is fetched by an ASP page executed on the client machine
with ALP.
VisiLabel.Src = "mk:C:\\helpfile.chm::/label.activelabel";
From a HTML help file So, the first important thing we can observe
is that the ActiveX control uses the base location conception
just like the WEB pages. The base location of a WEB page is that part of
the URL which defines the page's directory. For example the page http://server/path/somepage.htm
will have base location http://server/path/. The base location
allows relative paths to be used. For example anotherpage.htm
used in a link will mean this other page is in the same directory - http://server/path/anotherpage.htm
following the above example. Also this is used to evaluate virtual
paths (paths relative to the site root) - a path like /somepath/somepage.htm
will map to http://server//somepath/somepage.htm. When
embedded on a WEB page the ActiveX control uses the page's base location.
Thus you can specify in its Src property relative or virtual
paths the same way you specify such in hypertext links in the page or in
the src attributes of images on the page for instance. The
download of the label occurs asynchronously. This means that when you
set the Src property of the ActiveX it will just start the
transfer, but it will finish later. If you want to react upon completion
you need to handle an event fired by the ActiveX - OnDownloadCompleted.
If the operations you want to perform require that the download is
complete you need to perform them not immediately after invoking the
download but after the event is received! In other cases these
operations may not be automatic - e.g. you may have two buttons. The
first starts the download of a label and the second invokes some kind of
operation over it. As the user is the one who invokes the operation at a
later time you need to know if the download is complete only when it is
invoked. In such cases you can check the download state of the object
(See Download states below) when the
operation is invoked by the user and not handle the event (at least not
for that purpose - you may need it for some other operations). How
to handle the event? <SCRIPT FOR="VisiLabel"
EVENT="OnDownloadCompleted(element,success)">
... the handling code. It can use the element
and success like regular function arguments ...
</SCRIPT> Note that download can be invoked not only for
the label as whole but also for separate image and text box
elements. They have the same Src property and it follows the same
rules. They are also aware of the page's base location and you can
specify the Src for them the same way as for the ActiveX as
whole. In other words aside of the fact that you access them through the
newObjects Active Label object model you treat them much like the other
loadable WEB page elements. For example if you have an image with
ID="MyImage" on the WEB page and an image element in the label
with name "AnImage" and you want to show the same image on the
label and on the WEB page you can do something like this: VisiLabel("AnImage").Src
= "/images/myimage.jpg";
// The image on the label
document.all("MyImage").src = "/images/myimage.jpg";
// The image in the HTML page When you invoke a label download
e.g. VisiLabel.Src = "url_of_the_label" it automatically
invokes the download of the image (and the text boxes if they have
non-empty Src property) elements on it after the label has been loaded.
Therefore this is much like loading a WEB page in a frame for example. A
separate image element download (without loading a new label - i.e. only
changing the image shown in the element) may occur if you invoke it
explicitly (see the above sample lines of code) by setting the Src
property of the image element or when the internal data source is
navigated. For example you may want to allow the user to navigate
through the data entries, if there is a field that is linked to an image
element and it changes the image element source location (Src property)
then updating the label with the new data record will invoke download of
the new image. The OnDownloadCompleted event is fired for all
the downloads. I.e. the same event is fired for label download and for
element download (image element for example). You distinguish the
element for which the event is by checking the element parameter
of the event. If it is >= 0 then this event is about an
element. You can use the element as index and access the element's
object. When the element is -1 this event is for the label itself.
Apparently when you invoke label download the first event you will
receive will be about the label (element = -1) because the label must be
loaded before the ActiveX can determine what elements are on it and
start download for those of them that need such. What happens when the
download operation is not yet complete but you start a new one by
setting the Src property of the label or an element on it. The pending
operation is cancelled or ignored (whatever is appropriate for the
particular URL protocol used) and the new download operation is started.
OnDownloadCompleted is not fired for the cancelled operation, but
it is fired for the newly started operation. Thus you will receive only
one event - when the download of the respective object is truly
complete. This appears to be more convenient and effective and that is
why we did it that way. For instance firing too many events may decrease
the page performance (do not forget that they are usually handled by a
script), you would need more code to handle them etc. If you wonder
why the root object fires all the events (even for the objects that
represent the elements on it): It is nearly impossible to effectively
implement event handling for the inner objects of an ActiveX in a WEB
page. Especially when they vary (you can create/delete elements on the
label) additional Javascript code would be required to attach a handler
for them which would obviously increase the development effort. Having
all the events fired by the root object makes their handling very simple
and only static code in the WEB page is needed. You can access easily
the element objects for which the events are by using the indices passed
as parameters by the events.
If you have experience in the WEB development you probably associate
the post/upload operations on WEB pages with forms. It is possible, of
course, to use your own form(s) on the page on which the control is
embedded to post label related data to the server side. You can just
extract whatever properties you are interested in and put them in hidden
fields for example. It is even possible to obtain the definition of the
entire label from the VisiLabel.TextCommands
property and put it in a field. However this is not the most
effective way and it will require you to write additional code. We will
discuss below the techniques supported by the ActiveX itself, you can
still use your own forms and transfer information from the label using
Javascript sometimes, but this is a regular DHTML programming and does
not need any special remarks in this documentation. The newObjects
Active Label can post/upload data on its own. It has no forms or
form-like user interface thus the post/upload operations are invoked in
a bit different manner than on a WEB page. The label (VisiLabel
object), the image elements and the text
box elements support upload/post in the version 1.0, future versions
may extend this to other objects as well. For that purpose they have the
following properties: Dst, PostParams, PostVerb and
PostResult. They also have a method PostData which is just
a helper.. The Dst
property is the opposite of the Src. When set to an URL or
relative/virtual path it invokes the object to upload/post its data. If
you want to invoke upload to the URL/path already contained in the Dst
property you call the PostData method. Just like the Src
property the Dst is again aware of the page's base location, thus
the same rules apply for Dst as like for the Src (see the above section)
- you can use relateive, virtual paths and full URL to refer an
upload/post location. The upload/post operations, however, usually
involve some extended processing on the server side (the receiving
side). For example if you post through HTTP you post to a server side
script (for example an ASP, JSP, PHP page or other kind of server side
application component). That script (receiver) usually receives the data
and stores it in some manner. Some applications would use database,
while others may store the data in files on the server, others may use
other storages. Thus unlike the download the upload/post requires an
information about what is uploaded/posted and sometimes even custom
information you specified on the client side. In uploads and
form posts invoked from a form on a WEB page this is usually done by
using some fields in the form, but in this case the very nature of the
operations requires other means of passing that data. First of all
consider when the uploads occur - you may want to save the label on the
server, you may want to send also the images on it to the server thus
make the entire label fully loadable from the server from this point
further. I.e. the uploads/posts from newObjects Active Label control are
more similar to save operations than to form submits. Such a role means
that the user should not be involved in specifying the details about the
posts - this must be done automatically by the control and if this is
not enough the Javascript on the page should do the rest of the work. The
PostParams property serves that purpose - in it you can set some
parameters that will be appended to the URL when the upload is
performed. The receiving script on the server side uses them to
determine what is uploaded and the rest of the details it needs. The
parameters in the PostParams are specified in the usual format for the
URL parameters: ParamName1=Value1&ParamName2=Value2 etc. The control
generates also several standard parameters which are also appended
automatically when the post/upload operation occurs. These parameters
carry the most important information about the uploaded data and are
usually enough for the server side script, thus most often eliminating
the need you to set any parameters using Javascript on the client side. The
standard parameters: for the VisiLabel object
The VisiLabel object attaches a parameter LabelName which carries
the name specified for the label. It can be accessed directly through
the VisiLabel.Caption property. The post URL would look for example like
this http://server/page.asp?LabelName=YourLabelName. for the Image
elements
The PostParams of the VisiLabel object are appended, the LabelName
is appended too. Then the following additional parameters are appended
as well:
Name - the element's name (accessible otherwise through the
object's Name property).
ElementType - the element type constant the same as the value
returned by the ElementType property of the object.
ImageType - the image format constant, same as the value returned
by the ImageType of the Image element.
Thus the post URL for an image upload for the server side will look like
this for example: http://server/script.asp?LabelName=YourLabelName&Name=TheImageElementName&ElementType=5&ImageType=1. for
the Text element (text box)
The PostParams of the VisiLabel object are appended, the LabelName
is appended too. Then the following additional parameters are appended
as well:
Name - the element's name (accessible otherwise through the
object's Name property).
ElementType - the element type constant the same as the value
returned by the ElementType property of the object.
Thus the post URL for a text box upload for the server side will look
like this for example: http://server/script.asp?LabelName=YourLabelName&Name=TheImageElementName&ElementType=5 The
next important question is what the server side receives The
control and its elements use very simple method - they post their data
as binary stream to the receiver/server. Thus unlike the form uploads
from the browser the uploads from the newObjects Active Label control
are extremely easy to process. Lets see what we know to this point:
1. All the parameters that accompany the post/upload are passed as
parameters in the URL (also known as query string parameters), thus
they are not mixed with the posted data.
2. All the object's data is sent as continuous stream without further
packing.
To save/store the received data the server side script needs just to
read all the data and store it in the manner the developer wants. Any
information that describes the data can be obtained from the URL
parameters before starting to read the incoming data. As the URL
parameters are common technique all the WEB programming tools and
technologies offer simple and easy to use methods to read them. No
matter what kind of programming language you are using on the server
side the crucial code is literally a few lines. You can see below a
little code cut from one of the ASP examples. We intentionally put it
with part of the code that deals with the database (ADO is used) to give
you a more real-world picture. ... other code ...
If Request.QueryString("ElementType").Count > 0 Then
If Clng(Request.QueryString("ElementType")) = 5 Then
Set rimage = Server.CreateObject("ADODB.Recordset")
rimage.Open "SELECT * FROM Images WHERE LabelID=" & labelID & " AND " & _
"ElementName='" & dbEsc(Request.QueryString("Name")) & "'", db, 1, 3, 1
If rimage.EOF Then
rimage.Close
rimage.Open "Images", db, 1, 3, 2
rimage.AddNew
rimage("ElementName").Value = Request.QueryString("Name")
rimage("ImageType").Value = Request.QueryString("ImageType")
rimage("LabelID").Value = labelID
End If
rimage("ImageData").Value = Request.BinaryRead(Request.TotalBytes)
rimage.Update
imageID = rimage("ImageID").Value
rimage.Close
Response.Write "OK " & "image.asp?ImageID=" & imageID & vbCrLf
Else
Response.Write "ERR: This ASP page saves only images"
End If
Else
... other code ...
The lines in bold actually do something with the received data or the
accompanying URL parameters. As you can see the actual data read is a
single line of code (in blue).
What the data looks like?
Each object that supports upload/post posts different kind of data.
Usually you do not need to process it on the server side, thus there is
not need of much knowledge about what the data received is. Usually you
need to know only what it represents and the image format in case of
images. See the standard parameters above for more information.
The label definition itself (uploaded by the VisiLabel
object) is uploaded in the format specified in the VisiLabel.Misc.SaveFormat
property.
Confirmation for successful upload/post
The receiving server-side script should return a confirmation that
the operation has been performed successfully. See the Upload/Post
states below for the format requirements.
Each object in the control's object hierarchy has a property named ObjectState.
It can be checked for each object any given moment to determine its
load/ready state. The state indicates the result of the last download
operation performed by the element. In most cases you need to check this
property if the download is invoked by your code or when the label has
been just loaded. The values returned by the ObjectState
properties are:
0 - uninitialized. The element is in undetermined and
unusable state. This value is not actually returned except to indicate
fatal internal errors. In future versions of the ActiveX it may be
used by new graphical element types.
1 - loading. The element is currently loading data.
While in this state the element should not be used if possible. The
data is not yet entirely received.
2 - loaded. The last download operation has finished but
unsuccessfully.
3 - usable. The last download operation (if any) has
finished but was not completely successful. This may indicate that the
the data has been incomplete or corrupted, or no data has been ever
downloaded.
4 - ready. The element is ready and any download
operations have been finished successfully.
Remarks: The image elements are initially in usable
(3) state if they have empty Src property (i.e. the image
element is added but has not been set up with an picture to be shown).
Also most elements report usable in case of network errors, thus
the loading (2) state is used only in case of serious connection
errors that may put the element in completely unusable state (e.g. any
call to a member or property of an object in this state will most likely
case script error, because the usual operations supported by it cannot
be performed).
The ObjectState of the root object - VisiLabel
object has a special behavior. Instead of returning the
state of the root object only it summarizes the state of the root object
and all the elements on it and returns the lowest value. For instance if
even one image on the label is still loading it will return 1 - loading.
Thus to determine if all the download operations are complete you can
use the expression VisiLabel.ObjectState > 1 (where VisiLabel
is a variable referring to the root object of the control's hierarchy).
The objects that support upload/post operations support a property
named PostResult. It indicates the current state of the upload
operation and its success after its completion. The operation can be
invoked by setting the Dst property of the object or by calling its
PostData method, also OnPostCompleted event is fired when the operation
completes. The PostResult can be checked at any given moment to
determine what is the state of the object. The returned states are:
0 - not currently used and returned
1 - uploading. Upload/post operation is in progress.
2 - finished. Upload finished but unsuccessfully
3 - uploaded. The upload/post has been completed without
success confirmation from the server-side.
4 - complete. The operation has been completed successfully.
Remarks: The objects that support this property are initially
in complete (4) state. The state changes to uploading (1) if upload/post
is invoked and changes to 2, 3 or 4 when it finishes. The ActiveX expects a
plain text response from the server side in this form:
OK new_url<cr><lf>
optional_custom_data
The new_url is optional and if present changes the Src
property of the uploaded object. It is assumed that this feature is used
by the server side scripts to inform the element where it has been saved
and thus how it can be extracted in future. All the data after the first
line is ignored and can be used for tracking and tracing (see also the
OnDebugEvent). As not all protocols (FTP for instance) support custom
programming on the server side the state uploaded (3) will be returned
if upload is invoked through such protocol - even if everything is ok.
That is why the state 3 can be clear indication of an error over HTTP or
ALP where you have designed the server side script and you are sure they
return OK to confirm the success, but over protocols that do not have
this capability it will mean just "upload operation
completed". Apparently in most cases you can assume a value >=3
for success when using non-application oriented protocols like FTP,
still sometimes this may not be true depending on the server behavior.
So, if you intend to use such a protocol we strongly recommend you test
carefully the behavior of your server before relying on it.
|