Bluetooth. Chat PC (Windows) from/to App. AutoIt. Laptop. Shutdown PC. Upload image file to PC

Chat on a PC (Windows) with Bluetooth and the app.

3 Likes

1.- App Inventor.

Clock.TimerInterval: 50

p41i_pc_movil_chat.aia (3.3 KB)

2.- AutoIt.

AutoIt is similar to Visual Basic, we use it to create the Windows program.

[AutoIt Downloads - AutoIt] (AutoIt Downloads - AutoIt) (free) (18 MB)

bluetooth_autoit2

bluetooth_autoit3

Editor: SciTe / SciTE.exe

bluetooth_autoit4

3.- Code.

It's an adaptation of...

https://www.autoitscript.com/forum/topic/183106-question-regarding-serial-coms/#comment-1314735

  • This code needs files:

  • commg.dll (In the same directory as the code)

  • CommMG.au3 in C:\Program Files (x86)\AutoIt3\Include

bluetooth_autoit_ordenador_chat.au3

Summary
; Original: https://www.autoitscript.com/forum/topic/183106-question-regarding-serial-coms/#comment-1314735
; Modificado por Juan Antonio Villalpando
; KIO4.COM
; http://kio4.com/autoit/69C_bluethooth_ordenador_appinventor_chat.htm
; CHAT

#include <GUIConstants.au3>
#include <CommMG.au3>;or if you save the commMg.dll in the @scripdir use #include @SciptDir & '\commmg.dll'
#include <GuiEdit.au3>
#include <GuiComboBox.au3>
#include <windowsconstants.au3>
#include <buttonconstants.au3>
#include <Array.au3>

Opt("WINTITLEMATCHMODE", 3)
HotKeySet("{ESC}", "alldone")

$result = '';used for any returned error message setting port
Const $settitle = "COMMG listExample - set Port", $maintitle = "COMMG Example"
$setflow = 2;default to no flow control
Dim $FlowType[3] = ["Hardware (RTS, CTS)", "XOnXoff", "NONE"]
Dim $ParityType[5] = ["odd", "even", "none", "Mark", "Space"]
#region main program

