|
|
|
NOTE: This Design document is subject to change at any time. |
Plugins
One of the main advantages of developing applications using zApp is that every application automatically supports plugins.
Plugins are modules that either add new functionality to an application, or modify the existing application in some way (or both). For example, a plugin might add new menu items or toolbar items, or might rename existing items or change their icons.
Because plugins are implemented using the normal zApp ZML and ZXL files, a plugin can really do anything that a full application can. In fact, if written properly, it is very easy to use an existing application as a plugin for another application, making zApp development very modular.
For example, if you have a zApp program that implements a text editor, you might use this as a plugin for another application that needs an editor. Now you have a single editor source code that is shared by both applications.
zApp searches for plugins for a given application based upon the filenames of the application and plugins. If the application is called "APPNAME.ZML" or "APPNAME.ZXL" then zApp loads all files with names "APPNAME_.*" as plugin files. Plugin files can be either ZML (text) or ZXL (encrypted binary) files. If both exist for the same filename, then zApp will load the ZML text file. Plugins are loaded in alphabetical order. So, a plugin with a filename of "APPNAME_A.ZML" is loaded before "APPNAME_B.ZML".
zApp uses filenames to load plugins because this is a very simple mechanism that allows plugins to simply be dropped into the same directory as the main application file. No registry changes or installation procedure is needed. However, the main application will need to be reloaded in order to load the plugin. There is no way to load a plugin dynamically while an application is running. This restriction is mainly due to the powerful ways in which a plugin can alter an application.
Adding new features
To add new features to an application via a plugin, just write the plugin as if it were a normal zApp application. The plugin can create Windows, Toolbars, Actions, and anything that a normal application can. Because the plugin is loaded into the same framework as the main application, any existing objects or scripting routines can be referenced by the plugin.
For example, if the main application has an Edit box called "MyEdit" then any plugin is free to access this edit box by name. For security, you can prevent this by adding the LOCK attribute to the object in the main application.
The REF property
Any object in zApp can use a property called "REF" to "reference" an existing object with the specified name. This allows you to override properties of an existing object with an object in a plugin.
For example, if the main application has an Edit box named "MyEdit" with a caption of "Enter text:", then a plugin can override the properties of this edit box like this:
<EDIT ref='MyEdit' caption='New caption'/>
Whenever zApp sees a REF property, it looks for an existing object with that name. If this object is found, then its properties are overridden by any new values specified. So, in the above example, the plugin has changed the caption of the edit box in the main application from "Enter text:" to "New caption". Again, specifying the LOCK property for the edit box in the main application can prevent these changes from being made by a plugin.
In addition to using REF, just using the normal NAME property can have the same effect. Since all objects in zApp must have a unique name, using the NAME property and giving the name of an existing object will override the existing object rather than creating a new object.
The zApp searches for an object from the REF property, it first searches within the scope of the current object. For example, consider the following plugin code:
Code: |
<WINDOW ref="Main">
<EDIT ref='MyEdit' caption='New caption'/>
</WINDOW> |
In this case, zApp searches for an existing global window called "Main" and then searches for an edit box called "MyEdit" within this "Main" window. An edit box with the same name in a different window is ignored. Only the edit box in the "Main" window is overridden.
Menus and Toolbars
One of the most common modifications made by a plugin is to add new menu items or toolbar buttons to the application. The basic method for doing this is simple:
Code: |
<TOOLBAR ref="MainToolbar">
<ITEM Name="NewItem" Caption="New"/>
</TOOLBAR> |
In this example, zApp searches for an existing global toolbar named "MainToolbar". If found, then the toolbar button called "NewItem" is added to the toolbar.
This works fine, but zApp also gives you methods for better controlling where in the toolbar or menu your new item is added. By default, new items are just added to the end of the toolbar or menu. But each object within a toolbar or menu can use the properties BEFORE or AFTER to control where the new item is placed.
The value of the BEFORE or AFTER property is a string list of existing item captions. For example, consider the following main application menu:
Code: |
<TOOLBAR Name="MainMenu">
<MENU caption='&File'>
<ITEM action='_FileOpen'/>
<ITEMSEP/>
<ITEM action='_FileExit'/>
</MENU>
<MENU caption='&Edit'>
<ITEM action='_EditCut'/>
<ITEM action='_EditCopy'/>
<ITEM action='_EditPaste'/>
</MENU>
</TOOLBAR> |
This is a typical main menu with File and Edit submenus. The File submenu has an Open item, followed by a separator, followed by the Exit item.
Now, in our plugin, we want to add a new item to this main menu, called "Save", but we want this item added just after the existing Open item. To do this in our plugin, we would use the following code:
Code: |
<TOOLBAR ref="MainMenu">
<ITEM action='_FileSaveAs' after='File|Open'/>
</TOOLBAR> |
We have used the AFTER property and given a value of "File|Open". So, zApp looks within the current toolbar for the "File" menu, then it looks within the "File" menu for the "Open" item. If this is found, then our new item is inserted after the item that was found.
When searching for menu and item captions, the & character used to create an underlined hotkey is ignored, and any dots "." are also ignored. So, the above code works even though the File menu has the caption "&File" and the Open item has the caption "Open..."
When overridding existing menu and toolbar items, you can use the same caption string list syntax in the REF property if you desire. This allows you to reference existing items by their caption values instead of by their name since in many cases existing menu and toolbar items do not have specific names.
Finally, you can use both the REF and BEFORE/AFTER properties to move an existing item to a new location in the toolbar or menu. If you specify an empty string for the BEFORE or AFTER properties, then the toolbar or menu item is removed.
Plugin security
As mentioned previously, you can use the LOCK property in any object to prevent it from being overridden by any plugin. You can also use this in your plugin to prevent your new functions from being overidden by other plugins.
However, only use LOCK when absolutely necessary. Since the main advantage of zApp applications is their ability to be customized and extended by the end user, using LOCK prevents such customization.
As an additional security feature, you can also encrypt your plugin files. Instead of distributing the text ZML file, you can encrypt your plugin to a ZXL file using the Pro (Developers) edition of zApp, then only distribute the binary ZXL file. If you distribute ZML text files, they can only be loaded an used by end users that have purchased the zApp User edition. If you distribute binary ZXL files, then any user can load them using the free zApp Runtime version.
Regardless of whether your plugin or application uses the encrypted ZXL file or the text ZML file, you can still create a plugin and reference existing objects in the application or plugin.
This is a very powerful combination. You can protect the intellectual property of your plugin by encrypting it, and yet end-users can still customize the application and your plugin.
zApp uses this feature itself. The Integrated Development Environment (IDE) included with the zApp Pro version is actually a zApp application itself. And the plugin that adds the feature for encrypting your ZML file into a ZXL file is distributed as an encypted ZXL plugin for the IDE. In addition, the encryption plugin is licenced (using eLicense) so that only users that have purchased the zApp Pro license can even load this plugin. And yet, even with all of this security and protection, end users could still modify the Encrypt item added by the plugin by changing it's caption or icon, or moving it to a different position in the toolbar.
Overridding Scripts
When overriding properties of existing components, one property is treated differently: the SCRIPT property. If you try to override the SCRIPT property of an existing object, your new script is simply appended to the end of the current script. This allows you to add new features to existing scripts without actually being able to destroy or modify the existing script routines. |
|