Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

Portuguese

Este arquivo PRW contém o ferramental necessário para customizações ADVPL à partir do CloudBridge, nele você entenderá todo o mecanismo de comunicação entre o Navegador Embedado (JavaScript) e o ADVPL.

As funções mais importantes são:

Function u_CBCustom()
Função principal, deve ser inserida na TAG mainFunction no arquivo .cloud, base do aplicativo, para ser instanciada no momento da abertura.

Function loadFinished()
Função atribuida como bloco de código do oWebEngine:bLoadFinished, ela será disparada ao termino da carga das páginas e como parâmetro recebe a URL carregada.

Function notificationTapped()
Função atribuida como bloco de código do oMobile:bNotificationTapped, ela será disparada quando a notificação for selecionada no dispositivo móvel. Ela recebe o ID inserido na notificação.

Function jsToAdvpl()
Função atribuida como bloco de código do oWebChannel:bJsToAdvpl, ela será disparada durante o recebimento da Função dialog.jsToAdvpl() que será disparada via JavaScript.

Arquivo

Bloco de código
languagecpp
themeEclipse
linenumberstrue
collapsefalse
#include "TOTVS.CH"
#include "FILEIO.CH"
#INCLUDE "TBIConn.ch"

Function u_CBCustom()
	    // ---------------------------------------------------------------
	    local i
	    local oWebChannel
	    local cMultGet := ""
	    local cHost,nPort,lConnected
	    local tempPath := GetTempPath()
	    PRIVATE oWebEngine
	    PRIVATE oMultGet
	    PRIVATE oGetLink
	PRIVATE	oDlg
	    PRIVATE    oDlg

    oDlg := TWindow():New(10, 10, 800, 600, "TOTVS - CloudBridge", NIL, NIL, NIL, NIL, NIL, NIL, NIL,;
	    CLR_BLACK, CLR_WHITE, NIL, NIL, NIL, NIL, NIL, NIL, .T. )
	    oDlg:setCSS("QPushButton{margin: 1px; background-color: "+_colorTOTVS+"; border: none; color: #fff; }")
	
    // Android ou iOS
	    if _rmtType == 8 .Or. _rmtType == 9
		        // Libera rotacao do dispositivo
		        PRIVATE oMobile := TMobile():New(oDlg)
		        oMobile:SetScreenOrientation(-1)
		

        // Temporario do dispositivo
		        tempPath := oMobile:GetTempPath() + "/"
		

        // Prepara bloco de codigo pra callBack de notificacao
		        oMobile:bNotificationTapped := {|id| notificationTapped(id) }
	    endif

	    // Prepara o conector WebSocket, sempre pra LOCALHOST e retorna a PORTA LIVRE
	    oWebChannel := TWebChannel():New()
	    nPort   		       := oWebChannel::connect()
	cHost 		    cHost         := oWebChannel:cHost
	nPort 		    nPort         := oWebChannel:nPort
	lConnected 	    lConnected     := oWebChannel:lConnected

	    // Verifica conexão
	    if !lConnected
		        msgStop("Erro na conexão com o WebSocket")
		        return
	    endif

	    // Define o CallBack JavaScript
	    oWebChannel:bJsToAdvpl := {|self,codeType,codeContent| jsToAdvpl(self,codeType,codeContent) }
	
    // Monta link GLOBAL
	if subs    if subs(tempPath,1,2) == "C:"
		        tempPath := "file:///" + strTran(tempPath, "\", "/")
	    endif
	    mainHtml := tempPath + mainHtml
	
    oWebEngine := TWebEngine():New(oDlg, 0, 0, 100, 100,, nPort)
	    oWebEngine:bLoadFinished := {|self,url| loadFinished(self,url) }
	    oWebEngine:setAsMain() // Define como WebEngine que recebera o KEY_BACK (Android)

	    // Painel superior
	    @ 000, 000 MSPANEL pnTop SIZE 250, 024 OF oDlg COLORS 0, 16777215 RAISED // Mansano: 250, 012
	    pnTop:setCss("QFrame{background-color: #6BB4F1;}")

	    // Alinha componentes
	    pnTop:Align := CONTROL_ALIGN_TOP
	    oWebEngine:Align := CONTROL_ALIGN_ALLCLIENT
	
    // CONOUT fake para exibir a mensageria
	    oFont1 := TFont():New("Courier",,018,,.F.,,,,,.F.,.F.)
	    @ 038, 000 MSPANEL ConOut SIZE 250, 16 OF oDlg COLORS 0, 16777215 RAISED
	    oMultGet := TSimpleEditor():New( 0,0,ConOut, 50,50,"",, {| u | if( pCount() > 0, cMultGet := u, cMultGet )}, oFont1, .T.)
	    ConOut:Align := CONTROL_ALIGN_BOTTOM
	    oMultGet:Align := CONTROL_ALIGN_ALLCLIENT

	    CreateFormTop(pnTop)

	    oDlg:Activate("MAXIMIZED")
Return

// Parseia o Json em um Hash
Static Function getJsonHash(jsonData, oHash)
	    // ---------------------------------------------------------------
	    Local oJson := tJsonParser():New()
	    Local jsonfields := {}
	    Local nRetParser := 0

	    if empty(jsonData)
		        return .F.
	    endif

	    // Converte JSON pra Hash
	    return oJson:Json_Hash(jsonData, len(jsonData), @jsonfields, @nRetParser, @oHash)
return

// Retorna valor do campo no Hash
Static Function getHField(oHash, jsonField)
	    // ---------------------------------------------------------------
	    Local xGet := Nil
	    // Recupera valor do campo
	    if HMGet(oHash, jsonField, xGet)
		        return xGet
	    else
		        return ""
	    endif
return

// Bloco de codigo do termino da carga da pagina
static function loadFinished(self,url)
	    // ---------------------------------------------------------------
	    oGetLink:cText := url+space(1000)
return

// CALLBACK das notificacoes
static function notificationTapped(id)
	    conout("createNotification: id: " + cValToChar(id))
return

// CALLBACK JavaScript
static function jsToAdvpl(self,codeType,codeContent)
	    // ---------------------------------------------------------------
	    Local i
	    Local oTmpHash := .F.
	    Local xRet, lRet
	    Local xVal, fnCallBack, cFile, aBarResult,;
	    aDevicesResult, sMsg, cPosition, id, title, message,;
	    cQuery, nFields, nRecords, aAccelerometerSensor
	
    if valType(codeType) == "C"
		_        _conout("jsToAdvpl->codeType: " + codeType + " = " + codeContent)
		

        if codeType == "runAdvpl"
			            if getJsonHash(codeContent, @oTmpHash)
				                xVal := &("{|| " + getHField(oTmpHash, "codeBlock") + "}")
				                if valType(xVal) == "B"
					xRet := eval(xVal)
					xRet := cValToChar(xRet                    xRet := eval(xVal)
                    xRet := cValToChar(xRet) // Converte pra String
					

                    // Executa o CallBack
					fnCallBack = getHField(oTmpHash, "callBack"                    fnCallBack = getHField(oTmpHash, "callBack")+"('" +xRet+ "')"
					                    oWebEngine:runJavaScript(fnCallBack)
				endif
			else
				_msgAlert("RunAdvpl command not executed", "CloudBridge")
			endif
			return
		endif
		// Android Ou iOS
		if _rmtType == 8 .Or. _rmtType == 9
			// Tira foto
			if codeType == "getPicture"
				cFile:= oMobile:TakePicture()
				_conout("[getPicture] - " + cFile)
				// Executa o CallBack
				fnCallBack = codeContent+"('" +cFile+ "')"
				oWebEngine:runJavaScript(fnCallBack)
				return
			endif
			// Codigo de  barras
			if codeType == "barCodeScanner"
				aBarResult := oMobile:BarCode()
				If aBarResult[1] = ""
					_conout("[barCode] - " + "Nenhum código de barras disponível.")
				Else
					_conout("[barCode] - " + "Código: " + aBarResult[1] + chr(13) + "Formato: " + aBarResult[2])
					// Executa o CallBack
					fnCallBack = codeContent+"('" +aBarResult[1]+ "')"
					oWebEngine:runJavaScript(fnCallBack)
				EndIf
				return
			endif
			// Verifica dispositivos pareados
			if codeType == "pairedDevices"
				aDevicesResult:= oMobile:GetPairedBluetoothDevices()
				sMsg := ""
				For i := 1 to len(aDevicesResult)
					sMsg := sMsg + "Nome: " + aDevicesResult[i][1] + chr(13)
					sMsg := sMsg + "Endereço: " + aDevicesResult[i][2] + chr(13) + chr(13)
				Next i
				If sMsg = ""
					sMsg := "Nenhum dispositivo pareado ou interface Bluetooth desligada."
				Else
					sMsg := "Dispositivos Bluetooth Pareados:" + chr(13) + chr(13) + sMsg
				EndIf
				_conout("[bluetooth] - " + sMsg)
				// Executa o CallBack
				                endif
            else
                _msgAlert("RunAdvpl command not executed", "CloudBridge")
            endif
            return
        endif

        // Android Ou iOS
        if _rmtType == 8 .Or. _rmtType == 9

            // Tira foto
            if codeType == "getPicture"
                cFile:= oMobile:TakePicture()
                _conout("[getPicture] - " + cFile)

                // Executa o CallBack
                fnCallBack = codeContent+"('" +SubStr(sMsg,1,30)cFile+ "')"
				                oWebEngine:runJavaScript(fnCallBack)
				return
			endif
			// Libera orientacao
			                return
            endif

            // Codigo de  barras
            if codeType == "unlockOrientation"
				oMobile:SetScreenOrientation(-1)
				_conout("[unlockOrientation]")
				return
			endif
			// Trava orientacao
			if codeType == "lockOrientation"
				oMobile:SetScreenOrientation(2)
				_conout("[lockOrientation]")
				return
			endif
			// GPS
			if codeType == "getCurrentPosition"
				cPosition := oMobile:getGeoCoordinate(1)
				// PARA LIMPAR O SINAL DE GRAUS CHR(176)
				//cPosition := StrTran(cPosition, chr(176), "")
				_conout("[getCurrentPositionbarCodeScanner"
                aBarResult := oMobile:BarCode()
                If aBarResult[1] = ""
                    _conout("[barCode] - " + "Nenhum código de barras disponível.")
                Else
                    _conout("[barCode] - " + cPosition)
				// Executa o CallBack
				fnCallBack = codeContent+"('" +cPosition+ "')"
				oWebEngine:runJavaScript(fnCallBack)
				return
			endif
			// Testa perifericos
			if codeType == "testDevice"
				if getJsonHash(codeContent, @oTmpHash)
					lRet := oMobile:TestDevice(getHField(oTmpHash, "testFeature"))
					// Executa o CallBack
					fnCallBack = getHField(oTmpHash, "callBack")"Código: " + aBarResult[1] + chr(13) + "Formato: " + aBarResult[2])

                    // Executa o CallBack
                    fnCallBack = codeContent+"('" +cValToChar(lRet)aBarResult[1]+ "')"
					                    oWebEngine:runJavaScript(fnCallBack)
				else
					_msgAlert("testDevice command not executed", "CloudBridge")
				endif
				return
			endif
			// Cria notificacao
			// O callBack sera disparado pelo bloco de codigo bNotificationTapped
			if codeType == "createNotification"
				if getJsonHash(codeContent, @oTmpHash)
					id := getHField(oTmpHash, "id")
					title := getHField(oTmpHash, "title")
					message := getHField(oTmpHash, "message")
					oMobile:CreateNotification(id, title, message)
				else
					_msgAlert("createNotification command not executed", "CloudBridge")
				endif
				return
			endif
			// Abre configuracoes
			                EndIf

                return
            endif

            // Verifica dispositivos pareados
            if codeType == "openSettings"
				oWebEngine:runJavaScript("openSettings")
				oMobile:OpenSettings(val(codeContent))
				return
			endif
			
			// Recupera diretorio temporario 
			if codeType == "getTempPath"
				fnCallBack = codeContent + "('" + oMobile:GetTempPath() + "');"
				oWebEngine:runJavaScript(fnCallBack)
			endif
			
			// Aciona o vibracall do dispositivo 
			if codeType == "vibrate"
				oMobile:vibrate(val(codeContent))
			endif
			
			// Efetua uma leitura no sensor de acelerômetro do dispositivo 
			if codeType == "readAccelerometer"
				aAccelerometerSensor:= oMobile:ReadAccelerometer()
				sMsg := "Valores lidos do sensor acelerometro (m/s2):" + "\n"
				sMsg += "x:" + str(aAccelerometerSensor[1]) + "\n"
				sMsg += "y:" + str(aAccelerometerSensor[2]) + "\n"
				sMsg += "z:" + str(aAccelerometerSensor[3])
				_conout("accelerometer - " + sMsg)
				// Executa o CallBack
				fnCallBack = codeContent+"('" +sMsg+ "')"
				oWebEngine:runJavaScript(fnCallBack)
				return
			endif
			// Pre-insere um contato da agenda do dispositivo 
			if codeType == "addContact"
				if getJsonHash(codeContent, @oTmpHash)
					aEmails := {}
					aPhones := {}
					aPostals := {}
					oTMobCont := TMobileContact():New()
					oTMobCont:cName := getHField(oTmpHash, "name")
					oTMobCont:cCompany := getHField(oTmpHash, "company")
					oTMobCont:cJobTitle := getHField(oTmpHash, "jobTitle")
					oTMobCont:cNote := getHField(oTmpHash, "note")
					cEmail1 := getHField(oTmpHash, "email1")
					nEmailType1 := getHField(oTmpHash, "emailType1")
					aAdd( aEmails, TMobileContactEmail():New2( nEmailType1, cEmail1 ) )
					cPhone1 := getHField(oTmpHash, "phone1")
					nPhoneType1 := getHField(oTmpHash, "phoneType1")
					aAdd( aPhones, TMobileContactPhone():New2( nPhoneType1, cPhone1 ) )
					aAdd( aPostals, TMobileContactPostal():New2( 2, getHField(oTmpHash, "postal") ) )
					oTMobCont:aEmails := aEmails
					oTMobCont:aPhones := aPhones
					oTMobCont:aPostals := aPostals
					oMobile:AddContact( oTMobCont )
				else
					_msgAlert("addContact command not executed", "CloudBridge")
				endif
				return
			endif
		endif
		if codeType == "change_link"
			oGetLink:cText := codeContent+space(1000)
			return
		endif
		// SQLITE - BEGIN -----------------------------------------------------------------------------
		// SQLITE - Begin transction
		if codeType == "dbBegin" .and. getJsonHash(codeContent, @oTmpHash)
			if TCSQLExec("BEGIN") < 0
				// Executa o CallBack de ERRO
				fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
				oWebEngine:runJavaScript(fnCallBack)
			else
				// Executa o CallBack de SUCESSO
				fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
				oWebEngine:runJavaScript(fnCallBack)
			endif
		endif
		// SQLITE - Commit
		if codeType == "dbCommit" .and. getJsonHash(codeContent, @oTmpHash)
			if TCSQLExec("COMMIT") < 0
				pairedDevices"
                aDevicesResult:= oMobile:GetPairedBluetoothDevices()

                sMsg := ""
                For i := 1 to len(aDevicesResult)
                    sMsg := sMsg + "Nome: " + aDevicesResult[i][1] + chr(13)
                    sMsg := sMsg + "Endereço: " + aDevicesResult[i][2] + chr(13) + chr(13)
                Next i

                If sMsg = ""
                    sMsg := "Nenhum dispositivo pareado ou interface Bluetooth desligada."
                Else
                    sMsg := "Dispositivos Bluetooth Pareados:" + chr(13) + chr(13) + sMsg
                EndIf
                _conout("[bluetooth] - " + sMsg)

                // Executa o CallBack
                fnCallBack = codeContent+"('" +SubStr(sMsg,1,30)+ "')"
                oWebEngine:runJavaScript(fnCallBack)
                return
            endif

            // Libera orientacao
            if codeType == "unlockOrientation"
                oMobile:SetScreenOrientation(-1)
                _conout("[unlockOrientation]")
                return
            endif

            // Trava orientacao
            if codeType == "lockOrientation"
                oMobile:SetScreenOrientation(2)
                _conout("[lockOrientation]")
                return
            endif

            // GPS
            if codeType == "getCurrentPosition"
                cPosition := oMobile:getGeoCoordinate(1)

                // PARA LIMPAR O SINAL DE GRAUS CHR(176)
                //cPosition := StrTran(cPosition, chr(176), "")

                _conout("[getCurrentPosition] - " + cPosition)

                // Executa o CallBack
                fnCallBack = codeContent+"('" +cPosition+ "')"
                oWebEngine:runJavaScript(fnCallBack)
                return
            endif

            // Testa perifericos
            if codeType == "testDevice"
                if getJsonHash(codeContent, @oTmpHash)
                    lRet := oMobile:TestDevice(getHField(oTmpHash, "testFeature"))

                    // Executa o CallBack
                    fnCallBack = getHField(oTmpHash, "callBack")+"('" +cValToChar(lRet)+ "')"
                    oWebEngine:runJavaScript(fnCallBack)
                else
                    _msgAlert("testDevice command not executed", "CloudBridge")
                endif
                return
            endif

            // Cria notificacao
            // O callBack sera disparado pelo bloco de codigo bNotificationTapped
            if codeType == "createNotification"
                if getJsonHash(codeContent, @oTmpHash)
                    id := getHField(oTmpHash, "id")
                    title := getHField(oTmpHash, "title")
                    message := getHField(oTmpHash, "message")
                    oMobile:CreateNotification(id, title, message)
                else
                    _msgAlert("createNotification command not executed", "CloudBridge")
                endif
                return
            endif

            // Abre configuracoes
            if codeType == "openSettings"
                oWebEngine:runJavaScript("openSettings")

                oMobile:OpenSettings(val(codeContent))
                return
            endif
            
            // Recupera diretorio temporario 
            if codeType == "getTempPath"
                fnCallBack = codeContent + "('" + oMobile:GetTempPath() + "');"
                oWebEngine:runJavaScript(fnCallBack)
            endif
            
            // Aciona o vibracall do dispositivo 
            if codeType == "vibrate"
                oMobile:vibrate(val(codeContent))
            endif
            
            // Efetua uma leitura no sensor de acelerômetro do dispositivo 
            if codeType == "readAccelerometer"
                aAccelerometerSensor:= oMobile:ReadAccelerometer()

                sMsg := "Valores lidos do sensor acelerometro (m/s2):" + "\n"
                sMsg += "x:" + str(aAccelerometerSensor[1]) + "\n"
                sMsg += "y:" + str(aAccelerometerSensor[2]) + "\n"
                sMsg += "z:" + str(aAccelerometerSensor[3])

                _conout("accelerometer - " + sMsg)

                // Executa o CallBack
                fnCallBack = codeContent+"('" +sMsg+ "')"
                oWebEngine:runJavaScript(fnCallBack)
                return
            endif

            // Pre-insere um contato da agenda do dispositivo 
            if codeType == "addContact"
                if getJsonHash(codeContent, @oTmpHash)
                    aEmails := {}
                    aPhones := {}
                    aPostals := {}

                    oTMobCont := TMobileContact():New()
                    oTMobCont:cName := getHField(oTmpHash, "name")
                    oTMobCont:cCompany := getHField(oTmpHash, "company")
                    oTMobCont:cJobTitle := getHField(oTmpHash, "jobTitle")
                    oTMobCont:cNote := getHField(oTmpHash, "note")

                    cEmail1 := getHField(oTmpHash, "email1")
                    nEmailType1 := getHField(oTmpHash, "emailType1")
                    aAdd( aEmails, TMobileContactEmail():New2( nEmailType1, cEmail1 ) )

                    cPhone1 := getHField(oTmpHash, "phone1")
                    nPhoneType1 := getHField(oTmpHash, "phoneType1")
                    aAdd( aPhones, TMobileContactPhone():New2( nPhoneType1, cPhone1 ) )

                    aAdd( aPostals, TMobileContactPostal():New2( 2, getHField(oTmpHash, "postal") ) )

                    oTMobCont:aEmails := aEmails
                    oTMobCont:aPhones := aPhones
                    oTMobCont:aPostals := aPostals

                    oMobile:AddContact( oTMobCont )
                else
                    _msgAlert("addContact command not executed", "CloudBridge")
                endif
                return
            endif
            
            // Procura contatos no dispositivo
            if codeType == "findContact"
                if getJsonHash(codeContent, @oTmpHash)
                    aContacts := {}

                    oTMobCont := TMobileContact():New()
                    aContacts := oTMobCont:FindContact( getHField( oTmpHash, "filter" ) )
                    VarInfo( "Contatos encontrados", aContacts )
                else
                    _msgAlert("findContact command not executed", "CloudBridge")
                endif
                return
            endif

        endif

        if codeType == "change_link"
            oGetLink:cText := codeContent+space(1000)
            return
        endif

        // SQLITE - BEGIN -----------------------------------------------------------------------------

        // SQLITE - Begin transction
        if codeType == "dbBegin" .and. getJsonHash(codeContent, @oTmpHash)
            if TCSQLExec("BEGIN") < 0
                // Executa o CallBack de ERRO
                fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
                oWebEngine:runJavaScript(fnCallBack)
            else
                // Executa o CallBack de SUCESSO
                fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
                oWebEngine:runJavaScript(fnCallBack)
            endif
        endif

        // SQLITE - Commit
        if codeType == "dbCommit" .and. getJsonHash(codeContent, @oTmpHash)
            if TCSQLExec("COMMIT") < 0
                // Executa o CallBack de ERRO
                fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
                oWebEngine:runJavaScript(fnCallBack)
            else
                // Executa o CallBack de SUCESSO
                fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
                oWebEngine:runJavaScript(fnCallBack)
            endif
        endif

        // SQLITE - RollBack
        if codeType == "dbRollback" .and. getJsonHash(codeContent, @oTmpHash)
            if TCSQLExec("ROLLBACK") < 0
                // Executa o CallBack de ERRO
                fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
                oWebEngine:runJavaScript(fnCallBack)
            else
                // Executa o CallBack de SUCESSO
                fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
                oWebEngine:runJavaScript(fnCallBack)
            endif
        endif

        // SQLITE - Executa query
        if codeType == "dbExec"
            if getJsonHash(codeContent, @oTmpHash)
                cQuery := getHField(oTmpHash, "query")

                // Testa query
                if TCSQLExec(cQuery) < 0
                    // Executa o CallBack de ERRO
				                    fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
				                    oWebEngine:runJavaScript(fnCallBack)
			else
				                else
                    // Executa o CallBack de SUCESSO
				                    fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
				                    oWebEngine:runJavaScript(fnCallBack)
			endif
		endif
		// SQLITE - RollBack
		if codeType == "dbRollback" .and. getJsonHash(codeContent, @oTmpHash)
			if TCSQLExec("ROLLBACK") < 0
				// Executa o CallBack de ERRO
				fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
				oWebEngine:runJavaScript(fnCallBack)
			else
				// Executa o CallBack de SUCESSO
				fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
				oWebEngine:runJavaScript(fnCallBack)
			endif
		endif
		                endif
            else
                _msgAlert("dbExec command not executed", "CloudBridge")
            endif
        endif

        // SQLITE - Recupera Executadados da query
		        if codeType == "dbExecdbGet"
			            if getJsonHash(codeContent, @oTmpHash)
				                cQuery := getHField(oTmpHash, "query")
				// Testa query
				if TCSQLExec(cQuery) < 0
					

                // Testa query
                if TCSQLExec(cQuery) < 0
                    // Executa o CallBack de ERRO
					fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
					oWebEngine:runJavaScript(fnCallBack)
				else
					// Executa o CallBack de SUCESSO
					                    fnCallBack = getHField(oTmpHash, "callBackSuccesscallBackError") + "('" +TcSqlError()+ "');"
					                    oWebEngine:runJavaScript(fnCallBack)
				endif
			else
				_msgAlert("dbExec command not executed", "CloudBridge")
			endif
		endif
		// SQLITE - Recupera dados da query
		if codeType == "dbGet"
			if getJsonHash(codeContent, @oTmpHash)
				cQuery := getHField(oTmpHash, "query")
				// Testa query
				if TCSQLExec(cQuery) < 0
					// Executa o CallBack de ERRO
					fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
					oWebEngine:runJavaScript(fnCallBack)
					return
				endif
				
                    return
                endif

                // Recupera os dados
				                dbUseArea(.T., 'TOPCONN', TCGenQry(,,cQuery),'TRB', .F., .T.)
				'TRB', .F., .T.)

                nFields := TRB->(fCount())
				                nRecords := TRB->(recCount())
				                xRet := "["
				                while !TRB->(eof())
					                    xRet += '{'
					

                    for i :=  1 to nFields
						                        xRet += quotedStr( fieldName(i) ) )+":"
						+":"
                        xRet += quotedStr( fieldGet(i) ) + iif(i < nFields, ",", "")
					next i
					                    next i

                    xRet += '}' + iif(TRB->(recno()) < nRecords, ",", "")
					)) < nRecords, ",", "")
                    TRB->(DbSkip())
				end
				                end
                xRet += "]"
				                TRB->(dbCloseArea())
				
                // Executa o CallBack
				                fnCallBack = getHField(oTmpHash, "callBackSuccess") + "(" +xRet+ ");"
				                oWebEngine:runJavaScript(fnCallBack)
			else
				            else
                _msgAlert("dbGet command not executed", "CloudBridge")
			endif
		endif
		            endif
        endif
        // SQLITE - END -----------------------------------------------------------------------------
		

        if codeType == "page_started"
			            //form:loadForm()
		endif
	endif