#Region ### START Koda GUI section ### Form=
$Form2 = GUICreate("COMMG Example", 475, 430, 453, 189)
$Edit1 = GUICtrlCreateEdit("", 2, 33, 449, 311, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
GUICtrlSetData(-1, "")
$BtnSend = GUICtrlCreateButton("Send", 380, 353, 53, 30, $BS_FLAT)
$Input1 = GUICtrlCreateInput("", 18, 359, 337, 24)
$BtnSetPort = GUICtrlCreateButton("Set Port", 16, 392, 73, 30, $BS_FLAT)
$Label21 = GUICtrlCreateLabel("Nombre:", 18, 6, 70, 17)
$Input2 = GUICtrlCreateInput("Antonio", 88, 0, 121, 24)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

WinSetTitle($Form2, "", $maintitle & "  UDF = " & _CommGetVersion(1))

While setport(0) = -1
    If MsgBox(4, 'Port not set', 'Do you want to quite the program?') = 6 Then Exit
WEnd

Events()
_CommSetXonXoffProperties(11, 13, 100, 100)
GUICtrlSetState($Edit1, $GUI_FOCUS)

While 1
    $instr = _commGetLine(@CR, 50, 200);_CommGetString() ; CHAT Numero de caracteres 50

    If $instr <> '' Then ;if we got something
	   $instr = $instr & @CRLF ; CHAT cambio de linea
	   FileWrite(@ScriptDIr & "/Data.txt", $instr)
	   GUICtrlSetData($Edit1, $instr, 1)
    Else
        Sleep(20) ;MichaelXMike
    EndIf

WEnd

Alldone()


Func Events()
    Opt("GUIOnEventMode", 1)
    GUISetOnEvent($GUI_EVENT_CLOSE, "justgo")
    GUICtrlSetOnEvent($BtnSend, "SendEvent")
    GUICtrlSetOnEvent($BtnSetPort, "SetPortEvent")
EndFunc   ;==>Events

Func SetPortEvent()
    setport();needed because a parameter is optional for setport so we can't use "setport" for the event
    GUICtrlSetState($Edit1, $GUI_FOCUS)
EndFunc   ;==>SetPortEvent

Func justgo()
    Exit
EndFunc   ;==>justgo

Func SendEvent();send the text in the inputand append CR
	$poner = "- " & GUICtrlRead($Input2) & ": " & GUICtrlRead($Input1) & @CRLF ; CHAT
	GUICtrlSetData($Edit1, $poner, 1) ; CHAT anadir al Edit1
	_CommSendstring($poner) ; CHAT
    GUICtrlSetData($Input1, '') ;clear the input
EndFunc   ;==>SendEvent


Func AllDone()
    _Commcloseport(true)
    Exit
EndFunc   ;==>AllDone


Func SetPort($mode = 1);if $mode = 1 then returns -1 if settings not made
    Local $sportSetError
    Opt("GUIOnEventMode", 0);keep events for $Form2, use GuiGetMsg for $Form3

    #Region ### START Koda GUI section ### Form=d:\my documents\miscdelphi\commg\examplecommsetport.kxf
    $Form3 = GUICreate("COMMG Example - set Port", 422, 279, 329, 268, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_GROUP, $WS_BORDER, $WS_CLIPSIBLINGS, _
	$DS_MODALFRAME), BitOR($WS_EX_TOPMOST, $WS_EX_WINDOWEDGE))

    $Group1 = GUICtrlCreateGroup("Set COM Port", 18, 8, 288, 252)
    $CmboPortsAvailable = GUICtrlCreateCombo("", 127, 28, 145, 25, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_SORT))
    $CmBoBaud = GUICtrlCreateCombo("9600", 127, 66, 145, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL, $CBS_SORT, $WS_VSCROLL))
    GUICtrlSetData(-1, "115200|1200|128000|14400")
    $CmBoStop = GUICtrlCreateCombo("1", 127, 141, 145, 25)
    GUICtrlSetData(-1, "1|2|1.5")
    $CmBoParity = GUICtrlCreateCombo("", 127, 178, 145, 25)
    GUICtrlSetData(-1, "odd|even|none|Mark|Space")
    GUICtrlSetData(-1, "none")
    $Label2 = GUICtrlCreateLabel("Port", 94, 32, 23, 17)
    $Label3 = GUICtrlCreateLabel("baud", 89, 70, 28, 17)
    $Label4 = GUICtrlCreateLabel("No. Stop bits", 52, 145, 65, 17)
    $Label5 = GUICtrlCreateLabel("parity", 88, 182, 29, 17)
    $CmboDataBits = GUICtrlCreateCombo("8", 127, 103, 145, 25)
    GUICtrlSetData(-1, "7|8")
    $Label7 = GUICtrlCreateLabel("No. of Data Bits", 38, 107, 79, 17)
    $ComboFlow = GUICtrlCreateCombo("NONE", 127, 216, 145, 25)
    GUICtrlSetData(-1, "NONE|XOnXOff|Hardware (RTS, CTS)")
    $Label1 = GUICtrlCreateLabel("flow control", 59, 220, 58, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $BtnApply = GUICtrlCreateButton("Apply", 315, 95, 75, 35, $BS_FLAT)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    $BtnCancel = GUICtrlCreateButton("Cancel", 316, 147, 76, 35, $BS_FLAT)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###


    WinSetTitle($Form3, "", $settitle) ;ensure a change to Koda design doesn't stop script working
    $mainxy = WinGetPos($Form2)
    WinMove($Form3, "", $mainxy[0] + 20, $mainxy[1] + 20)

    $portlist = _CommListPorts(0);find the available COM ports and write them into the ports combo
    If @error = 1 Then
        MsgBox(0, 'trouble getting portlist', 'Program will terminate!')
        Exit
    EndIf

    For $pl = 1 To $portlist[0]
        $portnum = StringReplace($portlist[$pl], "COM", '')
        if StringLen($portnum) = 1 then $portnum = ' ' & $portnum
        $portlist[$pl] = 'COM' & $portnum
        GUICtrlSetData($CmboPortsAvailable, $portlist[$pl]) ;_CommListPorts())
    Next
    GUICtrlSetData($CmboPortsAvailable, $portlist[1]) ;show the first port found
    GUICtrlSetData($ComboFlow, $FlowType[$setflow])

    _GUICtrlComboBox_SetMinVisible($CmBoBaud, 10) ;restrict the length of the drop-down list

    $retval = 0

    While 1
        $msg = GUIGetMsg()
        If $msg = $BtnCancel Then
            If Not $mode Then $retval = -1
            ExitLoop
        EndIf

        If $msg = $BtnApply Then

            $comboflowsel = GUICtrlRead($ComboFlow)
            For $n = 0 To 2
                If $comboflowsel = $FlowType[$n] Then
                    $setflow = $n
                    ExitLoop
                EndIf

            Next
            $setport = StringReplace(GUICtrlRead($CmboPortsAvailable), 'COM', '')

            $ParitySel = GUICtrlRead($CmBoParity)
            For $n = 0 To 4
                If $ParitySel = $ParityType[$n] Then
                    $SetParity = $n
                    ExitLoop
                EndIf
            Next

            $setStop = StringReplace(GUICtrlRead($CmBoStop), '.', '');replace 1.5 with 15 if needed

	$resOpen = _CommSetPort($setport, $sportSetError, GUICtrlRead($CmBoBaud), GUICtrlRead($CmboDataBits), $SetParity, $setStop, $setflow)

            if $resOpen = 0 then
                Exit
            EndIf

            Sleep(1000)
            $mode = 1;
            ExitLoop
        EndIf
        ;stop user switching back to $form2
        If WinActive($maintitle) Then
            ConsoleWrite('main is active' & @CRLF)
            If WinActivate($settitle) = 0 Then MsgBox(0, 'not found', $settitle)
        EndIf

    WEnd

    GUIDelete($Form3)
    WinActivate($maintitle)
    Events()
    Return $retval

