Introduction
For a long time we have received requests for features and extensions that we could not easily provide with our limited development resources. As a micro-corp we must focus on providing the most value possible for the largest number of customers, so many requests stayed on our to-do lists for quite a long time. Previous versions of Personal Stock Monitor included a way to extend the software with plug-ins, but writing plug-ins required advanced programming knowledge and was therefore out of the reach of most of our customers.
With the Personal Stock Monitor release, we have now included a way for our customers to easily extend the software on their own through scripting. Because writing extensions is now so much easier than before, we at DTLink Software are also considering offering custom extension writing services for our customers who are interested in specific functionality.
What is Possible
Personal Stock Monitor extensions can be written with any of a number of scripting languages, including VBScript, JScript, PerlScript, and Python. In all cases the object model will be the same. The same object model can also be accessed from other OLE-compatible applications such as Excel, which allows for extensive custom integration, but that is a topic for another article.
The object model includes access to all of your portfolio data, including multiple portfolios, tickers, transations, alerts, and historical data. It includes the ability to add custom menus commands to the application and receive events when those menu commands are selected. It includes the ability to define custom technical indicators for the charts, the ability to create custom reports, the ability to generate alerts, and more. Detailed object model documentation is available on the Personal Stock Monitor web site.
Scripts vs. Extensions
Personal Stock Monitor can run simple standalone scripts, and specially formatted scripts can be installed as extensions. When scripts are installed as extensions, they are automatically loaded when Personal Stock Monitor starts. This allows them to do things such as installing event handlers that would otherwise not be possible in regular scripts.
How Extensions Work
In order for your script extensions to be loaded when Personal Stock Monitor starts, two things must happen. First, they must be wrapped in a simple XML document; second, they must be installed through the extension installer interface under the Tools menu.
The XML wrapper looks like this:
<pss_extension name="Hello World Sample" version="1.0">Sample Hello World Extension
<author email="support@dtlink.com" name="DTLink Software" url="http://www.dtlink.com" />
<script language="VBScript">
<![CDATA[
*** your script code goes here ***
]]>
</script>
</pss_extension>
<signature>
optional digital signature
</signature>
The XML wrapper briefly describes the extension in the installer interface and identifies you as the author. The extension code becomes part of a CDATA node in order to prevent the XML parser from interpreting tags incorrectly. The only restriction is that your script must not contain the "]]>" string that ends the CDATA nodes.
Extensions can optionally digitally signed in order to verify their authenticity for users. Personal Stock Monitor will test the extension signature before it is installed and will warn the user if there is no digital signature or if it does not match the extension. Oh the other hand, signed extensions will present with a nice dialog containing information about you and the extension. In either case the user will decide whether to allow the extension to be installed.
Once the extensions are installed, any code that is at the global scope of the script will be run when the extension is loaded at program startup. This part of the code will normally consist of initialization code that registers the necessary objects and event handlers with the host application.
Creating a Basic Extension
Before creating a basic extension I would recommend reviewing the Personal Stock Monitor object model documentation on the web site. Becoming familiar with this object model will make following the rest of this article much easire.
For this example we will create a basic extension that adds a menu item to the Tools menu and displays a message box when the menu is pressed. This requires us to define a class to be the menu event handler and register it with the application.
So let's start with a basic class to handle a menu event. If you have read the object model documentation you know that the menu handler is called OnMenuItemSelected(), so we start with this:
class HelloWorldHandlerClass
' menu event handler
public Function OnMenuItemSelected ( id )
If (id = menuId) Then
MsgBox "Hello, World", vbOKOnly
' set return value to indicate that menu selection was processed
OnMenuItemSelected = True
End If
end Function
Dim menuId
end Class
Now we have a class that we can use as a menu handler. Because there may be other extensions registered, we must first check whether the menu id matches our menu.
The next step is to register our handler class with the host application:
' get our event objects
Set EventManager = Application.GetObject("EventManager")
Set MenuManager = Application.GetObject("MenuManager")
Set Handler = new TestHandlerClass
' create the menu item
If Not MenuManager Is Nothing Then
' find the tools menu
Set MainMenu = MenuManager.MainMenu
Set ToolMenu = MainMenu.GetSubMenu(MainMenu.Find("Tools"))
' insert our menu item
If Not ToolMenu Is Nothing Then
Handler.menuId = ToolMenu.InsertItem(ToolMenu.ItemCount, "Hello World")
End If
End If
' register the menu handler
If Not EventManager Is Nothing Then
EventManager.RegisterHandlerMethod Handler, "OnMenuItemSelected"
End If
This section of code does a few things that are necessary for this extension to work. First, it gets references to the application objects and creates an instance of our menu handler object. Second, it finds the Tools menu and inserts the menu item. Note how the code saves the menu id of the menu item we created in the handler class. All of this should be pretty straighforward if you're familiar with Visual Basic or VBScript.
Lastly, we just need to create the XML wrapper for this extension like I showed above so that the extension can be installed properly. The completed extension is available here.
Finishing Up
Testing your extension is a matter of installing it under Personal Stock Monitor using the Extensions manager under the Tools menu. Extension management is based on version number, so once an extension is installed it can easily be updated in-place as long as don't move the xml file.