Client side scripting

Share your TSPlus experience ad feedback on mobile platforms using our state of the art HTML5 RDP client!
Post Reply
247Oversight
Posts: 3
Joined: Tue Jul 05, 2016 1:06 pm

Client side scripting

Post by 247Oversight » Tue Jul 05, 2016 8:27 pm

I have a project for our service tech. I need to access the GPS location from smart phones and tablets.
What is the process to set up client side scripting with Java or HTML5 ?
Thanks for your help.

Steve C.

juwagn
Site Admin
Posts: 239
Joined: Wed Oct 15, 2014 8:25 pm

Re: Client side scripting

Post by juwagn » Wed Jul 06, 2016 5:47 pm

Hello,

you can add own scripts according to this example.
1. locate and open
www\software\html5\settings.js

2. look for

Code: Select all

W.customerScripts = { 0: "../custom1.js" }; //example
                         // { 0: "../custom1.js", 1: "../custom2.js" };  // "../*" is web root
                         //Important notice: the third part JavaScripts and any issues/incompatibilities caused by it's usage are not covered by support and any help on it will be discarded!


4. save settings.js

5. save your customer script as example under www\custom1.js

Now you are free to use your own scripts...
But that step will make no sense, if you can not communicate with session, therefore...

Are you conform with AutoIt? If not, well, you have to learn it, since following example is in Autoit.
It is easy to compile to exe with AutoIt (you will have to google for it)

Code: Select all

;////code server.au3 start
#NoTrayIcon
#include <WindowsConstants.au3>
Global $versionNum = 3;

Global $ExitOnFirstMessage = False;
       ;//False means, the process will run permanently in listening mode and may receive messages
      ;//True means, the process will send the message to browser only one time and than exit immediatelly
       ;//never send persistent _sendPersistentMessage when $ExitOnFirstMessage = True

Global $ChannelCustomName = "WebIMECustom1";
       ;//The unique name of this program that may be accessed from parent process called by browser

;//main body
If $ExitOnFirstMessage = False Then
 If _SingletonPID(@ScriptName & $ChannelCustomName, 1) <> 0 Then
   MsgBox(0, 'Error!', 'Same process ' & $ChannelCustomName & ' already exists, exit now!', 5)
   Exit;
 EndIf
Else
 Local $ra = Random(1, 1234567890, 1);
 While _SingletonPID(@ScriptName & $ra & $ChannelCustomName, 1) <> 0
   $ra = Random(1, 1234567890, 1);
 WEnd
 $ChannelCustomName = $ra & $ChannelCustomName;
EndIf

Global $hChild = GUICreate($ChannelCustomName)
Global $hMainWnd = WinGetHandle("WebIMEGUIChannel")
Global $Succeed = 0

While $hMainWnd = 0 And $Succeed < 4
   Sleep(3000)
   $Succeed = $Succeed + 1
   $hMainWnd = WinGetHandle("WebIMEGUIChannel")
WEnd

If $hMainWnd <> 0 Then
  GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA_ReceiveData")
  GUISetState(@SW_HIDE)

  $Succeed = 0;

  Local $data = "";

  ;//you can add own functions being available inside JavaScript scope via settings.js > W.customerScripts = { }; //read important notices inside settings.js regarding W.customerScripts

  If $ExitOnFirstMessage = False Then
    ;//that is only example of possible usage, this data will be sent persistently and sendmsg.exe will listen for incoming commands to this custom channel process
    ;//that example will place icons in browser, in menu with back caller to this process to process arrived messages here with _handleData
    $data = $data & " (function() { " & @CRLF
    $data = $data & "   var window = document.defaultView || document.parentWindow; " & @CRLF
    $data = $data & "   var channelCustomName = '" & $ChannelCustomName & "'; " & @CRLF
    $data = $data & "   var userMessage = 'some user string'; " & @CRLF
    ;//$data = $data & "   window.ChannelCustomName = channelCustomName; " & @CRLF

    $data = $data & "   window.sendMyMessageBack = function(do_what) { " & @CRLF
    $data = $data & "     var messageBack = ""what ever you did""; " & @CRLF
    $data = $data & "     if(channelCustomName && channelCustomName.length > 0) { " & @CRLF
    $data = $data & "       W.sendChannelCustom(channelCustomName, messageBack); " & @CRLF
    $data = $data & "     } " & @CRLF
    $data = $data & "   }; " & @CRLF
    $data = $data & "   alert('Listening mode\r\nAfter clicking OK the message ""' + userMessage + '"" \r\nwill be sent back to customer channel:\r\n' + channelCustomName); " & @CRLF
    $data = $data & "   W.sendChannelCustom(channelCustomName, userMessage); " & @CRLF
    $data = $data & " })(); " & @CRLF
  Else
    ;///won't do anything
  EndIf


  If $ExitOnFirstMessage = False Then
    _sendPersistentMessage($data) ;//in permanent listening mode to force the rdp channel to replay the data when browser window was refreshed, so use peristent message
                           ;//if wishing to send commands once use _sendSingleMessage with $ExitOnFirstMessage = True
  Else
    _sendSingleMessage($data); //when message will be sent only once, do not store it persistently to be replayed on browsers refresh, so use single message
  EndIf