EndFunc

4.- Connection.

The most complicated part is the process is that the PC recognizes your Bluetooth and
pair the Bluetooth of the device with that of the PC.

5.- Run.

  • We choose the Bluetooth COM port of the PC.
  • To connect to the device they must be paired.

6.- Designer.

The design with the Buttons, TextBox, Labels,... components is done with Koda.

http://koda.darkhost.ru/wiki/doku.php?id=koda:en:start

We will get such a code, which we will insert into the editor.

Example:

Summary

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 431, 477, 187, 131)
$Label1 = GUICtrlCreateLabel("Área del triángulo.", 96, 16, 265, 41)
GUICtrlSetFont(-1, 20, 400, 0, "MS Sans Serif")
$Label2 = GUICtrlCreateLabel("Base", 16, 96, 76, 41)
GUICtrlSetFont(-1, 20, 400, 0, "MS Sans Serif")
$Input1 = GUICtrlCreateInput("Input1", 160, 96, 193, 45)
GUICtrlSetFont(-1, 20, 400, 0, "MS Sans Serif")
$Label3 = GUICtrlCreateLabel("Altura", 24, 184, 89, 41)
GUICtrlSetFont(-1, 20, 400, 0, "MS Sans Serif")
$Input2 = GUICtrlCreateInput("Input2", 160, 176, 193, 45)
GUICtrlSetFont(-1, 20, 400, 0, "MS Sans Serif")
$Button1 = GUICtrlCreateButton("Pulsa para calcular", 56, 256, 321, 49)
GUICtrlSetFont(-1, 20, 400, 0, "MS Sans Serif")
$Label4 = GUICtrlCreateLabel("Label4", 56, 360, 316, 41)
GUICtrlSetFont(-1, 20, 400, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

Tutorial of AutoIt in Spanish:
http://kio4.com/autoit/index.htm

7.- Shutdown PC from App via Bluetooth.

We add these lines to the AutoIt code...

While 1
    $instr = _commGetLine(@CR, 50, 200);_CommGetString() ; CHAT Numero de caracteres 50

    If $instr <> '' Then ;if we got something
	    ; RUN HERE
		   Local $iPosition = StringInStr($instr, "shutdown")
		   if $iPosition <> 0 Then
			   Shutdown(64)
			   ; run("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe", @SW_MINIMIZE)
			   ; http://kio4.com/autoit/8_hibernar_run_msgbox.htm
		   EndIf
		   
	   $instr = $instr & @CRLF ; CHAT cambio de linea
	   FileWrite(@ScriptDIr & "/Data.txt", $instr)
	   GUICtrlSetData($Edit1, $instr, 1)
    Else
        Sleep(20) ;MichaelXMike
    EndIf

WEnd
  • When in the application we write and send "shutdown", the PC will turn off.

http://kio4.com/autoit/8_hibernar_run_msgbox.htm

8.- Upload image file to PC by Bluetooth.

p41i_pc_movil_archivo.aia (102.5 KB)

Two examples:

a) Copy foto5.png from the asset to the ASD.
Convert it to Base64 using an extension.
Upload the string to the PC. BluetoothClient.SendText

