Geiger's Counter

Stuff I do with Lawson Smart Office

How to create a customized hotkey function

with one comment

How to create a customized hotkey function for M3 programs

Thibaud struck back here with some useful input validation examples, so I thought I’d finally wake from my slumber and contribute something related to that post from the key stroke angle of it.  The example was developed using Smart Office version 9.1.2.44.1 (don’t worry, I’ll catch up soon)

DISCLAIMER: Regarding the hotkey choice, if there’s some obscure or non-obscure function already hoarding ctrl+d tied to something nasty like a standard M3 delete function and you end up wiping out an account, don’t shoot the messenger.  If you have any doubts about potentially active hotkeys, make sure you’re taking this for a spin in your development environment.  Debate and hotkey best practice recommendations are welcome.

  1. mforms://yourFavoriteM3Form
  2. mforms://jscript
  3. copy/paste code sample text into JScript designer window
  4. click compile
  5. click run
  6. set focus on the yourFavoriteM3Form window
  7. leftctrl+d (noting disclaimer above)
import System.Windows;
import System.Windows.Controls;
import System.Windows.Input;
import Mango.UI;
import MForms;

package MForms.JScript {
	class HotKey {
		var instanceController : Object;
		var contentPanel : Grid;
		
		public function Init(element: Object, args: Object, controller : Object, debug : Object) {
			instanceController = controller;
			contentPanel = instanceController.RenderEngine.Content;
			// Add an event to the M3 Content window to detect any time the user releases a key.
			contentPanel.add_KeyUp(OnKeyUp);
		}
		/* Event Handler Delegate Funtion
		Do something if user has the LeftCtrl key pressed while releasing the D key.
		*/
		public function OnKeyUp(sender : Object, e : KeyEventArgs) {
			if (Keyboard.IsKeyDown(Key.LeftCtrl) && e.Key == Key.D) {
				ConfirmDialog.ShowInformationDialogNeverHidden("A message from the past", "You've got 'D'!");
				// Do something else here (use your imagination)
			}
		}
	}
}
Advertisements

Written by geigerzcounterz

July 7, 2012 at 12:21 AM

Posted in Uncategorized

Tagged with

How to get the user password in a Smart Office script

with 4 comments

By Thibaud Lopez Schneider – April 11, 2012

Here is a solution to get the Lawson Smart Office user’s password with a Personalized Script.

This solution is interesting in scenarios where at runtime we need the current user’s password to dynamically integrate to external systems, for example to connect to a network drive, to connect to a secure website, to execute SQL, to call web services, etc. Also, this solution is interesting to call M3 API or to trigger PFI flows for early versions of Lawson Smart Office that don’t have those native adapters; late versions of Smart Office have native adapters to call M3 API and to trigger PFI flows without the need to obtain the user’s password.

It’s important to be careful with this solution to not transmit the password in clear text over insecure networks.

Also, note that this solution is not part of the official Smart Office API. Thus, the code can break with upgrades of Smart Office. To ensure the code doesn’t break, use only the official API of the Smart Office Developer’s Guide.

Here’s the source code of the solution:

import System;
import Mango.Services;

package MForms.JScript {
	class Test extends MarshalByRefObject {
		public function Init(element: Object, args: Object, controller : Object, debug : Object) {
			var userName : String;
			var password : String;
			ApplicationServices.UserContext.RequestCredentials("M3", "MForms", &userName, &password);
			debug.WriteLine(userName + ":" + password);
		}
	}
}

It’s interesting to note that with JScript.NET we can pass parameters by reference, by extending MarshalByRefObject and by using the ampersand character in front of a parameter, as we can do in C as in C#.

Here is a screenshot of the result:

Thanks to karinpb for the solution in C#, and to geiger for the solution in JScript.NET, and thanks again to geiger for letting me post his solution on his blog.

Thibaud Lopez Schneider

Written by thibaudatwork

April 11, 2012 at 12:30 AM

Posted in Uncategorized

Tagged with ,

Detecting change mode cheat

leave a comment »

How to detect the entry mode of an M3 Form.  Version 2.

Having reviewed a post about Thibaud about this topic here, I thought a of a simplified mode detection method as my question was simply of button “To display or not to display”.  In optical review of the display mode vs edit mode of a form, I noticed that the background color of the textboxes were white in edit mode, while light grey in display mode.  Using this to my advantage, I created a method to get the background color of a text box and thereby also make a fairly reliable judgement call about the form’s mode.  Certainly, this will not be sufficient detection in some cases, i.e. in the event a user adds a conditional color to the validate field, etc., but so far it seems to fit the bill for narrowly scoped use. The example was developed using Smart Office version 9.1.2.44.1

import System.Windows;
import System.Windows.Controls;
import System.Windows.Media;
import MForms;