Else
   MsgBox(0, "Message error!", "Channel process listener not found!", 5)
   Exit;
EndIf

If $ExitOnFirstMessage = True Then
  While 1
   SleepOWN(2000)
   If $Succeed = 1 Then Exit;
  WEnd
Else
  While 1
   SleepOWN(2000)
  WEnd
EndIf

Exit;

Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ;
    ;////
    Local $inSend = DllCall("user32.dll", "BOOLEAN", "InSendMessage");
    If $inSend[0] = 1 Then
      $inSend = DllCall("user32.dll", "BOOLEAN", "ReplyMessage", "uint", 1)
     ;// reply to parent webime.exe process immediatelly to not make it hanging while waiting for this function to return
     ;//it is Microsoft recommendation to process so, because if parent caller hangs because of waiting to return this function
     ;//it will cause both processes to hang, so to avoid that and allow parent process to continue working answer with ReplyMessage as fast as possible here
     ;//
     ;//PS: never remove this command, else you may block the webime.exe
     ;//however webime.exe uses timeout of 4 seconds and will not block forever, anyway answer with this ReplyMessage is good approach, so do not remove this command!
   EndIf
    ;////

    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    Local $received = DllStructGetData($tMsg, 1)

    If StringLeft($received, 1) = "3" Then
     $Succeed = 0;// just handle data without exit
     $received = StringTrimLeft($received, 1);
     _handleData($received)
    ElseIf $received = 0 Then
      $Succeed = 1
    EndIf
EndFunc

Func _handleData($data)
   MsgBox(0, "DATA ARRIVED", $data, 5)
   ;//handle your data here
EndFunc

Func WM_COPYDATA_SendData($hWnd, $sData)
   WM_COPYDATA_SendDataTimeout($hWnd, $sData, 4000)
EndFunc

Func WM_COPYDATA_SendDataTimeout($hWnd, $sData, $timeout)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
   Local $Max = 0
   $Succeed = 0
    While $Succeed <> 1 And $Max < 40
    $Max = $Max + 1
     Local $Ret = DllCall("user32.dll", "lresult", "SendMessageTimeout", "hwnd", $hWnd, "uint", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA), "uint", 0x0000, "uint", $timeout, "ptr*", 0)
    ;//SendMessageTimeout gets used, because when due some wrong programming of process that retrieves this message the function should continue at least after time out elapsed
    ;//however if program followed Microsofts recommendations and process replies with ReplyMessage to this call, this will continue as fast as possible
    ;//
    ;//PS: the parent webime.exe that represents the virtual channel follows Microsoft recommendations and replies as fast as possible to not make this function to hang
    ;//however timeout of 4 seconds is good approach anyway here
    $Succeed = $Ret[0];
    If $Succeed = 0 Then ;// 0 means failed or timed out
      SleepOWN(250)
    EndIf
    WEnd
    If $Succeed = 1 Then
     ;//Exit;
    Else
     MsgBox(0, "Error", "Waited more than 10 seconds for sending message!", 5);
    If $ExitOnFirstMessage = True Then Exit;
    EndIf
EndFunc

Func _sendSingleMessage($msg)
   $msg = "0" & $hChild & "@" & $msg
   WM_COPYDATA_SendData($hMainWnd, $msg)
EndFunc

Func _sendPersistentMessage($msg)
   If $ExitOnFirstMessage = True Then
      _sendSingleMessage($msg)
      Return
   EndIf
   $msg = "1" & $hChild & "@" & $msg
   WM_COPYDATA_SendData($hMainWnd, $msg)
EndFunc

Func _SingletonPID($sOccurenceName, $iFlag = 0)
   Local $hWnd = WinGetHandle($sOccurenceName)
   If @error Then
      AutoItWinSetTitle($sOccurenceName)
      $hWnd = WinGetHandle($sOccurenceName)
      ControlSetText($hWnd, '', ControlGetHandle($hWnd, '', 'Edit1'), @AutoItPID)
   Else
      If BitAND($iFlag, 1) Then
         Return Int(ControlGetText($hWnd, '', ControlGetHandle($hWnd, '', 'Edit1')))
      Else
         Exit -1
      EndIf
   EndIf
   Return 0
EndFunc   ;==>_SingletonPID