return        endif

    endif

return

// Cria componentes superiores
static function CreateFormTop(pnTop)
	    // ---------------------------------------------------------------
	    Local oButton1
	    Local cLink := mainHtml + space(1000)
	    Local oFontBtn := TFont():New("Arial Narrow",,022,,.F.,,,,,.F.,.F.)
	    Local oFontGet := TFont():New("Arial",,022,,.F.,,,,,.F.,.F.)
	
    oWebEngine:navigate(mainHtml)

	    @ 000, 221 BUTTON oButtonL1 PROMPT "<" SIZE 028, 011 OF pnTop ACTION {|| oWebEngine:goBack() } FONT oFontBtn PIXEL
	    @ 000, 221 BUTTON oButtonL2 PROMPT ">" SIZE 028, 011 OF pnTop ACTION {|| oWebEngine:goForward() } FONT oFontBtn PIXEL

	    oGetLink := TGet():New( 000, 000, { | u | If( PCount() == 0, cLink, cLink := u ) },pnTop, 220, 011,,, 0, 16777215,,.F.,,.T.,,.F.,,.F.,.F.,,.F.,.F. ,,"cLink",,,, )
	    oGetLink:setFont(oFontGet)
	
    @ 000, 221 BUTTON oButton1 PROMPT "Go" SIZE 028, 011 OF pnTop ACTION {|| oWebEngine:navigate(cLink) } FONT oFontBtn PIXEL
	    @ 000, 221 BUTTON oButton2 PROMPT "Menu" SIZE 028, 011 OF pnTop ACTION {|| oGetLink:cText:=mainHtml, oMultGet:Load(""), oWebEngine:Navigate(mainHtml) } FONT oFontBtn PIXEL

	    @ 000, 221 BUTTON oButtonClose PROMPT "X" SIZE 028, 011 OF pnTop ACTION {|| oDlg:end() } FONT oFontBtn PIXEL
	    oButtonClose:setCSS("QPushButton{margin: 1px; background-color: #C75050; border: none; color: #fff; }")

	    oGetLink:setCSS("QLineEdit{margin: 1px; border: 1px solid "+_colorTOTVS)

	    oButtonL1:Align     	:= CONTROL_ALIGN_LEFT
	    oButtonL2:Align     	:= CONTROL_ALIGN_LEFT
	    oButtonClose:Align    	 := CONTROL_ALIGN_RIGHT
	    oButton2:Align 		         := CONTROL_ALIGN_RIGHT
	    oButton1:Align 		         := CONTROL_ALIGN_RIGHT
	    oGetLink:Align 		         := CONTROL_ALIGN_ALLCLIENT

return

// ---------------------------------------------------------------
// Funcoes de apoio
// ---------------------------------------------------------------
static function _conout(cText)
	    conOut(cText)
	    oMultGet:Load(cText)
Return

Static function _msgAlert(cText)
	    // Android Ou iOS
	    if _rmtType == 8 .Or. _rmtType == 9
		        oMobile:CreateNotification(999, "CloudBridge", cText)
	    else
		        msgAlert(cText)
		        conout(cText)
	    endif
Return

static function quotedStr(xText)
return ('"'+ cValToChar(xText) +'"')