b) Take Picture with Cam.
Decreases the size of the Picture using an extension.
Convert Picture to Base64 using an extension.
Upload the string to the PC. BluetoothClient.SendText

The Autoit code receives the string, decodes the Base64 and saves it in the mi_imagen.png file, in the same directory as the script.

Because the Picture file size is too large (about 4 MB), we reduce its size to about 500 kB using the @TIMAI2 extension: Image Convertor

http://kio4.com/autoit/69D_bluethooth_ordenador_appinventor_archivo.htm

bluetooth_autoit_ordenador_archivo.au3

Summary
; Modificado por Juan Antonio Villalpando
; KIO4.COM
; http://kio4.com/autoit/69D_bluethooth_ordenador_appinventor_archivo.htm
; CHAT

#include <GUIConstants.au3>
#include <CommMG.au3>;or if you save the commMg.dll in the @scripdir use #include @SciptDir & '\commmg.dll'
#include <GuiEdit.au3>
#include <GuiComboBox.au3>
#include <windowsconstants.au3>
#include <buttonconstants.au3>
#include <Array.au3>

Opt("WINTITLEMATCHMODE", 3)
HotKeySet("{ESC}", "alldone")

$result = '';used for any returned error message setting port
Const $settitle = "COMMG listExample - set Port", $maintitle = "COMMG Example"
$setflow = 2;default to no flow control
Dim $FlowType[3] = ["Hardware (RTS, CTS)", "XOnXoff", "NONE"]
Dim $ParityType[5] = ["odd", "even", "none", "Mark", "Space"]
#region main program

#Region ### START Koda GUI section ### Form=
$Form2 = GUICreate("COMMG Example", 475, 430, 453, 189)
$BtnSend = GUICtrlCreateButton("Send", 380, 353, 53, 30, $BS_FLAT)
$Input1 = GUICtrlCreateInput("", 18, 359, 337, 24)
$BtnSetPort = GUICtrlCreateButton("Set Port", 16, 392, 73, 30, $BS_FLAT)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

WinSetTitle($Form2, "", $maintitle & "  UDF = " & _CommGetVersion(1))

While setport(0) = -1
    If MsgBox(4, 'Port not set', 'Do you want to quite the program?') = 6 Then Exit
WEnd

Events()
_CommSetXonXoffProperties(11, 13, 100, 100)
$todo = ""
While 1
	$instr = _CommGetString() ;

    If $instr <> '' Then ;if we got something
	$todo = $todo & $instr
	 	   $iPosition = StringInStr($todo, "_EOF")
	       if $iPosition <> 0 Then
		   received($todo)
		   $todo = ""
		   $instr = ""
		   _CommSendstring("Recibido") ; Response
	      EndIf
    Else
        Sleep(10) ;MichaelXMike
    EndIf

WEnd

Alldone()