Func SleepOWN($time)
        Local $rWord = DllCall("User32.dll", "dword", "MsgWaitForMultipleObjectsEx", _
            "dword", 1, _
            "ptr", DllStructGetPtr($hChild), _
            "dword", $time, _
            "dword", 0x0040, _
            "dword", 0x6)
EndFunc
;////code server.au3 end
Save this snippet to server.au3 file, compile to exe, and execute inside session.
That was listening server example, once you start this server.exe (compiled au3) it will listen to messages from channel you send from browser.

Take attention at this part (I have commented it in script to disable)

Code: Select all

;***
    ;//$data = $data & "   alert('Listening mode\r\nAfter clicking OK the message ""' + userMessage + '"" \r\nwill be sent back to customer channel:\r\n ' + channelCustomName); " & @CRLF
    ;//$data = $data & "   W.sendChannelCustom('" & $ChannelCustomName & "', userMessage); " & @CRLF
;***
That is pure JavaScript part, that gets executed inside browser
In this example it gets first initial data, and than listens for incoming messages, after first initialisation you could add inside your www\custom1.js something like

Code: Select all

window.sendMyMessageBack = function(do_what) {
  ///do what ever you want here
  ///if(do_what == 1) { } etc..
  //
  var messageBack = "what ever you did";
  if("channelCustomName" in window &&  window.channelCustomName.length > 0) {
    W.sendChannelCustom(window.channelCustomName, messageBack);
  }
};
So to force the browser to send messages from inside session, make it also event driven, what I assume, you want to do here is next AutoIt snippet, almost equal to
server part but Global $ExitOnFirstMessage = True; also once it sends message, it exits immediatelly, also client version only.
Also as example save that snippet to client.au3 and compile to client.exe, and after you are sure, that server.exe runs, start client.exe.

Code: Select all

;////code client.au3 start
#NoTrayIcon
#include <WindowsConstants.au3>
Global $versionNum = 3;

Global $ExitOnFirstMessage = True;
       ;//False means, the process will run permanently in listening mode and may receive messages
      ;//True means, the process will send the message to browser only one time and than exit immediatelly
       ;//never send persistent _sendPersistentMessage when $ExitOnFirstMessage = True

Global $ChannelCustomName = "WebIMECustom1";
       ;//The unique name of this program that may be accessed from parent process called by browser

;//main body
If $ExitOnFirstMessage = False Then
 If _SingletonPID(@ScriptName & $ChannelCustomName, 1) <> 0 Then
   MsgBox(0, 'Error!', 'Same process ' & $ChannelCustomName & ' already exists, exit now!', 5)
   Exit;
 EndIf
Else
 Local $ra = Random(1, 1234567890, 1);
 While _SingletonPID(@ScriptName & $ra & $ChannelCustomName, 1) <> 0
   $ra = Random(1, 1234567890, 1);
 WEnd
 $ChannelCustomName = $ra & $ChannelCustomName;
EndIf

Global $hChild = GUICreate($ChannelCustomName)
Global $hMainWnd = WinGetHandle("WebIMEGUIChannel")
Global $Succeed = 0

While $hMainWnd = 0 And $Succeed < 4
   Sleep(3000)
   $Succeed = $Succeed + 1
   $hMainWnd = WinGetHandle("WebIMEGUIChannel")
WEnd

If $hMainWnd <> 0 Then
  GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA_ReceiveData")
  GUISetState(@SW_HIDE)

  $Succeed = 0;

  Local $data = "";

  ;//you can add own functions being available inside JavaScript scope via settings.js > W.customerScripts = { }; //read important notices inside settings.js regarding W.customerScripts

  If $ExitOnFirstMessage = False Then
    ;//that is only example of possible usage, this data will be sent persistently and sendmsg.exe will listen for incoming commands to this custom channel process
  Else
    ;//that is only example of possible usage, this data will be sent only once and sendmsg.exe will exit after sending the message
    $data = $data & " (function() { " & @CRLF
    $data = $data & "   var window = document.defaultView || document.parentWindow; " & @CRLF
    $data = $data & "   if(window.sendMyMessageBack) { window.sendMyMessageBack(1); } " & @CRLF
    $data = $data & " })(); " & @CRLF
  EndIf


  If $ExitOnFirstMessage = False Then
    _sendPersistentMessage($data) ;//in permanent listening mode to force the rdp channel to replay the data when browser window was refreshed, so use peristent message
                           ;//if wishing to send commands once use _sendSingleMessage with $ExitOnFirstMessage = True
  Else
    _sendSingleMessage($data); //when message will be sent only once, do not store it persistently to be replayed on browsers refresh, so use single message
  EndIf
Else
   MsgBox(0, "Message error!", "Channel process listener not found!", 5)
   Exit;
EndIf

If $ExitOnFirstMessage = True Then
  While 1
   SleepOWN(2000)
   If $Succeed = 1 Then Exit;
  WEnd
