Página 1 de 2

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 08:33
por asimoes
Pessoal,

Isso é um teste quero ver se é possível.

A pergunta é: tem como ler esse ini sem ter que gerar um arquivo para ser lido pela função Hwg_GetIni ou equivalente?

Obs.: o arquivo teste.ini é gerado com sucesso (cópia do config.ini).

Tenho esse arquivo ini :
config.ini

Código: Selecionar todos

[AMBIENTE]
HARBOUR=3.4
[DATABASE]
RDD=DBFCDX
PATH=.\DB
No resource file TESTE.RC

CONFIG RCDATA CONFIG.INI

Para ler o resource:

Código: Selecionar todos

#define RT_RCDATA       (10)

cIni     := Hb_LoadResourceRawFile ( "CONFIG", RT_RCDATA  )

hb_MemoWrit( "TESTE.INI", cIni )

cPath := Hwg_GetIni( 'DATABASE', 'PATH' ,'', hb_DirBase()+"TESTE.INI")

#pragma BEGINDUMP
#include <Windows.h>
#include <hbApi.h>

HB_FUNC( RESTOFILE )
{
 static HRSRC hr;
 static HGLOBAL hg;

 hr = FindResource( NULL, (LPSTR) hb_parc( 1 ), RT_RCDATA );
 if( ! ( hr == 0 ) )
   {
    hg = LoadResource( NULL, hr );
    if( ! ( hg == 0 ) )
      {
       char *lpRcData=( char *)LockResource( hg );
       hb_retc( lpRcData );
      }
   }
}

//        HMG_LoadResourceRawFile ( cFileName, cTypeResource | nTypeResourceID )
HB_FUNC ( HB_LOADRESOURCERAWFILE )
{
   HRSRC   hResourceData;
   HGLOBAL hGlobalResource;
   LPVOID  lpGlobalResource = NULL;
   DWORD   nFileSize;
   TCHAR   *FileName     = (TCHAR*) hb_parc(1);
   TCHAR   *TypeResource = HB_ISCHAR (2) ? (TCHAR*) hb_parc(2) : MAKEINTRESOURCE ( hb_parni(2) );

   hResourceData = FindResource ( NULL, FileName, TypeResource );
   if ( hResourceData != NULL )
   {
       hGlobalResource = LoadResource ( NULL, hResourceData );
       if ( hGlobalResource != NULL )
       {
           lpGlobalResource = LockResource ( hGlobalResource );
           if ( lpGlobalResource != NULL ) 
           {
               nFileSize = SizeofResource ( NULL, hResourceData );
               hb_retclen ( (const CHAR *) lpGlobalResource, (HB_SIZE) nFileSize );
           }
           FreeResource ( hGlobalResource );
       }
   }

   if ( lpGlobalResource == NULL )
        hb_retclen ( (const CHAR *) NULL, (HB_SIZE) 0 );
}

#pragma ENDDUMP

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 08:55
por asimoes
Imagem do debug:
Imagem do debug
Imagem do debug

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 09:20
por asimoes
Com aTokens:= hb_Atokens(cIni, Chr(13)+Chr(10))

Já consegui um vetor:
Com hb_ATokens
Com hb_ATokens

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 09:24
por JoséQuintas
Se vai colocar no EXE, é sinal de que já sabe o conteúdo do INI.
Não vejo pra que isso.

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 09:28
por asimoes
A finalidade é substituir arquivos de memória por exemplo:

SAVE TO CONFIG.MEM ALL LIKE *

Este ini pode conter até ter senhas criptografadas para uso diversos.

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 09:32
por asimoes
Bom a minha questão é ler agora o Vetor e montar uma função.

No meu caso a pasta do executável em produção é somente leitura, não temos acesso.
Embutir certas informações para o executável facilita.

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 11:22
por asimoes
Consegui montar a função, espero ser útil para alguém.

cIni := Hb_LoadResourceRawFile ( "CONFIG", RT_RCDATA )

cVersao:=LerIni(cIni, "AMBIENTE", "HARBOUR")

Código: Selecionar todos

FUNCTION LerIni(cBuffer, cSecao, cVar)
LOCAL aTokens, nSecao, I

   hb_Default(@cBuffer, "")
   hb_Default(@cSecao, "")
   hb_Default(@cVar, "")

   aTokens:= hb_Atokens(cBuffer, Chr(13)+Chr(10))

   IF Len(aTokens) != 0 
      nSecao := aScan(aTokens, "["+cSecao+"]")
      IF nSecao != 0
         FOR I:=nSecao +1  TO Len(aTokens) 
            IF hb_At("[", aTokens[i]) > 0 // se achou outra seção finaliza
               EXIT
            ENDIF
            IF !Empty(aTokens[i])
               cVariavel  := RTrim(SubStr(aTokens[i], 1, At("=", aTokens[i])-1))
               IF Upper(cVariavel) == Upper(cVar)
                  cValor     := '"'+hb_ValToStr(SubStr(aTokens[i], At("=", aTokens[i])+1))+'"'
                  &cVariavel.:= &cValor.
                  RETURN &cVariavel.
               ENDIF
            ENDIF
         NEXT
      ENDIF
   ENDIF