Func Events()
    Opt("GUIOnEventMode", 1)
    GUISetOnEvent($GUI_EVENT_CLOSE, "justgo")
    GUICtrlSetOnEvent($BtnSend, "SendEvent")
    GUICtrlSetOnEvent($BtnSetPort, "SetPortEvent")
EndFunc   ;==>Events

Func SetPortEvent()
    setport();needed because a parameter is optional for setport so we can't use "setport" for the event
EndFunc   ;==>SetPortEvent

Func justgo()
    Exit
EndFunc   ;==>justgo

Func SendEvent();send the text in the inputand append CR
	 $poner =  GUICtrlRead($Input1) & @CRLF ; CHAT
	_CommSendstring($poner) ; CHAT
EndFunc   ;==>SendEvent


Func AllDone()
    _Commcloseport(true)
    Exit
EndFunc   ;==>AllDone


Func SetPort($mode = 1);if $mode = 1 then returns -1 if settings not made
    Local $sportSetError
    Opt("GUIOnEventMode", 0);keep events for $Form2, use GuiGetMsg for $Form3

    #Region ### START Koda GUI section ### Form=d:\my documents\miscdelphi\commg\examplecommsetport.kxf
    $Form3 = GUICreate("COMMG Example - set Port", 422, 279, 329, 268, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_GROUP, $WS_BORDER, $WS_CLIPSIBLINGS, _
	$DS_MODALFRAME), BitOR($WS_EX_TOPMOST, $WS_EX_WINDOWEDGE))

    $Group1 = GUICtrlCreateGroup("Set COM Port", 18, 8, 288, 252)
    $CmboPortsAvailable = GUICtrlCreateCombo("", 127, 28, 145, 25, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_SORT))
    $CmBoBaud = GUICtrlCreateCombo("9600", 127, 66, 145, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL, $CBS_SORT, $WS_VSCROLL))
    GUICtrlSetData(-1, "115200|1200|128000|14400")
    $CmBoStop = GUICtrlCreateCombo("1", 127, 141, 145, 25)
    GUICtrlSetData(-1, "1|2|1.5")
    $CmBoParity = GUICtrlCreateCombo("", 127, 178, 145, 25)
    GUICtrlSetData(-1, "odd|even|none|Mark|Space")
    GUICtrlSetData(-1, "none")
    $Label2 = GUICtrlCreateLabel("Port", 94, 32, 23, 17)
    $Label3 = GUICtrlCreateLabel("baud", 89, 70, 28, 17)
    $Label4 = GUICtrlCreateLabel("No. Stop bits", 52, 145, 65, 17)
    $Label5 = GUICtrlCreateLabel("parity", 88, 182, 29, 17)
    $CmboDataBits = GUICtrlCreateCombo("8", 127, 103, 145, 25)
    GUICtrlSetData(-1, "7|8")
    $Label7 = GUICtrlCreateLabel("No. of Data Bits", 38, 107, 79, 17)
    $ComboFlow = GUICtrlCreateCombo("NONE", 127, 216, 145, 25)
    GUICtrlSetData(-1, "NONE|XOnXOff|Hardware (RTS, CTS)")
    $Label1 = GUICtrlCreateLabel("flow control", 59, 220, 58, 17)
    GUICtrlCreateGroup("", -99, -99, 1, 1)
    $BtnApply = GUICtrlCreateButton("Apply", 315, 95, 75, 35, $BS_FLAT)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    $BtnCancel = GUICtrlCreateButton("Cancel", 316, 147, 76, 35, $BS_FLAT)
    GUICtrlSetFont(-1, 12, 400, 0, "MS Sans Serif")
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###


    WinSetTitle($Form3, "", $settitle) ;ensure a change to Koda design doesn't stop script working
    $mainxy = WinGetPos($Form2)
    WinMove($Form3, "", $mainxy[0] + 20, $mainxy[1] + 20)

    $portlist = _CommListPorts(0);find the available COM ports and write them into the ports combo
    If @error = 1 Then
        MsgBox(0, 'trouble getting portlist', 'Program will terminate!')
        Exit
    EndIf

    For $pl = 1 To $portlist[0]
        $portnum = StringReplace($portlist[$pl], "COM", '')
        if StringLen($portnum) = 1 then $portnum = ' ' & $portnum
        $portlist[$pl] = 'COM' & $portnum
        GUICtrlSetData($CmboPortsAvailable, $portlist[$pl]) ;_CommListPorts())
    Next
    GUICtrlSetData($CmboPortsAvailable, $portlist[1]) ;show the first port found
    GUICtrlSetData($ComboFlow, $FlowType[$setflow])

    _GUICtrlComboBox_SetMinVisible($CmBoBaud, 10) ;restrict the length of the drop-down list

    $retval = 0

    While 1
        $msg = GUIGetMsg()
        If $msg = $BtnCancel Then
            If Not $mode Then $retval = -1
            ExitLoop
        EndIf

        If $msg = $BtnApply Then

            $comboflowsel = GUICtrlRead($ComboFlow)
            For $n = 0 To 2
                If $comboflowsel = $FlowType[$n] Then
                    $setflow = $n
                    ExitLoop
                EndIf

            Next
            $setport = StringReplace(GUICtrlRead($CmboPortsAvailable), 'COM', '')

            $ParitySel = GUICtrlRead($CmBoParity)
            For $n = 0 To 4
                If $ParitySel = $ParityType[$n] Then
                    $SetParity = $n
                    ExitLoop
                EndIf
            Next

            $setStop = StringReplace(GUICtrlRead($CmBoStop), '.', '');replace 1.5 with 15 if needed

	$resOpen = _CommSetPort($setport, $sportSetError, GUICtrlRead($CmBoBaud), GUICtrlRead($CmboDataBits), $SetParity, $setStop, $setflow)

            if $resOpen = 0 then
                Exit
            EndIf

            Sleep(1000)
            $mode = 1;
            ExitLoop
        EndIf
        ;stop user switching back to $form2
        If WinActive($maintitle) Then
            ConsoleWrite('main is active' & @CRLF)
            If WinActivate($settitle) = 0 Then MsgBox(0, 'not found', $settitle)
        EndIf

    WEnd

    GUIDelete($Form3)
    WinActivate($maintitle)
    Events()
    Return $retval