Else
  While 1
   SleepOWN(2000)
  WEnd
EndIf

Exit;

Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ;
    ;////
    Local $inSend = DllCall("user32.dll", "BOOLEAN", "InSendMessage");
    If $inSend[0] = 1 Then
      $inSend = DllCall("user32.dll", "BOOLEAN", "ReplyMessage", "uint", 1)
     ;// reply to parent webime.exe process immediatelly to not make it hanging while waiting for this function to return
     ;//it is Microsoft recommendation to process so, because if parent caller hangs because of waiting to return this function
     ;//it will cause both processes to hang, so to avoid that and allow parent process to continue working answer with ReplyMessage as fast as possible here
     ;//
     ;//PS: never remove this command, else you may block the webime.exe
     ;//however webime.exe uses timeout of 4 seconds and will not block forever, anyway answer with this ReplyMessage is good approach, so do not remove this command!
   EndIf
    ;////

    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    Local $received = DllStructGetData($tMsg, 1)

    If StringLeft($received, 1) = "3" Then
     $Succeed = 0;// just handle data without exit
     $received = StringTrimLeft($received, 1);
     _handleData($received)
    ElseIf $received = 0 Then
      $Succeed = 1
    EndIf
EndFunc

Func _handleData($data)
   MsgBox(0, "DATA ARRIVED", $data, 5)
   ;//handle your data here
EndFunc

Func WM_COPYDATA_SendData($hWnd, $sData)
   WM_COPYDATA_SendDataTimeout($hWnd, $sData, 4000)
EndFunc

Func WM_COPYDATA_SendDataTimeout($hWnd, $sData, $timeout)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
   Local $Max = 0
   $Succeed = 0
    While $Succeed <> 1 And $Max < 40
    $Max = $Max + 1
     Local $Ret = DllCall("user32.dll", "lresult", "SendMessageTimeout", "hwnd", $hWnd, "uint", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA), "uint", 0x0000, "uint", $timeout, "ptr*", 0)
    ;//SendMessageTimeout gets used, because when due some wrong programming of process that retrieves this message the function should continue at least after time out elapsed
    ;//however if program followed Microsofts recommendations and process replies with ReplyMessage to this call, this will continue as fast as possible
    ;//
    ;//PS: the parent webime.exe that represents the virtual channel follows Microsoft recommendations and replies as fast as possible to not make this function to hang
    ;//however timeout of 4 seconds is good approach anyway here
    $Succeed = $Ret[0];
    If $Succeed = 0 Then ;// 0 means failed or timed out
      SleepOWN(250)
    EndIf
    WEnd
    If $Succeed = 1 Then
     ;//Exit;
    Else
     MsgBox(0, "Error", "Waited more than 10 seconds for sending message!", 5);
    If $ExitOnFirstMessage = True Then Exit;
    EndIf
EndFunc

Func _sendSingleMessage($msg)
   $msg = "0" & $hChild & "@" & $msg
   WM_COPYDATA_SendData($hMainWnd, $msg)
EndFunc

Func _sendPersistentMessage($msg)
   If $ExitOnFirstMessage = True Then
      _sendSingleMessage($msg)
      Return
   EndIf
   $msg = "1" & $hChild & "@" & $msg
   WM_COPYDATA_SendData($hMainWnd, $msg)
EndFunc

Func _SingletonPID($sOccurenceName, $iFlag = 0)
   Local $hWnd = WinGetHandle($sOccurenceName)
   If @error Then
      AutoItWinSetTitle($sOccurenceName)
      $hWnd = WinGetHandle($sOccurenceName)
      ControlSetText($hWnd, '', ControlGetHandle($hWnd, '', 'Edit1'), @AutoItPID)
   Else
      If BitAND($iFlag, 1) Then
         Return Int(ControlGetText($hWnd, '', ControlGetHandle($hWnd, '', 'Edit1')))
      Else
         Exit -1
      EndIf
   EndIf
   Return 0
EndFunc   ;==>_SingletonPID

Func SleepOWN($time)
        Local $rWord = DllCall("User32.dll", "dword", "MsgWaitForMultipleObjectsEx", _
            "dword", 1, _
            "ptr", DllStructGetPtr($hChild), _
            "dword", $time, _
            "dword", 0x0040, _
            "dword", 0x6)
EndFunc

;////code client.au3 end
Technically you could completely avoid usage www\software\html5\settings.js -> W.customerScripts
and evaluate your functions on first server.exe(.au3) start, as example

Code: Select all

;//server.au3 start
****
    $data = $data & "   window.ChannelCustomName = channelCustomName; " & @CRLF
    $data = $data & "   window.sendMyMessageBack = function(do_what) { " & @CRLF
    $data = $data & "     var messageBack = ""what ever you did""; " & @CRLF
    $data = $data & "     if(""channelCustomName"" in window &&  window.channelCustomName.length > 0) { " & @CRLF
    $data = $data & "       W.sendChannelCustom(window.channelCustomName, messageBack); " & @CRLF
    $data = $data & "     } " & @CRLF
    $data = $data & "   }; " & @CRLF
