With the addon connector you can connect your own addon to beas.
Example:
Create an AddOn for SAP Business One and use the SAP UI Interface.
Problem:
•This interface does not allow other connected AddOns to communicate with your AddOn.
•beas uses its own windows and an addon cannot use SAP UI interface to check beas events or to manipulate the beas front end.
The window event connector creates a bidirectional interface between the addon and beas.
No additional tools or objects are needed, the Windows Standard System can be used.
With the connector all beas window properties can be manipulated and beas script can be executed in the application.
For example, buttons, functionality on a button, work orders, time receipt and lot of more can be created.
To understand the concept, download an example.
To use the Test WindowEvent Connector:
1. Beas must be started only once.
2. Download and extract the example and execute beasAddonConnectorExample.exe.
3. Click Connect.
4. Insert a beas script on left side.
Example for testing WindowEvent Connector // create a variable, make a loop and add number 1-10 in brackets |
5. Disable "Return Result". This returns only 1 or 0 and it is not required.
6. Click on "Execute Script".
The result is displayed.
8. Click on "Disconnect".
Beas can also communicate with the AddOn.
app=external=<YourAddOnName>=<return text>
Insert this to beas directly, to inform the addon of special events or you can send this commands to beas. See first example:
To insert a button use the form loaded event. Insert the button with the function. 1.Name of your AddOn: MyAddOn a.In the form, insert an event, that you want to send to the AddOn. b.Check the event on the AddOn. If you get the "ResourceFormLoaded" string, you can send follow script to create a button: If the user clicks this button, the AddOn receives the "ResourceFormButtonClicked" String. 2.Execute the function. |
In this example we are going to create a button in a beas window (using a simple beas script) and this button will send a message to connected external AddOn and it will execute an external functionality.
1.Open Screen where you want to add the button (Operation Catalog screen for example) and go to "Extension for clients" option. 2.Add following code to send the message from Beas to an external App:
windowevent open
"MyAddOn" --> Is the name of the external Addon you registered in the connection to beas command (app=external=register=handle=XXX<tab>name=MyAddOn<tab>subscribe=Y)
3. Now you have to modify your "WndProc" function to catch this message:
protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == 1025) { is_receipt += char.ConvertFromUtf32(m.WParam.ToInt32()); is_receipt = is_receipt.ToLower(); if (is_receipt.Length >= 9) { string strcheck = is_receipt.Substring(is_receipt.Length - 9); if (strcheck == "[execute]") { string strcommand = is_receipt.Substring(0, is_receipt.Length - 9); if (strcommand.StartsWith("welcome")) { m_strMsg = "Beas is connected"; } else if(strcommand.StartsWith("id_001")) { //We cannot execute SAP commands directly because this event is fired by "BEAS Addon" and this addon is executed in a different //Thread than SAP, if you want to send information to SAP then easy way is throught a "Timer" (There are many other options). //For this example I save my message in a temp variable and the timer will send the message to SAP. m_strMsg = strcommand; } is_receipt = ""; } } } }
4. It is important to understand when you receive events from Beas AddOn context of this Application is not the same than SAP UI context, it means that both applications are running in different threads, if you receive a message from beas and then you try to modify UI of SAP directly you will receive a error message like this:
System.Runtime.InteropServices.COMException: 'An outgoing call cannot be made since the application is dispatching an input-synchronous call. (Exception from HRESULT: 0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL))'
To avoid this tipical issue you have to update UI object using the same thread than connection to SAP UI was created, the easy way to do this is using a "Timer", you have to save the message in a temp string variable and then you process the message in the "Timer_Tick" event of a created timer.
5. Modify your form to add a Timer and implement Timer Tick event
private void timer1_Tick(object sender, EventArgs e) { if (m_strMsg != "") { //m_sbo.SBO_Application.StatusBar.SetText(m_strMsg, SAPbouiCOM.BoMessageTime.bmt_Short, SAPbouiCOM.BoStatusBarMessageType.smt_Success); m_sbo.SBO_Application.MessageBox(m_strMsg, 1, "Ok", "", ""); m_strMsg = ""; } }
|
SAP can be started multiple times. Accordingly, each AddOn is startet multiple times. Make sure that you communicate only with an AddOn that is active in the same session. •Determine the session number through SAP-SDK using the application.appid property. •Event from beas listining and your window: 1025 •Send register string to beas:
•Name = Your AddOn Name •With the SendMessageToBeas command every beasscript command can be sent to beas.
Subscribe Definnition
|
Return a value (for example, a value from a column): "[handle=<your windowhandle>]itemcode=<itemcode>/itemname=<itemname>[executevalue]"
[handle=x] defines the window handle, on which beas sends the result. beas replaces all placeholders.
Execute a beas command: "your beas script[execute]" executes the script in beas systemwindow "your beas script[executew]" executes the script in the current window
A simpler method is to use this command: private void SendMessageToBeas(int hwndBeas, Boolean bActivewindow, string strmessage, Boolean bReturnResult)
With a parameter type of execution can be defined. |
Example of communication between beas and an external C# applicationWindows API declarations: /// <summary> /// The FindWindow API /// </summary> /// <param name="lpClassName">the class name for the window to search for</param> /// <param name="lpWindowName">the name of the window to search for</param> /// <returns></returns> [DllImport("User32.dll")] public static extern Int32 FindWindow(String lpClassName,String lpWindowName);
/// <summary> /// The SendMessage API /// </summary> /// <param name="hWnd">handle to the required window</param> /// <param name="msg">the system/Custom message to send</param> /// <param name="wParam">first message parameter</param> /// <param name="lParam">second message parameter</param> /// <returns></returns> [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);
// Function to connect to beas
private void btnGetWindows_Click(object sender, System.EventArgs e) { //Connect to beas is easy, we simple have to connect to "beaswindow:appid" appid--> SAP identifier m_hwndBeas = FindWindow(null, "beaswindow:0"); if (m_hwndBeas == 0) { //Maybe beas was started as Standalone app, we try to find this window m_hwndBeas = FindWindow(null, "beaswindow:single"); if (m_hwndBeas == 0) { MessageBox.Show(this, "Couldn't find Beas application.", "Test Beas Messages"); } } SendMessageToBeas(m_hwndBeas, false, "app=external=register=handle=" + this.Handle.ToString() + "<tab>name=B1UP<tab>subscribe=Y"); }
// Function to disconnect from beas
private void DisconnectFromBeas() { SendMessageToBeas(m_hwndBeas, false, "app=external=unregister=handle=" + this.Handle.ToString()); }
// Function to send a message to Beas. Now this function can receive result of executed operation
private void SendMessageToBeas(int hwndBeas, Boolean bActivewindow, string strmessage, Boolean bReturnResult) { string strMessageToSend = ""; if (bReturnResult == true) { strMessageToSend += "[handle=" + this.Handle.ToString() + "]"; }
strMessageToSend += strmessage;
if (bActivewindow == true) strMessageToSend += "[executew]"; else strMessageToSend += "[execute]";
//We have to send word by word for (int i=0; i< strMessageToSend.Length;i++) { SendMessage(hwndBeas, 1025, strMessageToSend[i], IntPtr.Zero); } }
// Function to request a value from beas
private void GetValueFromBeas(int hwndBeas, string strmessage) { string strMessageToSend = "[handle=" + this.Handle.ToString() + "]"; strMessageToSend += strmessage; strMessageToSend += "[execvalue]";
//We have to send word by word for (int i = 0; i < strMessageToSend.Length; i++) { SendMessage(hwndBeas, 1025, strMessageToSend[i], IntPtr.Zero); } }
// Function to process messages received from Beas
protected override void WndProc(ref Message m) { base.WndProc(ref m); if (m.Msg == 1025) { is_receipt += char.ConvertFromUtf32(m.WParam.ToInt32()); is_receipt = is_receipt.ToLower(); if (is_receipt.Length >= 9) { string strcheck = is_receipt.Substring(is_receipt.Length - 9); if (strcheck == "[execute]") { string strcommand = is_receipt.Substring(0, is_receipt.Length - 9); MessageBox.Show(strcommand); is_receipt = ""; } } } }
|