EndFunc

Func received($sData)
$BASE64_DATA = $sData
$BASE64_DATA = StringReplace ($BASE64_DATA, @CR, "")
$BASE64_DATA = StringReplace ($BASE64_DATA, @LF, "")

$base64_code =  StringSplit($BASE64_DATA, "_EOF", 1)
$BASE64_DATA = $base64_code[1]

    Local $hFile = 0
	$sImageName = "mi_imagen.png"
    $hFile=FileOpen($sImageName, 18)
	FileWrite($hFile, _Encoding_Base64Decode($BASE64_DATA))
   ; FileWrite($hFile, $BASE64_DATA)
    FileClose($hFile)
EndFunc   ;==>received

Func _Encoding_Base64Decode($sData)
    Local $struct = DllStructCreate("int")

    $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", _
            "str", $sData, _
            "int", 0, _
            "int", 1, _
            "ptr", 0, _
            "ptr", DllStructGetPtr($struct, 1), _
            "ptr", 0, _
            "ptr", 0)

    If @error Or Not $a_Call[0] Then
        Return SetError(1, 0, "") ; error calculating the length of the buffer needed
    EndIf

    Local $a = DllStructCreate("byte[" & DllStructGetData($struct, 1) & "]")

    $a_Call = DllCall("Crypt32.dll", "int", "CryptStringToBinary", _
            "str", $sData, _
            "int", 0, _
            "int", 1, _
            "ptr", DllStructGetPtr($a), _
            "ptr", DllStructGetPtr($struct, 1), _
            "ptr", 0, _
            "ptr", 0)

    If @error Or Not $a_Call[0] Then
        Return SetError(2, 0, "") ; error decoding
    EndIf

    Return BinaryToString(DllStructGetData($a, 1))
EndFunc   ;==>_Encoding_Base64Decode