****
;//server.au3 end
But that would make it hard to debug for you.
(remember under au3 some chars are escaped differently than by JavaScript, as example for Autoit for escaping " you must type it twice "")

PS: but unfortuantelly I can not give you aid on your code, because it is not covered by support. Any browser related issues are fully yours.

Sincerely yours, JW.
TSplus HTML5 and Java web engineer

247Oversight
Posts: 3
Joined: Tue Jul 05, 2016 1:06 pm

Re: Client side scripting

Post by 247Oversight » Wed Jul 06, 2016 10:23 pm

Thank you for your time and direction. I will start working on it.

juwagn
Site Admin
Posts: 239
Joined: Wed Oct 15, 2014 8:25 pm

Re: Client side scripting

Post by juwagn » Fri Jul 08, 2016 6:03 pm

Hello,

fixed some spellings errors and made the server.au3/client.au3 custom example script usage ready to use, also wished function gets evaled once from server.au3 instead from www\custom1.js
And client.au3 plays the role of event driver.
However you may pack as example the call of function window.sendMyMessageBack into setInterval and poll for changes of gps location, and only than send message back to server, or make it event driven on side of browser. So you could avoid usage of client.au3 too.

server.au3

Code: Select all

;////code server.au3 start
#NoTrayIcon
#include <WindowsConstants.au3>
Global $versionNum = 3;

Global $ExitOnFirstMessage = False;
       ;//False means, the process will run permanently in listening mode and may receive messages
      ;//True means, the process will send the message to browser only one time and than exit immediatelly
       ;//never send persistent _sendPersistentMessage when $ExitOnFirstMessage = True

Global $ChannelCustomName = "WebIMECustom1";
       ;//The unique name of this program that may be accessed from parent process called by browser

;//main body
If $ExitOnFirstMessage = False Then
 If _SingletonPID(@ScriptName & $ChannelCustomName, 1) <> 0 Then
   MsgBox(0, 'Error!', 'Same process ' & $ChannelCustomName & ' already exists, exit now!', 5)
   Exit;
 EndIf
Else
 Local $ra = Random(1, 1234567890, 1);
 While _SingletonPID(@ScriptName & $ra & $ChannelCustomName, 1) <> 0
   $ra = Random(1, 1234567890, 1);
 WEnd
 $ChannelCustomName = $ra & $ChannelCustomName;
EndIf

Global $hChild = GUICreate($ChannelCustomName)
Global $hMainWnd = WinGetHandle("WebIMEGUIChannel")
Global $Succeed = 0

While $hMainWnd = 0 And $Succeed < 4
   Sleep(3000)
   $Succeed = $Succeed + 1
   $hMainWnd = WinGetHandle("WebIMEGUIChannel")
WEnd

If $hMainWnd <> 0 Then
  GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA_ReceiveData")
  GUISetState(@SW_HIDE)

  $Succeed = 0;

  Local $data = "";

  ;//you can add own functions being available inside JavaScript scope via settings.js > W.customerScripts = { }; //read important notices inside settings.js regarding W.customerScripts

  If $ExitOnFirstMessage = False Then
    ;//that is only example of possible usage, this data will be sent persistently and sendmsg.exe will listen for incoming commands to this custom channel process
    ;//that example will place icons in browser, in menu with back caller to this process to process arrived messages here with _handleData
    $data = $data & " (function() { " & @CRLF
    $data = $data & "   var window = document.defaultView || document.parentWindow; " & @CRLF
    $data = $data & "   var channelCustomName = '" & $ChannelCustomName & "'; " & @CRLF
    $data = $data & "   var userMessage = 'some user string'; " & @CRLF
    ;//$data = $data & "   window.ChannelCustomName = channelCustomName; " & @CRLF

    $data = $data & "   window.sendMyMessageBack = function(do_what) { " & @CRLF
    $data = $data & "     var messageBack = do_what; " & @CRLF
    $data = $data & "     if(channelCustomName && channelCustomName.length > 0) { " & @CRLF
    $data = $data & "       W.sendChannelCustom(channelCustomName, messageBack); " & @CRLF
    $data = $data & "     } " & @CRLF
    $data = $data & "   }; " & @CRLF
    $data = $data & "   alert('Listening mode\r\nAfter clicking OK the message ""' + userMessage + '"" \r\nwill be sent back to customer channel:\r\n' + channelCustomName); " & @CRLF
    $data = $data & "   W.sendChannelCustom(channelCustomName, userMessage); " & @CRLF
    $data = $data & " })(); " & @CRLF
  Else
    ;///won't do anything
  EndIf


  If $ExitOnFirstMessage = False Then
    _sendPersistentMessage($data) ;//in permanent listening mode to force the rdp channel to replay the data when browser window was refreshed, so use peristent message
                           ;//if wishing to send commands once use _sendSingleMessage with $ExitOnFirstMessage = True
  Else
    _sendSingleMessage($data); //when message will be sent only once, do not store it persistently to be replayed on browsers refresh, so use single message
  EndIf
Else
   MsgBox(0, "Message error!", "Channel process listener not found!", 5)
   Exit;
EndIf

If $ExitOnFirstMessage = True Then
  While 1
   SleepOWN(2000)
   If $Succeed = 1 Then Exit;
  WEnd
Else
  While 1
   SleepOWN(2000)
  WEnd
EndIf

Exit;

Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ;
    ;////
    Local $inSend = DllCall("user32.dll", "BOOLEAN", "InSendMessage");
    If $inSend[0] = 1 Then
      $inSend = DllCall("user32.dll", "BOOLEAN", "ReplyMessage", "uint", 1)
     ;// reply to parent webime.exe process immediatelly to not make it hanging while waiting for this function to return
     ;//it is Microsoft recommendation to process so, because if parent caller hangs because of waiting to return this function
     ;//it will cause both processes to hang, so to avoid that and allow parent process to continue working answer with ReplyMessage as fast as possible here
     ;//
     ;//PS: never remove this command, else you may block the webime.exe
     ;//however webime.exe uses timeout of 4 seconds and will not block forever, anyway answer with this ReplyMessage is good approach, so do not remove this command!
   EndIf
    ;////

    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    Local $received = DllStructGetData($tMsg, 1)

    If StringLeft($received, 1) = "3" Then
     $Succeed = 0;// just handle data without exit
     $received = StringTrimLeft($received, 1);
     _handleData($received)
    ElseIf $received = 0 Then
      $Succeed = 1
    EndIf
EndFunc

Func _handleData($data)
   MsgBox(0, "DATA ARRIVED", $data, 5)
   ;//handle your data here
EndFunc

Func WM_COPYDATA_SendData($hWnd, $sData)
   WM_COPYDATA_SendDataTimeout($hWnd, $sData, 4000)
EndFunc

Func WM_COPYDATA_SendDataTimeout($hWnd, $sData, $timeout)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
   Local $Max = 0
   $Succeed = 0
    While $Succeed <> 1 And $Max < 40
    $Max = $Max + 1
     Local $Ret = DllCall("user32.dll", "lresult", "SendMessageTimeout", "hwnd", $hWnd, "uint", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA), "uint", 0x0000, "uint", $timeout, "ptr*", 0)
    ;//SendMessageTimeout gets used, because when due some wrong programming of process that retrieves this message the function should continue at least after time out elapsed
    ;//however if program followed Microsofts recommendations and process replies with ReplyMessage to this call, this will continue as fast as possible
    ;//
    ;//PS: the parent webime.exe that represents the virtual channel follows Microsoft recommendations and replies as fast as possible to not make this function to hang
    ;//however timeout of 4 seconds is good approach anyway here
    $Succeed = $Ret[0];
    If $Succeed = 0 Then ;// 0 means failed or timed out
      SleepOWN(250)
    EndIf
    WEnd
    If $Succeed = 1 Then
     ;//Exit;
    Else
     MsgBox(0, "Error", "Waited more than 10 seconds for sending message!", 5);
    If $ExitOnFirstMessage = True Then Exit;
    EndIf
