Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

GUI in JScript and VBScript, using Windows Common Controls

0.00/5 (No votes)
18 Mar 2009 2  
This article is about writing GUI applications in VBScript and JScript using Windows common controls

Introduction 

You may want to create a GUI application written in VBScript or JScript using Windows Common Controls. I'm sure you would not like to read tons of sources to find two lines of useful code.  This article is only an ABC, a starting point.

First of all, VBScript or JScript GUI application are not real Win32 API. This kind of GUI is HTA or HTML for Internet Explorer browser. By using any of them, you can take advantage of easy using Windows features. Standard windows controls like buttons, edit boxes, comboboxes do not require anything special to use in HTA. But Windows Common Controls, like TreeView, ListView are available as ActiveX controls.

This may look a little like WEB design. But in fact this is a mixed style of programming.

If you need plain Win32 API, you would rather need some scriptable wrapper of WinAPI written in C/C++, or any other languages. But for many Windows applications, HTA and HTML for Internet Explorer are far enough. You can be surprised how many types of applications you may write in HTA or HTML for Internet Explorer.

Background

This code explains as briefly as possible the main ideas of using standard ActiveX controls as to what wraps Windows Common Controls. It can be used with client side scripting just in HTML pages, or as standalone HTA applications. It is ideal to use at the office, where policy could prohibit using some third party programming languages, browsers, compilers, components, non windows operation systems, or all of them. You don't need to install anything, and these applications will work. To use HTA applications, you will need to copy scripts to each computer on which you would like to use them, or put on a share folder on the local network. Or you could put applications on a WEB server, and users will use it via Internet Explorer browser. 

This Code Can't be Used  

This code is incompatible with non Microsoft Windows operation systems. This code is not compatible with non Microsoft Internet Explorer browsers. A big advantage is to have some basic knowledge of ActiveX. But it is not required. You can use this without knowing ActiveX.

Some Technical Background

I don't intend to write a full guide to ActiveX controls. All the member functions, properties, events and passed arguments, you can find with tools like Office VBA, OleView. In Office VBA, you need to add a reference to some version of Microsoft Windows Common Controls by finding and checking it in the list of references, or add by browsing for mscomctl.ocx. After that, you will see all the information in the Object Browser. If you use OleView for that, I'm quite sure that you know how to find these objects.

Now, some information for people who are not familiar with ActiveX. The ActiveX objects are identified by ClassID (clsid). This is a GUID which looks like a big thing with 32 hex numbers that makes no sense for a human. A more human readable identificator is ProgID. If you would like to use some other versions, or if windows has other versions of controls, you may need to use other clsids than the ones from my samples. In this case, you need to find the clsid in the type library. If you don't have OleView, you can't find them in Windows registry. For instance, I use the TreeView control. The ProgID of TreeView control is MSComctlLib.TreeCtrl. You have to find this ProgID in the registry inside HKEY_CLASSES_ROOT:

HKEY_CLASSES_ROOT\MSComctlLib.TreeCtrl

or some other version:

HKEY_CLASSES_ROOT\MSComctlLib.TreeCtrl.2

Here you find the default value of subkey CLSID. It is exactly the CLSID you need. On my computer, it is {C74190B6-8589-11D1-B16A-00C0F0283628}. Just remove the brackets and copy/paste in your code.

Let's Use a TreeView

See the archive TreeView.zip.  

To use the TreeView, you need to insert the TreeView ActiveX object:

   <object id="ITreeView"  classid="clsid:C74190B6-8589-11D1-B16A-00C0F0283628" 
						height="200" width="200" >
      ......
   </object>

To manipulate the object, you will need to obtain the object.
In VBScript, you do like this:

set treeObj = document.getElementById("ITreeView").object

Quite the same thing is done in JScript:

treeObj = document.getElementById('ITreeView').object; 

From ActiveX point of view, this code obtains the IDispatch of the ActiveX object.

Let's add nodes/items to the treeview in VBS:

set x  = treeObj.Nodes.Add(null, TreeRelationship.tvwFirst, "key 1",   "The VBS Item 1")
set x1 = treeObj.Nodes.Add(x, TreeRelationship.tvwChild, "key 1.1", "The VBS Item 1.1")
... 

Same thing in JS:

x  = treeObj.Nodes.Add(null, TreeRelationship.tvwFirst, "key 1",   "The JS Item  1");
x1 = treeObj.Nodes.Add(x,    TreeRelationship.tvwChild, "key 1.1", "The JS Item  1.1");

The function add(...) returns the added node. The first parameter should be a related tree node, for example the parent node. The second parameter indicates how the nodes have to be added. The third parameter is a key which must be unique.

Using ImageList VBScript and JScript with TreeView

See archive TreeViewAndImages.zip.

To use images/icons for tree nodes, you need an image list:

treeObj.ImageList = imgList

Now, adding a node with image is just a snap:

set x = treeObj.Nodes.Add(null, TreeRelationship.tvwFirst, 
		"key 1", "VBS Tree Item 1", "PictureNumber0")

A small difference is one more parameter. The last one. This parameter indicates the ID of picture in the imgList.

Same thing in JScript:

x = treeObj.Nodes.Add(null, TreeRelationship.tvwFirst, 
			"key 1", "salut 1", "PictureNumber0");

The imgList is another ActiveX object. It can be instantiated like this:

VBS:

set imgList = CreateObject("MSComctlLib.ImageListCtrl.2") 

JScript:

var imgList = new ActiveXObject("MSComctlLib.ImageListCtrl.2");

Loading images is done in VBScript like this: 

imgList.ListImages.Clear()
imgList.ListImages.add  1, "PictureNumber0", LoadPicture("Icon\Number0.ico")
imgList.ListImages.add  2, "PictureNumber1", LoadPicture("Icon\Number1.ico")

Function LoadPicture returns a IPictureDisp. This function is available in standard WSH VBScript, but is not available in WSH JScript. To use it in JScript, we can write a short and very simple VBScript wrapper, see VBScriptWrapper.wsc in TreeViewAndImages.zip.

First of all, register this wrapper with regsvr32 in the command line:  

regsvr32 VBScriptWrapper.wsc   

Now we can use function LoadPicture in the JScript program:

var vbsw = new ActiveXObject("IFVBScript.Wrapper");

Now load pictures:

imgList.ListImages.Clear();
imgList.ListImages.add(1, "PictureNumber0", vbsw.LoadPicture("Icon\\Number0.ico"));
imgList.ListImages.add(2, "PictureNumber1", vbsw.LoadPicture("Icon\\Number1.ico")); 

Another way to use this wrapper is to declare it as an HTML <object>:

<object id="VBScriptFunctionsWrapper" 
	classid="clsid:02F3817F-4555-4e51-A741-D87662FA7987"  > </object>

Accessing it in JScript and loading images:

var vbobj = document.getElementById('VBScriptFunctionsWrapper').object;
imgList.ListImages.Clear();
imgList.ListImages.add(1, "PictureNumber0", vbobj.LoadPicture("Icon\\Number0.ico"));
imgList.ListImages.add(2, "PictureNumber1", vbobj.LoadPicture("Icon\\Number1.ico"));

If you know a better way to LoadPicture in JScript, please tell me.

Events  

In response to user input, you may need to process events. Let's process the click on an item, and the mouse move over the tree. See TreeViewWithEvents.zip.  

In VB, you will do the standard way of processing event SomeEvent of an object with ID SomeObject. You just have to add a procedure named SomeObject_SomeEvent, and voila: 

sub MyTreeView_MouseMove(Button, Shift, x, y) 
   'processing mouse move here
end sub

sub MyTreeView_NodeClick(node) 
   'processing the node click here
end sub 

In JavaScript, this is quite standard as well. You addition should look like this SomeObject::SomeEvent

function MyTreeView::MouseMove(Button, Shift, x, y)
{
   //process the mouse move here
}
function MyTreeView::NodeClick(node)
{
   //process your node click here
} 

To find what item is under a coordinate x,y is used the function HitTest. But function HitTest does not accept pixel coordinates like the ones you get in MouseMove event. Before you pass coordinates to HitTest, it is required to transform them from pixels to twips. On my computer, I use 14.4 to transform.  

VB: 

set node = treeObj.HitTest(x * 14.4, y * 14.4)

JScript:

node = treeObj.HitTest(x * 14.4, y * 14.4);

Points of Interest

This article is not finished, and will be continued. 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here