package MForms.JScript {
	class EditableTextBoxValidator {
		// M3 InstanceController Interface object
		var instanceController : InstanceController;
		// Grid content object
		var content : Grid;

		public function Init (element: Object, args: Object, controller : Object, debug : Object) {

			var xxyyyyTextBox : TextBox;
			// Get the M3 instance controller interface.
			instanceController = controller;
			// Get the M3 Grid content object allowing for manipulation of Elements on the MForm.
			content = instanceController.RenderEngine.Content;
			// Where XX is the field prefix and YYYY is the field name e.g. WHWHSL
			xxyyyyTextBox = ScriptUtil.FindChild(content, "XXYYYY");
			if (GetBackgroundColor(xxyyyyTextBox) == "#FFFFFFFF") {
				MessageBox.Show("MForm IS in edit mode. Do something?");
			} else {
				MessageBox.Show("MForm is NOT in edit mode. Do something?");
			}
		}

		public function GetBackgroundColor(inputTextBox : TextBox) : String {
			var backgroundColorBrush : SolidColorBrush;
			var backgroundColor : Color;
			var color : String;

			backgroundColorBrush = inputTextBox.Background;
			backgroundColor = backgroundColorBrush.Color;
			color = backgroundColor.ToString();
			return color;
		}
	}
}

Written by geigerzcounterz

March 21, 2012 at 2:19 PM

Posted in Uncategorized

Tagged with ,

Handling Business Engine messages

with 4 comments

How to check for the existence of an M3 Business Engine program message before executing a JScript function

Since I have slowly worked my way up to the need for solving this particular dilemma, I thought I would share my outcome.  In particular, I developed a type of JScript exit function which was to execute after the success a certain Business Engine operation.  Checking the success of a that Business Engine operation happens to be the tricky part.  As any given Business Engine program may issue various transaction messages (error, informational, confirmation warning, etc…), one cannot be sure it is safe to run a JScript exit function without first checking the Business Engine transaction message.  I used the standalone JScript code shown below as the starting template to determine if I could detect a Business Engine message in a suitable way.  From there I was able to merge the needed parts of this example into my exit function, so that I could handle the Business Engine message appropriately with my JScript exit function.  The example was developed using Smart Office version 9.1.2.44.1

import System;
import System.Text;
import System.Windows;
import System.Xml;
import MForms;
import MForms.Runtime;

package MForms.JScript {
	class CheckRequestCompletedResponse {

		var instanceController : Object;

		public function Init(element: Object, args: Object, controller : Object, debug : Object) {
			// Initialize the MForms InstanceController interface.
			instanceController = controller;
			// Create a RequestCompleted event handler.
			instanceController.add_RequestCompleted(OnRequestCompleted);
		}

		// This function is an event handler for OnRequesting events.
		public function OnRequestCompleted(sender : Object, e : RequestEventArgs) {
			var response : Response; // Mforms.Runtime.Response
			var messageXmlNode : XmlNode;
			var message : String;
			var responseText : String;
			var lineFeed : String = Environment.NewLine;
			// Remove the RequestCompleted after the function has triggered
			instanceController.remove_RequestCompleted(OnRequestCompleted);
			response = instanceController.Response;
			// Parse the transaction's XML response to determine if a <Root><ControlData><Msg> node exists.
			messageXmlNode = response.Content.SelectSingleNode("Root/ControlData/Msg");
			message = messageXmlNode.InnerText
			if (messageXmlNode != null) {
				MessageBox.Show("The program would like to tell you something:" + lineFeed + lineFeed + message);
				responseText = GetResponsePropertyResults(response);
				MessageBox.Show("More info about what the program just told you:" + lineFeed + lineFeed + responseText);
			} else {
				MessageBox.Show("The program has nothing to share with you.  No news is good news.");
			}
		}

		function GetResponsePropertyResults(response : Response) : String {
			var stringBuilder : StringBuilder = new StringBuilder();
			stringBuilder.AppendLine(response.GetType().GetProperty("Content").Name + ": " + response.Content);
			stringBuilder.AppendLine(response.GetType().GetProperty("ExecutionTime").Name + ": " + response.ExecutionTime);
			stringBuilder.AppendLine(response.GetType().GetProperty("Header").Name + ": " + response.Header);
			stringBuilder.AppendLine(response.GetType().GetProperty("IID").Name + ": " + response.IID);
			stringBuilder.AppendLine(response.GetType().GetProperty("IsDialog").Name + ": " + response.IsDialog);
			stringBuilder.AppendLine(response.GetType().GetProperty("IsProgramRunning").Name + ": " + response.IsProgramRunning);
			stringBuilder.AppendLine(response.GetType().GetProperty("Request").Name + ": " + response.Request);
			stringBuilder.AppendLine(response.GetType().GetProperty("Result").Name + ": " + response.Result);
			stringBuilder.AppendLine(response.GetType().GetProperty("ResultCode").Name + ": " + response.ResultCode);
			stringBuilder.AppendLine(response.GetType().GetProperty("SID").Name + ": " + response.SID);
			stringBuilder.AppendLine(response.GetType().GetProperty("RawContent").Name + ": " + response.RawContent);
			return stringBuilder.ToString();
		}
	}
}

Example of the request XML which is parsed within the JScript
Transaction response XML

Written by geigerzcounterz

February 27, 2012 at 4:36 PM

Posted in Uncategorized

Tagged with ,

These might be the droids you’re looking for.

with 4 comments

Written by geigerzcounterz

January 24, 2012 at 6:39 PM

Posted in Uncategorized