EndFunc

Func _sendSingleMessage($msg)
   $msg = "0" & $hChild & "@" & $msg
   WM_COPYDATA_SendData($hMainWnd, $msg)
EndFunc

Func _sendPersistentMessage($msg)
   If $ExitOnFirstMessage = True Then
      _sendSingleMessage($msg)
      Return
   EndIf
   $msg = "1" & $hChild & "@" & $msg
   WM_COPYDATA_SendData($hMainWnd, $msg)
EndFunc

Func _SingletonPID($sOccurenceName, $iFlag = 0)
   Local $hWnd = WinGetHandle($sOccurenceName)
   If @error Then
      AutoItWinSetTitle($sOccurenceName)
      $hWnd = WinGetHandle($sOccurenceName)
      ControlSetText($hWnd, '', ControlGetHandle($hWnd, '', 'Edit1'), @AutoItPID)
   Else
      If BitAND($iFlag, 1) Then
         Return Int(ControlGetText($hWnd, '', ControlGetHandle($hWnd, '', 'Edit1')))
      Else
         Exit -1
      EndIf
   EndIf
   Return 0
EndFunc   ;==>_SingletonPID

Func SleepOWN($time)
        Local $rWord = DllCall("User32.dll", "dword", "MsgWaitForMultipleObjectsEx", _
            "dword", 1, _
            "ptr", DllStructGetPtr($hChild), _
            "dword", $time, _
            "dword", 0x0040, _
            "dword", 0x6)
