Here is a solution to write stand-alone scripts for Smart Office. Stand-alone scripts are interesting to create mini applications in Smart Office like widgets, or to create full blown applications like composite applications.
A stand-alone script runs independently of an M3 program, in its own instance, eventually with its own user interface. Whereas a regular script runs as part of an M3 program, for example inside CRS610.
I will illustrate how to write a stand-alone script by creating a Tiling Window Manager widget. It’s a continuation of my previous post on How to tile windows in Smart Office. The result will look like this:
Make sure to read my disclaimer before trying this as I’m using non-public APIs.
First, I will create an empty window with an icon in the Taskbar:
var task = new Task(new Uri('jscript://')); task.VisibleName = 'Hello World'; var runner = DashboardTaskService.Current.LaunchTask(task, null); runner.Status = RunnerStatus.Running; var host = runner.Host; host.HostTitle = 'Hello World'; host.Show();
The result will look like a regular Smart Office window, albeit empty:
Then, I will use HostType.Widget to change the appearance of the window and make it look like a small widget:
var task = new Task(new Uri('jscript://')); task.AllowAsShortcut = false; task.VisibleName = 'Tiling Window Manager'; var runner = DashboardTaskService.Current.LaunchTask(task, HostType.Widget); runner.Status = RunnerStatus.Running; var host = runner.Host; var wrapPanel = new WrapPanel(); host.HostContent = wrapPanel; host.HostTitle = 'Tiling Window Manager'; host.ResizeMode = ResizeMode.NoResize; host.Show(); host.Width = 221; host.Height = 85;
The host’s Width and Height must be set after host.Show().
The result will look like a widget:
Then, I will add three buttons to the widget:
var buttons: String[] = [' ← ', 'Tile', ' → ']; for (var i in buttons) { var btn = new Button(); btn.Content = buttons[i]; btn.Width = double.NaN; // auto width btn.Margin = new Thickness(3, 0, 3, 0); // ltrb btn.Padding = new Thickness(7, 0, 7, 0); // ltrb wrapPanel.Children.Add(btn); } wrapPanel.HorizontalAlignment = HorizontalAlignment.Center;
The result will finally look like the desired widget:
Then, I will add an event handler for the buttons:
btn.add_Click(OnClick); ... function OnClick(sender: Object, e: RoutedEventArgs) { if (sender.Content.Equals(' ← ')) { // } else if (sender.Content.Equals('Tile')) { // } else if (sender.Content.Equals(' → ')) { // } }
Then, I will add the functions for tiling and shifting the visible windows horizontally on the screen.
var shift = 0; ... /* Tiles the specified windows horizontally accross the screen. */ function tileInstances(instances: ArrayList) { this.shift = 0; for (var i = 0; i < instances.Count; i++) { tileInstance(instances[i], i, instances.Count); } } /* Shifts the specified windows horizontally, to the left or to the right. */ function shiftInstances(instances: ArrayList, increment: int) { this.shift += increment; for (var i = 0; i < instances.Count; i++) { var n: int = instances.Count; var j: int = (((i + this.shift) % n) + n) % n; // fix the JavaScript modulo bug tileInstance(instances[i], j, instances.Count); } }
Then, I will deploy the script on the server.
For Grid installations the deploy folder is somewhere like:
\\hostname\d$\Lawson\LifeCycleManager\Service\XYZ\grid\TST\applications\LSO_M3_Adapter\webapps\mne\jscript\
For non-Grid installations the deploy folder is somewhere like:
\\hostname\d$\IBM\WebSphere7\AppServer\profiles\MWPProfile\installedApps\MWPProfileCell\MWP_EAR.ear\MNE.war\jscript\
Then, I will add a shortcut to the Smart Office Canvas to launch the script with this special syntax:
mforms://_runscript?name=TilingWindowManager
My final script is:
import System;
import System.Collections;
import System.Windows;
import System.Windows.Controls;
import Mango.Services;
import Mango.UI.Core;
import Mango.UI.Services;
import MForms;
import Mango.UI;
/*
Thibaud Lopez Schneider
Infor
May 7, 2012
This script opens a widget to tile and shift the visible windows horizontally in Smart Office.
*/
package MForms.JScript {
class TilingWindowManager {
var shift = 0;
public function Init(element: Object, args: Object, controller : Object, debug : Object) {
try {
var task = new Task(new Uri('jscript://'));
task.AllowAsShortcut = false;
task.VisibleName = 'Tiling Window Manager';
var runner = DashboardTaskService.Current.LaunchTask(task, HostType.Widget);
runner.Status = RunnerStatus.Running;
var host = runner.Host;
host.HostContent = CreateWindow();
host.HostTitle = 'Tiling Window Manager';
host.ResizeMode = ResizeMode.NoResize;
host.Show();
host.Width = 221;
host.Height = 85;
} catch(ex: Exception) {
ConfirmDialog.ShowErrorDialogWithoutCancel(ex.GetType(), ex.Message + '\n' + ex.StackTrace, null);
}
}
function CreateWindow() {
var wrapPanel: WrapPanel = new WrapPanel();
var buttons: String[] = [' ← ', 'Tile', ' → '];
for (var i in buttons) {
var btn = new Button();
btn.Content = buttons[i];
btn.Width = double.NaN; // auto width
btn.Margin = new Thickness(3, 0, 3, 0); // ltrb
btn.Padding = new Thickness(7, 0, 7, 0); // ltrb
wrapPanel.Children.Add(btn);
btn.add_Click(OnClick);
}
wrapPanel.HorizontalAlignment = HorizontalAlignment.Center;
return wrapPanel;
}
/*
Returns a list of the visible windows.
*/
function getVisibleInstances() {
var instances = MainController.Current.GetInstances();
var visibleInstances = new ArrayList();
for (var instance in instances) {
var window: EmbeddedHostWindow = instance.Host.Implementation;
if (window.Visibility == Visibility.Visible) {
visibleInstances.Add(instance);
}
}
return visibleInstances;
}
/*
Tiles the specified window at the specified index relative to the specified count of windows.
*/
function tileInstance(instance: InstanceController, i: int, count: int) {
var window: EmbeddedHostWindow = instance.Host.Implementation;
window.Width = instance.ParentWindow.Width / count;
window.Height = instance.ParentWindow.Height;
DashboardService.Window.SetPosition(new Point(window.Width * i, 0), window);
}
/*
Tiles the specified windows horizontally accross the screen.
*/
function tileInstances(instances: ArrayList) {
this.shift = 0;
for (var i = 0; i < instances.Count; i++) {
tileInstance(instances[i], i, instances.Count);
}
}
/*
Shifts the specified windows horizontally, to the left or to the right.
*/
function shiftInstances(instances: ArrayList, increment: int) {
this.shift += increment;
for (var i = 0; i < instances.Count; i++) {
var n: int = instances.Count;
var j: int = (((i + this.shift) % n) + n) % n; // fix the JavaScript modulo bug
tileInstance(instances[i], j, instances.Count);
}
}
/*
Handles the click on the buttons.
*/
function OnClick(sender: Object, e: RoutedEventArgs) {
try {
var visibleInstances = getVisibleInstances();
if (visibleInstances.Count > 0) {
if (sender.Content.Equals(' ← ')) {
shiftInstances(visibleInstances, -1);
} else if (sender.Content.Equals('Tile')) {
tileInstances(visibleInstances);
} else if (sender.Content.Equals(' → ')) {
shiftInstances(visibleInstances, +1);
}
}
} catch(ex: Exception) {
ConfirmDialog.ShowErrorDialogWithoutCancel(ex.GetType(), ex.Message + '\n' + ex.StackTrace, null);
}
}
}
}
Voilà!
This solution showed how to create a stand-alone script in Smart Office, how to create a widget-like script, and how to tile and shift windows.
If you liked this solution, I invite you to subscribe to this blog.
Special thanks to Peter A.J. for the original help.









