RETURN ""

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 12:33
por JoséQuintas
Vamos a outra questão:
Como vai embutir o INI no EXE? Na compilação?

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 12:54
por asimoes
Na compilação,

Em um .rc

No meu teste: teste.rc

Informo no hbp

teste.rc

CONFIG RCDATA CONFIG.INI

Na compilação o resource é "embutido" no executável.

Ou

FUNCTION GravaIni()
#pragma __binarystreaminclude "config.ini" | RETURN %s

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 12:56
por asimoes
Para ler:

cIni:=GravaIni()

cRdd :=LerIni(cIni, "AMBIENTE", "variavel")

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 13:20
por asimoes
A principio pode embutir qualquer arquivo para o executável até dbf só não sei como usar, mas fiz um teste aqui e o dbf foi embutido no exe.

Tem que analisar as possibilidades de uso, lebrando que isso implica no tamanho final do exe

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 13:36
por JoséQuintas
Então.
Porque não um PRG?
Se de qualquer forma vai compilar, deixa no fonte, ou como opção no projeto.

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 14:05
por asimoes
Outra coisa interessante que pode colocar no executável um script harbour.

Exemplo:

harbour @hbscript.clp -gh -n -i\hb32fork\include

hbscript.clp

Código: Selecionar todos

FUNCAO1.PRG
FUNCAO2.PRG
Para executar o script:
dempo.prg

Código: Selecionar todos

#define HB_HRB_BIND_DEFAULT 0x0 
FUNCTION MAIN
   REQUEST DBUSEAREA, HB_Default, hwg_MsgInfo
   pHrb := hb_HrbLoad(HB_HRB_BIND_DEFAULT, "hbscript.hrb" )
   pExec1 := hb_hrbGetFunSym(pHrb, 'PROG1')
   pExec2 := hb_hrbGetFunSym(pHrb, 'PROG2')
   cTeste:="Valor inicial"
   pExec2:Eval(@cTeste)
   hwg_msginfo(cTeste)
   hwg_msginfo(pExec1:Eval("FUNÇÃO 1"),"Retorno da função 1 ")
RETURN NIL
Var gerar o arquivo hbscript.hrb este arquivo pode ser embutido no executável.

FUNCAO1.PRG

Código: Selecionar todos

FUNCTION PROG1(cMensagem)
LOCAL cTeste
HB_Default(@cMensagem,"")
   CLS
   hwg_MsgInfo(cMensagem, 'Atenção')
   //hwg_MsgInfo('estou executando HRB','Atenção')
   //USE APC01 ALIAS APC01
   //dbedit()
   //CLS
   //? alias()
   //? APC01->Codigo,APC01->Nome
   u_Return1 := 'SCRIPT 1'
RETURN u_Return1
FUNCAO2.PRG

Código: Selecionar todos

FUNCTION PROG2(cMensagem)
HB_Default(@cMensagem,"")
   hwg_msginfo(cMensagem)
   cMensagem:="mudou o valor"   
RETURN Nil

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 19:04
por asimoes
As funções que vão ser utilizadas nos scripts tem que ter o REQUEST na aplicação chamadora a que vai fazer hb_HrbLoad.

O sistema pode ter várias rotinas externas e podem ser usadas quando necessário, isso diminui significamente o tamanho do executável.

Ler um arquivo INI de um resource file (.rc)

Enviado: 16 Jan 2016 19:21
por asimoes
Para não esquecer nenhum REQUEST das funções do harbour pode fazer assim:

REQUEST __HB_EXTERN__

Qualquer outra função que seja usada que não seja das libs do harbour

REQUEST hwg_MsgInfo, hwg_MsgStop //Se compilado com HWGUI
REQUEST MsgInfo, MsgStop //Se compilado com MiniGui (*)

Pode ser até função da própria aplicação chamadora que irá ser usada no script.

Ex.:

REQUEST JANELA

Código: Selecionar todos

FUNCTION JANELA
  hb_gtReload( "WVT" )
  HB_gtInfo(HB_GTI_WINTITLE, "JANELA THREAD")
  SETMODE(10, 40)
  SETCURSOR(0)
  nSec := Seconds()
  @ 00, 00 SAY cPublica COLOR "W+/N"
  DO WHILE .T.
     @ 05, 00 SAY Time() COLOR "W+/N"
     IF Seconds()-nSec > 5
        EXIT
     ENDIF
  ENDDO
 RETURN Nil