EndFunc
;////code server.au3 end
client.au3

Code: Select all

;////code client.au3 start
#NoTrayIcon
#include <WindowsConstants.au3>
Global $versionNum = 3;

Global $ExitOnFirstMessage = True;
       ;//False means, the process will run permanently in listening mode and may receive messages
      ;//True means, the process will send the message to browser only one time and than exit immediatelly
       ;//never send persistent _sendPersistentMessage when $ExitOnFirstMessage = True

Global $ChannelCustomName = "WebIMECustom1";
       ;//The unique name of this program that may be accessed from parent process called by browser

;//main body
If $ExitOnFirstMessage = False Then
 If _SingletonPID(@ScriptName & $ChannelCustomName, 1) <> 0 Then
   MsgBox(0, 'Error!', 'Same process ' & $ChannelCustomName & ' already exists, exit now!', 5)
   Exit;
 EndIf
Else
 Local $ra = Random(1, 1234567890, 1);
 While _SingletonPID(@ScriptName & $ra & $ChannelCustomName, 1) <> 0
   $ra = Random(1, 1234567890, 1);
 WEnd
 $ChannelCustomName = $ra & $ChannelCustomName;
EndIf

Global $hChild = GUICreate($ChannelCustomName)
Global $hMainWnd = WinGetHandle("WebIMEGUIChannel")
Global $Succeed = 0

While $hMainWnd = 0 And $Succeed < 4
   Sleep(3000)
   $Succeed = $Succeed + 1
   $hMainWnd = WinGetHandle("WebIMEGUIChannel")
WEnd

If $hMainWnd <> 0 Then
  GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA_ReceiveData")
  GUISetState(@SW_HIDE)

  $Succeed = 0;

  Local $data = "";

  ;//you can add own functions being available inside JavaScript scope via settings.js > W.customerScripts = { }; //read important notices inside settings.js regarding W.customerScripts

  If $ExitOnFirstMessage = False Then
    ;//that is only example of possible usage, this data will be sent persistently and sendmsg.exe will listen for incoming commands to this custom channel process
  Else
    ;//that is only example of possible usage, this data will be sent only once and sendmsg.exe will exit after sending the message
    $data = $data & " (function() { " & @CRLF
    $data = $data & "   var window = document.defaultView || document.parentWindow; " & @CRLF
    $data = $data & "   if(window.sendMyMessageBack) { window.sendMyMessageBack(new Date().getTime() / 1000); } " & @CRLF
    $data = $data & " })(); " & @CRLF
  EndIf


  If $ExitOnFirstMessage = False Then
    _sendPersistentMessage($data) ;//in permanent listening mode to force the rdp channel to replay the data when browser window was refreshed, so use peristent message
                           ;//if wishing to send commands once use _sendSingleMessage with $ExitOnFirstMessage = True
  Else
    _sendSingleMessage($data); //when message will be sent only once, do not store it persistently to be replayed on browsers refresh, so use single message
  EndIf
Else
   MsgBox(0, "Message error!", "Channel process listener not found!", 5)
   Exit;
EndIf

If $ExitOnFirstMessage = True Then
  While 1
   SleepOWN(2000)
   If $Succeed = 1 Then Exit;
  WEnd
Else
  While 1
   SleepOWN(2000)
  WEnd
EndIf

Exit;

Func WM_COPYDATA_ReceiveData($hWnd, $MsgID, $wParam, $lParam) ;
    ;////
    Local $inSend = DllCall("user32.dll", "BOOLEAN", "InSendMessage");
    If $inSend[0] = 1 Then
      $inSend = DllCall("user32.dll", "BOOLEAN", "ReplyMessage", "uint", 1)
     ;// reply to parent webime.exe process immediatelly to not make it hanging while waiting for this function to return
     ;//it is Microsoft recommendation to process so, because if parent caller hangs because of waiting to return this function
     ;//it will cause both processes to hang, so to avoid that and allow parent process to continue working answer with ReplyMessage as fast as possible here
     ;//
     ;//PS: never remove this command, else you may block the webime.exe
     ;//however webime.exe uses timeout of 4 seconds and will not block forever, anyway answer with this ReplyMessage is good approach, so do not remove this command!
   EndIf
    ;////

    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    Local $received = DllStructGetData($tMsg, 1)

    If StringLeft($received, 1) = "3" Then
     $Succeed = 0;// just handle data without exit
     $received = StringTrimLeft($received, 1);
     _handleData($received)
    ElseIf $received = 0 Then
      $Succeed = 1
    EndIf
EndFunc

Func _handleData($data)
   MsgBox(0, "DATA ARRIVED", $data, 5)
   ;//handle your data here
EndFunc

Func WM_COPYDATA_SendData($hWnd, $sData)
   WM_COPYDATA_SendDataTimeout($hWnd, $sData, 4000)
EndFunc

Func WM_COPYDATA_SendDataTimeout($hWnd, $sData, $timeout)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
   Local $Max = 0
   $Succeed = 0
    While $Succeed <> 1 And $Max < 40
    $Max = $Max + 1
     Local $Ret = DllCall("user32.dll", "lresult", "SendMessageTimeout", "hwnd", $hWnd, "uint", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA), "uint", 0x0000, "uint", $timeout, "ptr*", 0)
    ;//SendMessageTimeout gets used, because when due some wrong programming of process that retrieves this message the function should continue at least after time out elapsed
    ;//however if program followed Microsofts recommendations and process replies with ReplyMessage to this call, this will continue as fast as possible
    ;//
    ;//PS: the parent webime.exe that represents the virtual channel follows Microsoft recommendations and replies as fast as possible to not make this function to hang
    ;//however timeout of 4 seconds is good approach anyway here
    $Succeed = $Ret[0];
    If $Succeed = 0 Then ;// 0 means failed or timed out
      SleepOWN(250)
    EndIf
    WEnd
    If $Succeed = 1 Then
     ;//Exit;
    Else
     MsgBox(0, "Error", "Waited more than 10 seconds for sending message!", 5);
    If $ExitOnFirstMessage = True Then Exit;
    EndIf
EndFunc

Func _sendSingleMessage($msg)
   $msg = "0" & $hChild & "@" & $msg
   WM_COPYDATA_SendData($hMainWnd, $msg)
EndFunc

Func _sendPersistentMessage($msg)
   If $ExitOnFirstMessage = True Then
      _sendSingleMessage($msg)
      Return
   EndIf
   $msg = "1" & $hChild & "@" & $msg
   WM_COPYDATA_SendData($hMainWnd, $msg)
EndFunc

Func _SingletonPID($sOccurenceName, $iFlag = 0)
   Local $hWnd = WinGetHandle($sOccurenceName)
   If @error Then
      AutoItWinSetTitle($sOccurenceName)
      $hWnd = WinGetHandle($sOccurenceName)
      ControlSetText($hWnd, '', ControlGetHandle($hWnd, '', 'Edit1'), @AutoItPID)
   Else
      If BitAND($iFlag, 1) Then
         Return Int(ControlGetText($hWnd, '', ControlGetHandle($hWnd, '', 'Edit1')))
      Else
         Exit -1
      EndIf
   EndIf
   Return 0
EndFunc   ;==>_SingletonPID

Func SleepOWN($time)
        Local $rWord = DllCall("User32.dll", "dword", "MsgWaitForMultipleObjectsEx", _
            "dword", 1, _
            "ptr", DllStructGetPtr($hChild), _
            "dword", $time, _
            "dword", 0x0040, _
            "dword", 0x6)
EndFunc

;////code client.au3 end
TSplus HTML5 and Java web engineer

247Oversight
Posts: 3
Joined: Tue Jul 05, 2016 1:06 pm

Re: Client side scripting

Post by 247Oversight » Sun Jul 24, 2016 3:32 pm

Returning from vacation. Thank you for all your help. Take a couple of days to get back on track in the office and then I will start work on this project. Once again thank you for your time and help on this request.

Have a Great Week,
Steve C.

User avatar
Marc Pelosi
Posts: 1
Joined: Fri Aug 11, 2017 8:20 am

Re: Client side scripting

Post by Marc Pelosi » Fri Aug 11, 2017 8:22 am

Thanks for the clarification! Got it working.
I'm gonna learn some tricks, the basic ones. I need to know all the main concepts. They can be used at the table. But they won't help me with that roulette.

Onlyzen
Posts: 3
Joined: Fri Jul 28, 2017 11:32 am
Location: United States

Re: Client side scripting

Post by Onlyzen » Fri Nov 03, 2017 12:27 pm

The client-side environment used to run scripts is usually a browser. The processing takes place on the end users computer. The source code is transferred from the web server to the users computer over the internet and run directly in the browser. The scripting language needs to be enabled on the client computer.

Onlyzen
Posts: 3
Joined: Fri Jul 28, 2017 11:32 am
Location: United States

Re: Client side scripting

Post by Onlyzen » Thu Nov 09, 2017 7:12 am

A client-side dynamic web page processes the web page using HTML scripting running in the browser as it loads. JavaScript and other scripting languages determine the way the HTML in the received page is parsed into the Document Object Model, or DOM, that represents the loaded web page. The same client-side techniques can then dynamically update or change the DOM in the same way.

Post Reply