Attachments
Attachments
Code: Select all
C:\core\contrib\hbmysql>set HB_WITH_MYSQL=C:\MariaDB\include\mysql
C:\core\contrib\hbmysql>buildsystem hbmysql.hbp
[INFO] BuildSystem
[BUILD] C:\WorkSpace\harbour64\bin\hbmk2.exe hbmysql.hbp
hbmk2: Procesando opciones de entorno: -comp=mingw64
hbmk2: Dependencia 'mysql' encontrada: C:\MariaDB\include\mysql
hbmk2[hbmysql]: Advertencia: Fuentes de Biblioteca de importación no se
encontraron.
hbmk2: Harbour: Compilando módulos...
Harbour 3.2.1dev (r2607071005)
Copyright (c) 1999-2025, https://harbour.github.io/
Compiling 'hbmysql.hbx'...
Lines 63, Functions/Procedures 1
Generating C source output to '.hbmk\win\mingw64\hbmysql.c'... Done.
Compiling 'tmysql.prg'...
Lines 2477, Functions/Procedures 54
Generating C source output to '.hbmk\win\mingw64\tmysql.c'... Done.
Compiling 'tsqlbrw.prg'...
Lines 1674, Functions/Procedures 9
Generating C source output to '.hbmk\win\mingw64\tsqlbrw.c'... Done.
hbmk2: Compilando...
hbmk2: Creando librería estática... libhbmysql.a
[INFO] Build session: 20260819-145748-212653965468152
[INFO] Build log: C:\WorkSpace\logs\build\20260819-145748-212653965468152\raw.log
[INFO] Build completed.
C:\core\contrib\hbmysql>Code: Select all
C:\core\contrib\hbmysql>set HB_WITH_MYSQL=C:\MariaDB\include\mysql
C:\core\contrib\hbmysql>buildsystem hbmysql.hbp
[INFO] BuildSystem
[BUILD] C:\WorkSpace\harbour64\bin\hbmk2.exe hbmysql.hbp
hbmk2: Procesando opciones de entorno: -comp=mingw64
hbmk2: Dependencia 'mysql' encontrada: C:\MariaDB\include\mysql
hbmk2[hbmysql]: Advertencia: Fuentes de Biblioteca de importación no se
encontraron.
hbmk2: Harbour: Compilando módulos...
Harbour 3.2.1dev (r2607071005)
Copyright (c) 1999-2025, https://harbour.github.io/
Compiling 'hbmysql.hbx'...
Lines 63, Functions/Procedures 1
Generating C source output to '.hbmk\win\mingw64\hbmysql.c'... Done.
Compiling 'tmysql.prg'...
Lines 2477, Functions/Procedures 54
Generating C source output to '.hbmk\win\mingw64\tmysql.c'... Done.
Compiling 'tsqlbrw.prg'...
Lines 1674, Functions/Procedures 9
Generating C source output to '.hbmk\win\mingw64\tsqlbrw.c'... Done.
hbmk2: Compilando...
hbmk2: Creando librería estática... libhbmysql.a
[INFO] Build session: 20260819-145748-212653965468152
[INFO] Build log: C:\WorkSpace\logs\build\20260819-145748-212653965468152\raw.log
[INFO] Build completed.
C:\core\contrib\hbmysql>Code: Select all
C:\Users\danie>cd C:\core\contrib\hbmysql
C:\core\contrib\hbmysql>set path=%path%;c:\Workspace\bin
C:\core\contrib\hbmysql>set HB_WITH_MYSQL=CC:\MariaDB\include\mysql
C:\core\contrib\hbmysql>buildsystem hbmysql.hbp
[INFO] BuildSystem
[BUILD] C:\WorkSpace\harbour64\bin\hbmk2.exe hbmysql.hbp
hbmk2: Procesando opciones de entorno: -comp=mingw64
hbmk2: Dependencia 'mysql' encontrada: C:\MariaDB\include\mysql
hbmk2: Encontrado archivo .lib con formto COFF con el mismo nombre, se recurre
a usar éste en lugar de la .dll.
hbmk2: Biblioteca de importación creada: liblibmariadb.a <=
C:\MariaDB\lib\libmariadb.lib
hbmk2: Creando librería estática... libhbmysql.a
[INFO] Build session: 20260819-160327-212653969407261
[INFO] Build log: C:\WorkSpace\logs\build\20260819-160327-212653969407261\raw.log
[INFO] Build completed.Code: Select all
C:\Users\danie>cd C:\core\contrib\hbmysql
C:\core\contrib\hbmysql>set path=%path%;c:\Workspace\bin
C:\core\contrib\hbmysql>set HB_WITH_MYSQL=CC:\MariaDB\include\mysql
C:\core\contrib\hbmysql>buildsystem hbmysql.hbp
[INFO] BuildSystem
[BUILD] C:\WorkSpace\harbour64\bin\hbmk2.exe hbmysql.hbp
hbmk2: Procesando opciones de entorno: -comp=mingw64
hbmk2: Dependencia 'mysql' encontrada: C:\MariaDB\include\mysql
hbmk2: Encontrado archivo .lib con formto COFF con el mismo nombre, se recurre
a usar éste en lugar de la .dll.
hbmk2: Biblioteca de importación creada: liblibmariadb.a <=
C:\MariaDB\lib\libmariadb.lib
hbmk2: Creando librería estática... libhbmysql.a
[INFO] Build session: 20260819-160327-212653969407261
[INFO] Build log: C:\WorkSpace\logs\build\20260819-160327-212653969407261\raw.log
[INFO] Build completed.Attachments
Attachments
Attachments
Attachments
Solo necesito esas dos funciones de la librería de momento. Alguna idea o información de si algo cambió. Gracias anticipadas y saludos.hbmk2: Error: Función(es) referenciada, no encontrada, pero desconocida:
BT_BITMAPTEXTWIDTH(), BT_BITMAPTEXTHEIGHT()
I only need those two functions from the library for the time being. Any ideas or information on whether something has changed? Thanks in advance.]]>hbmk2: Error: Referenced function(s) not found:
BT_BITMAPTEXTWIDTH(), BT_BITMAPTEXTHEIGHT()
Solo necesito esas dos funciones de la librería de momento. Alguna idea o información de si algo cambió. Gracias anticipadas y saludos.hbmk2: Error: Función(es) referenciada, no encontrada, pero desconocida:
BT_BITMAPTEXTWIDTH(), BT_BITMAPTEXTHEIGHT()
I only need those two functions from the library for the time being. Any ideas or information on whether something has changed? Thanks in advance.]]>hbmk2: Error: Referenced function(s) not found:
BT_BITMAPTEXTWIDTH(), BT_BITMAPTEXTHEIGHT()
Code: Select all
FUNCTION hb_UnzipFile( cFileName, bUpdate, lWithPath, cPassword, cPath, acFiles, bProgress )
LOCAL lRetVal := .T.
LOCAL hUnzip
LOCAL nErr
LOCAL nPos
LOCAL cZipName
LOCAL lExtract
LOCAL hHandle
LOCAL nSize
LOCAL nRead
LOCAL nLen
LOCAL dDate
LOCAL cTime
LOCAL cBuffer := Space( t_nReadBuffer )
LOCAL cTarget
LOCAL cDir
IF hb_defaultValue( lWithPath, .F. ) .AND. ! hb_DirExists( cPath ) .AND. ! Zip_MakeDirTree( cPath )
lRetVal := .F.
ENDIF
IF Empty( cPassword )
cPassword := NIL
ENDIF
IF Set( _SET_DEFEXTENSIONS )
cFileName := hb_FNameExtSetDef( cFileName, ".zip" )
ENDIF
IF Empty( hUnzip := hb_unzipOpen( cFileName ) )
lRetVal := .F.
ELSE
IF HB_ISNUMERIC( acFiles ) .OR. HB_ISSTRING( acFiles )
acFiles := { acFiles }
ENDIF
IF Empty( cPath )
cPath := hb_FNameDir( cFileName )
ENDIF
cPath := hb_DirSepAdd( cPath )
nPos := 0
nErr := hb_unzipFileFirst( hUnzip )
DO WHILE nErr == 0
nPos++
IF hb_unzipFileInfo( hUnzip, @cZipName, @dDate, @cTime,,,, @nSize ) == 0
lExtract := Empty( acFiles ) .OR. ;
AScan( acFiles, nPos ) > 0 .OR. ;
AScan( acFiles, {| cMask | hb_FileMatch( cZipName, cMask ) } ) > 0
IF lExtract
cTarget := cPath + cZipName
IF Right( cZipName, 1 ) == "/" .OR. Right( cZipName, 1 ) == "\"
/* FIX (3): entrada de directorio → crear el directorio,
no intentar FCreate() sobre un nombre con separador final */
IF ! Zip_MakeDirTree( cTarget )
lRetVal := .F.
ENDIF
ELSE
/* FIX (1)+(2): crear TODOS los directorios intermedios
antes de FCreate(), y NO silenciar el fallo */
cDir := hb_FNameDir( cTarget )
IF ! Empty( cDir ) .AND. ! Zip_MakeDirTree( cDir )
lRetVal := .F.
ELSEIF ( hHandle := FCreate( cTarget ) ) == F_ERROR
lRetVal := .F.
ELSE
IF hb_unzipFileOpen( hUnzip, cPassword ) != UNZ_OK
lRetVal := .F.
FClose( hHandle )
EXIT
ENDIF
nRead := 0
DO WHILE ( nLen := hb_unzipFileRead( hUnzip, @cBuffer, hb_BLen( cBuffer ) ) ) > 0
/* FIX (4): verificar la escritura */
IF FWrite( hHandle, cBuffer, nLen ) != nLen
lRetVal := .F.
ENDIF
IF HB_ISEVALITEM( bProgress )
nRead += nLen
Eval( bProgress, nRead, nSize )
ENDIF
ENDDO
hb_unzipFileClose( hUnzip )
FClose( hHandle )
hb_FSetDateTime( cTarget, dDate, cTime )
IF HB_ISEVALITEM( bUpdate )
Eval( bUpdate, cZipName, nPos )
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
nErr := hb_unzipFileNext( hUnzip )
ENDDO
hb_unzipClose( hUnzip )
ENDIF
RETURN lRetVal
STATIC FUNCTION Zip_MakeDirTree( cDir )
IF Empty( cDir )
RETURN .F.
ENDIF
IF hb_DirExists( cDir )
RETURN .T.
ENDIF
/* hb_DirBuild() crea el árbol completo, nivel por nivel */
hb_DirBuild( cDir )
RETURN hb_DirExists( cDir )Code: Select all
FUNCTION hb_UnzipFile( cFileName, bUpdate, lWithPath, cPassword, cPath, acFiles, bProgress )
LOCAL lRetVal := .T.
LOCAL hUnzip
LOCAL nErr
LOCAL nPos
LOCAL cZipName
LOCAL lExtract
LOCAL hHandle
LOCAL nSize
LOCAL nRead
LOCAL nLen
LOCAL dDate
LOCAL cTime
LOCAL cBuffer := Space( t_nReadBuffer )
IF hb_defaultValue( lWithPath, .F. ) .AND. ! hb_DirExists( cPath ) .AND. hb_DirCreate( cPath ) != 0
lRetVal := .F.
ENDIF
IF Empty( cPassword )
cPassword := NIL
ENDIF
IF Set( _SET_DEFEXTENSIONS )
cFileName := hb_FNameExtSetDef( cFileName, ".zip" )
ENDIF
IF Empty( hUnzip := hb_unzipOpen( cFileName ) )
lRetVal := .F.
ELSE
IF HB_ISNUMERIC( acFiles ) .OR. ;
HB_ISSTRING( acFiles )
acFiles := { acFiles }
ENDIF
IF Empty( cPath )
cPath := hb_FNameDir( cFileName )
ENDIF
cPath := hb_DirSepAdd( cPath )
nPos := 0
nErr := hb_unzipFileFirst( hUnzip )
DO WHILE nErr == 0
nPos++
IF hb_unzipFileInfo( hUnzip, @cZipName, @dDate, @cTime,,,, @nSize ) == 0
/* NOTE: As opposed to original hbziparch we don't do a second match without path. */
lExtract := Empty( acFiles ) .OR. ;
AScan( acFiles, nPos ) > 0 .OR. ;
AScan( acFiles, {| cMask | hb_FileMatch( cZipName, cMask ) } ) > 0
IF lExtract .AND. ( hHandle := FCreate( cPath + cZipName ) ) != F_ERROR
IF hb_unzipFileOpen( hUnzip, cPassword ) != UNZ_OK
lRetVal := .F.
EXIT
ENDIF
nRead := 0
DO WHILE ( nLen := hb_unzipFileRead( hUnzip, @cBuffer, hb_BLen( cBuffer ) ) ) > 0
IF HB_ISEVALITEM( bProgress )
nRead += nLen
Eval( bProgress, nRead, nSize )
ENDIF
FWrite( hHandle, cBuffer, nLen )
ENDDO
hb_unzipFileClose( hUnzip )
FClose( hHandle )
hb_FSetDateTime( cPath + cZipName, dDate, cTime )
IF HB_ISEVALITEM( bUpdate )
Eval( bUpdate, cZipName, nPos )
ENDIF
ENDIF
ENDIF
nErr := hb_unzipFileNext( hUnzip )
ENDDO
hb_unzipClose( hUnzip )
ENDIF
RETURN lRetValCode: Select all
FUNCTION hb_UnzipFile( cFileName, bUpdate, lWithPath, cPassword, cPath, acFiles, bProgress )
LOCAL lRetVal := .T.
LOCAL hUnzip
LOCAL nErr
LOCAL nPos
LOCAL cZipName
LOCAL lExtract
LOCAL hHandle
LOCAL nSize
LOCAL nRead
LOCAL nLen
LOCAL dDate
LOCAL cTime
LOCAL cBuffer := Space( t_nReadBuffer )
LOCAL cTarget
LOCAL cDir
IF hb_defaultValue( lWithPath, .F. ) .AND. ! hb_DirExists( cPath ) .AND. ! Zip_MakeDirTree( cPath )
lRetVal := .F.
ENDIF
IF Empty( cPassword )
cPassword := NIL
ENDIF
IF Set( _SET_DEFEXTENSIONS )
cFileName := hb_FNameExtSetDef( cFileName, ".zip" )
ENDIF
IF Empty( hUnzip := hb_unzipOpen( cFileName ) )
lRetVal := .F.
ELSE
IF HB_ISNUMERIC( acFiles ) .OR. HB_ISSTRING( acFiles )
acFiles := { acFiles }
ENDIF
IF Empty( cPath )
cPath := hb_FNameDir( cFileName )
ENDIF
cPath := hb_DirSepAdd( cPath )
nPos := 0
nErr := hb_unzipFileFirst( hUnzip )
DO WHILE nErr == 0
nPos++
IF hb_unzipFileInfo( hUnzip, @cZipName, @dDate, @cTime,,,, @nSize ) == 0
lExtract := Empty( acFiles ) .OR. ;
AScan( acFiles, nPos ) > 0 .OR. ;
AScan( acFiles, {| cMask | hb_FileMatch( cZipName, cMask ) } ) > 0
IF lExtract
cTarget := cPath + cZipName
IF Right( cZipName, 1 ) == "/" .OR. Right( cZipName, 1 ) == "\"
/* FIX (3): entrada de directorio → crear el directorio,
no intentar FCreate() sobre un nombre con separador final */
IF ! Zip_MakeDirTree( cTarget )
lRetVal := .F.
ENDIF
ELSE
/* FIX (1)+(2): crear TODOS los directorios intermedios
antes de FCreate(), y NO silenciar el fallo */
cDir := hb_FNameDir( cTarget )
IF ! Empty( cDir ) .AND. ! Zip_MakeDirTree( cDir )
lRetVal := .F.
ELSEIF ( hHandle := FCreate( cTarget ) ) == F_ERROR
lRetVal := .F.
ELSE
IF hb_unzipFileOpen( hUnzip, cPassword ) != UNZ_OK
lRetVal := .F.
FClose( hHandle )
EXIT
ENDIF
nRead := 0
DO WHILE ( nLen := hb_unzipFileRead( hUnzip, @cBuffer, hb_BLen( cBuffer ) ) ) > 0
/* FIX (4): verificar la escritura */
IF FWrite( hHandle, cBuffer, nLen ) != nLen
lRetVal := .F.
ENDIF
IF HB_ISEVALITEM( bProgress )
nRead += nLen
Eval( bProgress, nRead, nSize )
ENDIF
ENDDO
hb_unzipFileClose( hUnzip )
FClose( hHandle )
hb_FSetDateTime( cTarget, dDate, cTime )
IF HB_ISEVALITEM( bUpdate )
Eval( bUpdate, cZipName, nPos )
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
nErr := hb_unzipFileNext( hUnzip )
ENDDO
hb_unzipClose( hUnzip )
ENDIF
RETURN lRetVal
STATIC FUNCTION Zip_MakeDirTree( cDir )
IF Empty( cDir )
RETURN .F.
ENDIF
IF hb_DirExists( cDir )
RETURN .T.
ENDIF
/* hb_DirBuild() crea el árbol completo, nivel por nivel */
hb_DirBuild( cDir )
RETURN hb_DirExists( cDir )Code: Select all
FUNCTION hb_UnzipFile( cFileName, bUpdate, lWithPath, cPassword, cPath, acFiles, bProgress )
LOCAL lRetVal := .T.
LOCAL hUnzip
LOCAL nErr
LOCAL nPos
LOCAL cZipName
LOCAL lExtract
LOCAL hHandle
LOCAL nSize
LOCAL nRead
LOCAL nLen
LOCAL dDate
LOCAL cTime
LOCAL cBuffer := Space( t_nReadBuffer )
IF hb_defaultValue( lWithPath, .F. ) .AND. ! hb_DirExists( cPath ) .AND. hb_DirCreate( cPath ) != 0
lRetVal := .F.
ENDIF
IF Empty( cPassword )
cPassword := NIL
ENDIF
IF Set( _SET_DEFEXTENSIONS )
cFileName := hb_FNameExtSetDef( cFileName, ".zip" )
ENDIF
IF Empty( hUnzip := hb_unzipOpen( cFileName ) )
lRetVal := .F.
ELSE
IF HB_ISNUMERIC( acFiles ) .OR. ;
HB_ISSTRING( acFiles )
acFiles := { acFiles }
ENDIF
IF Empty( cPath )
cPath := hb_FNameDir( cFileName )
ENDIF
cPath := hb_DirSepAdd( cPath )
nPos := 0
nErr := hb_unzipFileFirst( hUnzip )
DO WHILE nErr == 0
nPos++
IF hb_unzipFileInfo( hUnzip, @cZipName, @dDate, @cTime,,,, @nSize ) == 0
/* NOTE: As opposed to original hbziparch we don't do a second match without path. */
lExtract := Empty( acFiles ) .OR. ;
AScan( acFiles, nPos ) > 0 .OR. ;
AScan( acFiles, {| cMask | hb_FileMatch( cZipName, cMask ) } ) > 0
IF lExtract .AND. ( hHandle := FCreate( cPath + cZipName ) ) != F_ERROR
IF hb_unzipFileOpen( hUnzip, cPassword ) != UNZ_OK
lRetVal := .F.
EXIT
ENDIF
nRead := 0
DO WHILE ( nLen := hb_unzipFileRead( hUnzip, @cBuffer, hb_BLen( cBuffer ) ) ) > 0
IF HB_ISEVALITEM( bProgress )
nRead += nLen
Eval( bProgress, nRead, nSize )
ENDIF
FWrite( hHandle, cBuffer, nLen )
ENDDO
hb_unzipFileClose( hUnzip )
FClose( hHandle )
hb_FSetDateTime( cPath + cZipName, dDate, cTime )
IF HB_ISEVALITEM( bUpdate )
Eval( bUpdate, cZipName, nPos )
ENDIF
ENDIF
ENDIF
nErr := hb_unzipFileNext( hUnzip )
ENDDO
hb_unzipClose( hUnzip )
ENDIF
RETURN lRetValCode: Select all
// Ejemplo de inicialización y uso del driver personalizado en Harbour
REQUEST DBFCDX
PROCEDURE Main()
LOCAL aStruct
// Registrar el driver si estás extendiendo DBFCDX
// Set ( _SET_DEFAULT_RDD, "VFPLET" )
// 1. Crear una tabla estilo VFP con campos largos usando la API de Harbour
aStruct := { ;
{ "CODIGO_CLIENTE_PRINCIPAL", "C", 10, 0 }, ;
{ "NOMBRE_COMPLETO_DEL_USUARIO", "C", 50, 0 }, ;
{ "FECHA_ULTIMA_TRANSACCION", "D", 8, 0 } ;
}
// Creación usando la función extendida de Harbour que soporta diccionarios
hb_dbCreate( "clientes_vfp.dbf", aStruct, "DBFCDX" )
? "Tabla creada con éxito con nombres de campo de más de 10 caracteres."
RETURN]]>Code: Select all
// Ejemplo de inicialización y uso del driver personalizado en Harbour
REQUEST DBFCDX
PROCEDURE Main()
LOCAL aStruct
// Registrar el driver si estás extendiendo DBFCDX
// Set ( _SET_DEFAULT_RDD, "VFPLET" )
// 1. Crear una tabla estilo VFP con campos largos usando la API de Harbour
aStruct := { ;
{ "CODIGO_CLIENTE_PRINCIPAL", "C", 10, 0 }, ;
{ "NOMBRE_COMPLETO_DEL_USUARIO", "C", 50, 0 }, ;
{ "FECHA_ULTIMA_TRANSACCION", "D", 8, 0 } ;
}
// Creación usando la función extendida de Harbour que soporta diccionarios
hb_dbCreate( "clientes_vfp.dbf", aStruct, "DBFCDX" )
? "Tabla creada con éxito con nombres de campo de más de 10 caracteres."
RETURN]]>Code: Select all
#include "hbclass.ch"
// Simulación de lectura de tabla VFP con mapeo de campos largos
CLASS VfpTable
DATA cDbcPath
DATA cTable
DATA aFieldMap INIT {=>} // Hash: NombreLargo -> NombreCorto
METHOD New( cDbc, cTable )
METHOD Open()
METHOD FieldGet( cLongName )
METHOD FieldPut( cLongName, xVal )
ENDCLASS
METHOD New( cDbc, cTable ) CLASS VfpTable
::cDbcPath := cDbc
::cTable := cTable
// Ejemplo: Mapeo manual o extraído dinámicamente del archivo .dbc
::aFieldMap["NOMBRE_COMPLETO_CLIENTE"] := "NOMB_CLI"
::aFieldMap["CODIGO_IDENTIFICACION"] := "COD_ID"
RETURN Self
METHOD Open() CLASS VfpTable
USE ( ::cTable ) VIA "DBFCDX" SHARED
RETURN NIL
METHOD FieldGet( cLongName ) CLASS VfpTable
LOCAL cShortName := ::aFieldMap[ Upper( cLongName ) ]
RETURN FieldGet( FieldPos( cShortName ) )
METHOD FieldPut( cLongName, xVal ) CLASS VfpTable
LOCAL cShortName := ::aFieldMap[ Upper( cLongName ) ]
RETURN FieldPut( FieldPos( cShortName ), xVal )Code: Select all
#include "hbclass.ch"
// Simulación de lectura de tabla VFP con mapeo de campos largos
CLASS VfpTable
DATA cDbcPath
DATA cTable
DATA aFieldMap INIT {=>} // Hash: NombreLargo -> NombreCorto
METHOD New( cDbc, cTable )
METHOD Open()
METHOD FieldGet( cLongName )
METHOD FieldPut( cLongName, xVal )
ENDCLASS
METHOD New( cDbc, cTable ) CLASS VfpTable
::cDbcPath := cDbc
::cTable := cTable
// Ejemplo: Mapeo manual o extraído dinámicamente del archivo .dbc
::aFieldMap["NOMBRE_COMPLETO_CLIENTE"] := "NOMB_CLI"
::aFieldMap["CODIGO_IDENTIFICACION"] := "COD_ID"
RETURN Self
METHOD Open() CLASS VfpTable
USE ( ::cTable ) VIA "DBFCDX" SHARED
RETURN NIL
METHOD FieldGet( cLongName ) CLASS VfpTable
LOCAL cShortName := ::aFieldMap[ Upper( cLongName ) ]
RETURN FieldGet( FieldPos( cShortName ) )
METHOD FieldPut( cLongName, xVal ) CLASS VfpTable
LOCAL cShortName := ::aFieldMap[ Upper( cLongName ) ]
RETURN FieldPut( FieldPos( cShortName ), xVal )Attachments
Attachments
Code: Select all
C:\Proyectos\Sample\ClientServerVFP\ThreeTierSPT\threetier.exeCode: Select all
cd C:\Proyectos\Sample
read C:\Proyectos\Sample\ClientServerVFP\ThreeTierSPTCode: Select all
C:\Proyectos\Sample\ClientServerVFP\ThreeTierSPT\threetier.exeCode: Select all
cd C:\Proyectos\Sample
read C:\Proyectos\Sample\ClientServerVFP\ThreeTierSPTCode: Select all
// Level 1: Root -> Level 2: Module -> Level 3: Collection or Attribute
hDOM["agenda"]["ultimo_id"] := 3Code: Select all
// Level 1: Root -> Level 2: Module -> Level 3: Collection or Attribute
hDOM["agenda"]["ultimo_id"] := 3Code: Select all
hDOM["configuration"] := { "theme" => "dark", "language" => "EN" }Attachments
Code: Select all
hDOM["configuration"] := { "theme" => "dark", "language" => "EN" }Attachments
Code: Select all
#include "fileio.ch"
PROCEDURE Main()
// Configuración de codepage para acentos en consola
// Codepage setting for accented characters in console
hb_cdpSelect( "UTF8" )
// Declaramos la variable global/pública
// Declare global/public variable
PUBLIC hDOM
hDOM := {=>}
// Inicializamos el contenedor principal de la agenda
// Initialize main agenda container
hDOM["agenda"] := {=>}
hDOM["agenda"]["contactos"] := {=>}
hDOM["agenda"]["ultimo_id"] := 0
? "=== AGENDA EN HARBOUR / HARBOUR AGENDA ===" [cite: 2]
?
// 1. Cargar contactos de ejemplo / Load sample contacts [cite: 3]
AgregarContacto("Juan Pérez", "11-4444-5555", "juan@email.com")
AgregarContacto("María Gómez", "11-6666-7777", "maria@email.com")
AgregarContacto("Carlos López", "11-8888-9999", "carlos@email.com")
// 2. Listar contactos / List contacts
ListarContactos()
// 3. Buscar contacto por ID / Search contact by ID
BuscarContacto(2)
// 4. Exportar la estructura completa a un archivo JSON
// Export the full structure to a JSON file
?
? "========================================" [cite: 4]
? " Export the full structure to a JSON file / Exportar la estructura completa a un archivo JSON"
? "========================================" [cite: 5]
GuardarAgendaJSON("agenda.json")
// 5. Cargar y deserializar desde el archivo JSON
// Load and deserialize from the JSON file
?
? "========================================" [cite: 6]
? " Load and deserialize from the JSON file / Cargar y deserializar desde el archivo JSON"
? "========================================" [cite: 7]
CargarAgendaJSON("agenda.json")
RETURN
// ----------------------------------------------------------------------
// Función para agregar un nuevo contacto al Hash Map
// Function to add a new contact to the Hash Map
// ----------------------------------------------------------------------
FUNCTION AgregarContacto( cNombre, cTelefono, cEmail )
LOCAL nNuevoId
LOCAL cIdKey
LOCAL hNuevoContacto
hDOM["agenda"]["ultimo_id"]++
nNuevoId := hDOM["agenda"]["ultimo_id"]
cIdKey := LTrim(Str(nNuevoId))
hNuevoContacto := {=>}
hNuevoContacto["id"] := nNuevoId
hNuevoContacto["name"] := cNombre
hNuevoContacto["phone"] := cTelefono
hNuevoContacto["email"] := cEmail
hDOM["agenda"]["contactos"][ cIdKey ] := hNuevoContacto
? "--> Contacto agregado con éxito! / Contact added successfully! ID: " + cIdKey [cite: 8]
RETURN Nil
// ----------------------------------------------------------------------
// Función para recorrer y listar los contactos
// Function to iterate through and list contacts
// ----------------------------------------------------------------------
FUNCTION ListarContactos()
LOCAL cIdKey
LOCAL hContacto
?
? "========================================" [cite: 9]
? " LISTA DE CONTACTOS / CONTACT LIST" [cite: 9]
? "========================================" [cite: 10]
FOR EACH cIdKey IN hDOM["agenda"]["contactos"]:Keys
hContacto := hDOM["agenda"]["contactos"][ cIdKey ]
? "ID : " + LTrim(Str(hContacto["id"])) [cite: 11]
? "Name : " + hContacto["name"] [cite: 12]
? "Tel : " + hContacto["phone"] [cite: 13]
? "Email : " + hContacto["email"] [cite: 14]
? "----------------------------------------" [cite: 15]
NEXT
RETURN Nil
// ----------------------------------------------------------------------
// Función para consultar un contacto por su ID
// Function to query a contact by ID
// ----------------------------------------------------------------------
FUNCTION BuscarContacto( nId )
LOCAL cIdKey := LTrim(Str(nId))
LOCAL hContacto
?
IF hb_HHasKey( hDOM["agenda"]["contactos"], cIdKey ) [cite: 16]
hContacto := hDOM["agenda"]["contactos"][ cIdKey ]
? ">>> BÚSQUEDA DEL CONTACTO / CONTACT SEARCH ID " + cIdKey + ":" [cite: 17]
? "Encontrado / Found: " + hContacto["name"] + " | Tel: " + hContacto["phone"] [cite: 18]
ELSE
? "El contacto con ID " + cIdKey + " no existe. / Contact ID does not exist." [cite: 19]
ENDIF [cite: 20]
RETURN Nil
// ----------------------------------------------------------------------
// Función para serializar hDOM y guardarlo en archivo .json
// Function to serialize hDOM and save it into a .json file
// ----------------------------------------------------------------------
FUNCTION GuardarAgendaJSON( cNombreArchivo )
LOCAL cJsonTexto := ""
cJsonTexto := HB_ToJSON( hDOM )
IF Empty( cJsonTexto )
? "--> Error: La cadena JSON está vacía. / Error: JSON string is empty." [cite: 21]
RETURN .F.
ENDIF
// hb_MemoWrit escribe el buffer directamente a disco sin lidiar con pointers de C
// hb_MemoWrit writes the buffer directly to disk without dealing with C pointers
IF hb_MemoWrit( cNombreArchivo, cJsonTexto )
? "--> Agenda guardada en JSON con éxito / Agenda successfully saved to JSON: " + cNombreArchivo [cite: 22]
RETURN .T.
ELSE
? "--> Error al escribir el archivo en disco. / Error writing file to disk." [cite: 23]
ENDIF
RETURN .F.
// ----------------------------------------------------------------------
// Función para leer el archivo .json y reconstruir hDOM
// Function to read the .json file and rebuild hDOM
// ----------------------------------------------------------------------
FUNCTION CargarAgendaJSON( cNombreArchivo )
LOCAL cContenido := ""
LOCAL hResultado := {=>}
IF !hb_FileExists( cNombreArchivo )
? "--> No se encontró el archivo JSON / JSON file not found: " + cNombreArchivo [cite: 25]
RETURN hResultado
ENDIF
cContenido := hb_MemoRead( cNombreArchivo )
IF !Empty( cContenido )
hb_jsonDecode( cContenido, @hResultado )
IF !Empty( hResultado )
? "--> Archivo JSON leído y reconstruido correctamente. / JSON file read and rebuilt successfully." [cite: 26]
? "--> Total contactos en JSON / Total contacts in JSON: " + LTrim(Str(Len(hResultado["agenda"]["contactos"])))
ELSE
? "--> El contenido del archivo JSON no pudo procesarse. / JSON file content could not be processed." [cite: 27]
ENDIF
ELSE
? "--> El archivo JSON está vacío. / JSON file is empty." [cite: 28]
ENDIF
RETURN hResultado
// ----------------------------------------------------------------------
// Serializador JSON en Harbour Puro
// Pure Harbour JSON Serializer
// ----------------------------------------------------------------------
FUNCTION HB_ToJSON( xVal, nIndent )
LOCAL cType := ValType( xVal )
LOCAL cJson := ""
LOCAL cKey, i, nLen
LOCAL cPad := ""
IF nIndent == Nil
nIndent := 0
ENDIF
cPad := Space( nIndent * 2 )
DO CASE
CASE cType == "H" // Hash Map / Diccionario (Dictionary)
cJson := "{" + hb_eol()
nLen := Len( xVal )
i := 0
FOR EACH cKey IN xVal:Keys
i++
cJson += cPad + " " + '"' + hb_ValToStr( cKey ) + '": ' + HB_ToJSON( xVal[ cKey ], nIndent + 1 )
IF i < nLen
cJson += ","
ENDIF
cJson += hb_eol() [cite: 30]
NEXT
cJson += cPad + "}"
CASE cType == "A" // Array / Lista (List)
cJson := "[" + hb_eol()
nLen := Len( xVal )
FOR i := 1 TO nLen
cJson += cPad + " " + HB_ToJSON( xVal[ i ], nIndent + 1 )
IF i < nLen
cJson += "," [cite: 31]
ENDIF
cJson += hb_eol()
NEXT
cJson += cPad + "]"
CASE cType == "C" // Cadena de texto / String
cJson := '"' + StrTran( StrTran( xVal, "\", "\\" ), '"', '\"' ) + '"'
CASE cType == "N" // Número / Number
cJson := LTrim( Str( xVal ) )
CASE cType == "L" // Booleano / Boolean
cJson := IIF( xVal, "true", "false" ) [cite: 32]
OTHERWISE
cJson := "null"
ENDCASE
RETURN cJson]]>Code: Select all
#include "fileio.ch"
PROCEDURE Main()
// Configuración de codepage para acentos en consola
// Codepage setting for accented characters in console
hb_cdpSelect( "UTF8" )
// Declaramos la variable global/pública
// Declare global/public variable
PUBLIC hDOM
hDOM := {=>}
// Inicializamos el contenedor principal de la agenda
// Initialize main agenda container
hDOM["agenda"] := {=>}
hDOM["agenda"]["contactos"] := {=>}
hDOM["agenda"]["ultimo_id"] := 0
? "=== AGENDA EN HARBOUR / HARBOUR AGENDA ===" [cite: 2]
?
// 1. Cargar contactos de ejemplo / Load sample contacts [cite: 3]
AgregarContacto("Juan Pérez", "11-4444-5555", "juan@email.com")
AgregarContacto("María Gómez", "11-6666-7777", "maria@email.com")
AgregarContacto("Carlos López", "11-8888-9999", "carlos@email.com")
// 2. Listar contactos / List contacts
ListarContactos()
// 3. Buscar contacto por ID / Search contact by ID
BuscarContacto(2)
// 4. Exportar la estructura completa a un archivo JSON
// Export the full structure to a JSON file
?
? "========================================" [cite: 4]
? " Export the full structure to a JSON file / Exportar la estructura completa a un archivo JSON"
? "========================================" [cite: 5]
GuardarAgendaJSON("agenda.json")
// 5. Cargar y deserializar desde el archivo JSON
// Load and deserialize from the JSON file
?
? "========================================" [cite: 6]
? " Load and deserialize from the JSON file / Cargar y deserializar desde el archivo JSON"
? "========================================" [cite: 7]
CargarAgendaJSON("agenda.json")
RETURN
// ----------------------------------------------------------------------
// Función para agregar un nuevo contacto al Hash Map
// Function to add a new contact to the Hash Map
// ----------------------------------------------------------------------
FUNCTION AgregarContacto( cNombre, cTelefono, cEmail )
LOCAL nNuevoId
LOCAL cIdKey
LOCAL hNuevoContacto
hDOM["agenda"]["ultimo_id"]++
nNuevoId := hDOM["agenda"]["ultimo_id"]
cIdKey := LTrim(Str(nNuevoId))
hNuevoContacto := {=>}
hNuevoContacto["id"] := nNuevoId
hNuevoContacto["name"] := cNombre
hNuevoContacto["phone"] := cTelefono
hNuevoContacto["email"] := cEmail
hDOM["agenda"]["contactos"][ cIdKey ] := hNuevoContacto
? "--> Contacto agregado con éxito! / Contact added successfully! ID: " + cIdKey [cite: 8]
RETURN Nil
// ----------------------------------------------------------------------
// Función para recorrer y listar los contactos
// Function to iterate through and list contacts
// ----------------------------------------------------------------------
FUNCTION ListarContactos()
LOCAL cIdKey
LOCAL hContacto
?
? "========================================" [cite: 9]
? " LISTA DE CONTACTOS / CONTACT LIST" [cite: 9]
? "========================================" [cite: 10]
FOR EACH cIdKey IN hDOM["agenda"]["contactos"]:Keys
hContacto := hDOM["agenda"]["contactos"][ cIdKey ]
? "ID : " + LTrim(Str(hContacto["id"])) [cite: 11]
? "Name : " + hContacto["name"] [cite: 12]
? "Tel : " + hContacto["phone"] [cite: 13]
? "Email : " + hContacto["email"] [cite: 14]
? "----------------------------------------" [cite: 15]
NEXT
RETURN Nil
// ----------------------------------------------------------------------
// Función para consultar un contacto por su ID
// Function to query a contact by ID
// ----------------------------------------------------------------------
FUNCTION BuscarContacto( nId )
LOCAL cIdKey := LTrim(Str(nId))
LOCAL hContacto
?
IF hb_HHasKey( hDOM["agenda"]["contactos"], cIdKey ) [cite: 16]
hContacto := hDOM["agenda"]["contactos"][ cIdKey ]
? ">>> BÚSQUEDA DEL CONTACTO / CONTACT SEARCH ID " + cIdKey + ":" [cite: 17]
? "Encontrado / Found: " + hContacto["name"] + " | Tel: " + hContacto["phone"] [cite: 18]
ELSE
? "El contacto con ID " + cIdKey + " no existe. / Contact ID does not exist." [cite: 19]
ENDIF [cite: 20]
RETURN Nil
// ----------------------------------------------------------------------
// Función para serializar hDOM y guardarlo en archivo .json
// Function to serialize hDOM and save it into a .json file
// ----------------------------------------------------------------------
FUNCTION GuardarAgendaJSON( cNombreArchivo )
LOCAL cJsonTexto := ""
cJsonTexto := HB_ToJSON( hDOM )
IF Empty( cJsonTexto )
? "--> Error: La cadena JSON está vacía. / Error: JSON string is empty." [cite: 21]
RETURN .F.
ENDIF
// hb_MemoWrit escribe el buffer directamente a disco sin lidiar con pointers de C
// hb_MemoWrit writes the buffer directly to disk without dealing with C pointers
IF hb_MemoWrit( cNombreArchivo, cJsonTexto )
? "--> Agenda guardada en JSON con éxito / Agenda successfully saved to JSON: " + cNombreArchivo [cite: 22]
RETURN .T.
ELSE
? "--> Error al escribir el archivo en disco. / Error writing file to disk." [cite: 23]
ENDIF
RETURN .F.
// ----------------------------------------------------------------------
// Función para leer el archivo .json y reconstruir hDOM
// Function to read the .json file and rebuild hDOM
// ----------------------------------------------------------------------
FUNCTION CargarAgendaJSON( cNombreArchivo )
LOCAL cContenido := ""
LOCAL hResultado := {=>}
IF !hb_FileExists( cNombreArchivo )
? "--> No se encontró el archivo JSON / JSON file not found: " + cNombreArchivo [cite: 25]
RETURN hResultado
ENDIF
cContenido := hb_MemoRead( cNombreArchivo )
IF !Empty( cContenido )
hb_jsonDecode( cContenido, @hResultado )
IF !Empty( hResultado )
? "--> Archivo JSON leído y reconstruido correctamente. / JSON file read and rebuilt successfully." [cite: 26]
? "--> Total contactos en JSON / Total contacts in JSON: " + LTrim(Str(Len(hResultado["agenda"]["contactos"])))
ELSE
? "--> El contenido del archivo JSON no pudo procesarse. / JSON file content could not be processed." [cite: 27]
ENDIF
ELSE
? "--> El archivo JSON está vacío. / JSON file is empty." [cite: 28]
ENDIF
RETURN hResultado
// ----------------------------------------------------------------------
// Serializador JSON en Harbour Puro
// Pure Harbour JSON Serializer
// ----------------------------------------------------------------------
FUNCTION HB_ToJSON( xVal, nIndent )
LOCAL cType := ValType( xVal )
LOCAL cJson := ""
LOCAL cKey, i, nLen
LOCAL cPad := ""
IF nIndent == Nil
nIndent := 0
ENDIF
cPad := Space( nIndent * 2 )
DO CASE
CASE cType == "H" // Hash Map / Diccionario (Dictionary)
cJson := "{" + hb_eol()
nLen := Len( xVal )
i := 0
FOR EACH cKey IN xVal:Keys
i++
cJson += cPad + " " + '"' + hb_ValToStr( cKey ) + '": ' + HB_ToJSON( xVal[ cKey ], nIndent + 1 )
IF i < nLen
cJson += ","
ENDIF
cJson += hb_eol() [cite: 30]
NEXT
cJson += cPad + "}"
CASE cType == "A" // Array / Lista (List)
cJson := "[" + hb_eol()
nLen := Len( xVal )
FOR i := 1 TO nLen
cJson += cPad + " " + HB_ToJSON( xVal[ i ], nIndent + 1 )
IF i < nLen
cJson += "," [cite: 31]
ENDIF
cJson += hb_eol()
NEXT
cJson += cPad + "]"
CASE cType == "C" // Cadena de texto / String
cJson := '"' + StrTran( StrTran( xVal, "\", "\\" ), '"', '\"' ) + '"'
CASE cType == "N" // Número / Number
cJson := LTrim( Str( xVal ) )
CASE cType == "L" // Booleano / Boolean
cJson := IIF( xVal, "true", "false" ) [cite: 32]
OTHERWISE
cJson := "null"
ENDCASE
RETURN cJson]]>Code: Select all
/*
* Agenda de Contatos (2)
* Humberto Fornazier - Março/2003
* hfornazier@brfree.com.br
*
* HMG - Harbour Win32 GUI library - Release 60
* Copyright 2002 Roberto Lopez <mail.box.hmg@gmail.com>
* http://www.hmgforum.com//
*
* Refactored to work with JSON instead of DBF files
* Refactorizado para trabajar con JSON en lugar de archivos DBF
*/
#include "hmg.ch"
#define BLUE { 0, 0, 128 }
PROCEDURE Main()
LOCAL i
// Codepage setting for console and GUI / Configuración de codepage
hb_cdpSelect( "UTF8" )
// Public global variable for memory DOM / Variable global pública para hDOM
PUBLIC hDOM
hDOM := {=>}
// Initialize or load JSON agenda / Inicializar o cargar la agenda JSON
CargarAgendaJSON( "agenda.json" )
PRIVATE lNovo := .F.
DEFINE WINDOW Form_1 ;
AT 0,0 ;
WIDTH 480 ;
HEIGHT 470 ;
TITLE "Agenda de Contactos / Contacts Agenda" ;
MAIN ;
NOMAXIMIZE ;
NOSIZE ;
ON RELEASE GuardarAgendaJSON( "agenda.json" ) ;
BACKCOLOR BLUE
// Index column (A-Z search) / Columna de índice (Búsqueda A-Z)
@ 010,415 GRID GIndice OF Form_1 ;
WIDTH 48 HEIGHT 360 ;
HEADERS {""} WIDTHS { 28 } ;
FONT "Arial" SIZE 09 BOLD ;
TOOLTIP "Click on desired letter / Click en la letra deseada" ;
ON CLICK Pesquisa_Agenda()
// Main contacts Grid / Grilla principal de contactos
@ 010,010 GRID Grid_Agenda ;
WIDTH 398 ;
HEIGHT 360 ;
HEADERS {"Código / Code", "Nome / Name"} ;
WIDTHS { 80, 290 } ;
FONT "Arial" SIZE 09 ;
ON DBLCLICK Novo_Registro( .F. )
// Action Buttons / Botones de acción
@ 385,010 BUTTON Btn_Novo OF Form_1 ;
CAPTION '&Novo / New' ;
ACTION Novo_Registro( .T. ) ;
WIDTH 120 HEIGHT 27 ;
FONT "Arial" SIZE 09 ;
TOOLTIP "New Record / Novo Registro" ;
FLAT
@ 385,165 BUTTON Btn_Imprimir OF Form_1 ;
CAPTION '&Imprimir / Print' ;
ACTION Imprimir() ;
WIDTH 120 HEIGHT 27 ;
FONT "Arial" SIZE 09 ;
TOOLTIP "Print Contacts / Imprimir Contatos" ;
FLAT
@ 385,318 BUTTON Btn_Sair OF Form_1 ;
CAPTION '&Sair / Exit' ;
ACTION Form_1.Release ;
WIDTH 120 HEIGHT 27 ;
FONT "Arial" SIZE 09 ;
TOOLTIP "Exit System / Finalizar Sistema" ;
FLAT
END WINDOW
// Populate A-Z index grid / Poblar el índice A-Z
FOR i := 1 TO 26
ADD ITEM { CHR( i + 64 ) } TO GIndice OF Form_1
NEXT
MODIFY CONTROL GIndice OF Form_1 VALUE 1
Pesquisa_Agenda()
CENTER WINDOW Form_1
ACTIVATE WINDOW Form_1
RETURN
// ----------------------------------------------------------------------
// Filter contacts by selected letter in hDOM
// Filtrar contactos en hDOM según la letra seleccionada
// ----------------------------------------------------------------------
FUNCTION Pesquisa_Agenda()
LOCAL cPesq := ValorDaColuna( "GIndice", "Form_1", 1 )
LOCAL cIdKey, hContacto, cNome
cPesq := IIf( Empty( cPesq ), "A", Upper( cPesq ) )
DELETE ITEM ALL FROM Grid_Agenda OF Form_1
IF hb_HHasKey( hDOM, "agenda" ) .AND. hb_HHasKey( hDOM["agenda"], "contactos" )
FOR EACH cIdKey IN hDOM["agenda"]["contactos"]:Keys
hContacto := hDOM["agenda"]["contactos"][ cIdKey ]
cNome := Upper( hb_HGetDef( hContacto, "name", "" ) )
IF Left( cNome, 1 ) == cPesq
ADD ITEM { cIdKey, hContacto["name"] } TO Grid_Agenda OF Form_1
ENDIF
NEXT
ENDIF
RETURN Nil
// ----------------------------------------------------------------------
// Open New / Edit Contact Form
// Abrir Formulario de Nuevo / Editar Contacto
// ----------------------------------------------------------------------
FUNCTION Novo_Registro( lNovo_Registro )
LOCAL cCodigo := ""
LOCAL cNome := ""
LOCAL cFone1 := ""
LOCAL cEmail := ""
LOCAL hContacto
Form_1.Btn_Novo.Enabled := .F.
Form_1.Btn_Sair.Enabled := .F.
lNovo := lNovo_Registro
IF !lNovo
cCodigo := ValorDaColuna( "Grid_Agenda", "Form_1", 1 )
IF Empty( cCodigo ) .OR. !hb_HHasKey( hDOM["agenda"]["contactos"], cCodigo )
MsgSTOP( "Record " + cCodigo + " not found! / Registro " + cCodigo + " no localizado!", "Agenda" )
Form_1.Btn_Novo.Enabled := .T.
Form_1.Btn_Sair.Enabled := .T.
RETURN Nil
ENDIF
hContacto := hDOM["agenda"]["contactos"][ cCodigo ]
cNome := AllTrim( hb_HGetDef( hContacto, "name", "" ) )
cFone1 := AllTrim( hb_HGetDef( hContacto, "phone", "" ) )
cEmail := AllTrim( hb_HGetDef( hContacto, "email", "" ) )
ENDIF
DEFINE WINDOW Form_2 ;
AT 0,0 ;
WIDTH 490 HEIGHT 230 ;
TITLE "Agenda - " + IIf( lNovo, "New Record / Nuevo Registro", "Editing / Editando " + cCodigo ) ;
MODAL NOSIZE ;
ON RELEASE {|| Form_1.Btn_Novo.Enabled := .T., Form_1.Btn_Sair.Enabled := .T., Pesquisa_Agenda(), Form_1.Grid_Agenda.SetFocus() } ;
BACKCOLOR WHITE
@ 10,10 LABEL Label_Codigo VALUE 'Código / Code' WIDTH 140 HEIGHT 25 FONT 'Arial' SIZE 09 BACKCOLOR WHITE FONTCOLOR BLUE BOLD
@ 40,10 LABEL Label_Nome VALUE 'Nome / Name' WIDTH 140 HEIGHT 25 FONT 'Arial' SIZE 09 BACKCOLOR WHITE FONTCOLOR BLUE BOLD
@ 70,10 LABEL Label_Fone1 VALUE 'Fone / Phone' WIDTH 140 HEIGHT 25 FONT 'Arial' SIZE 09 BACKCOLOR WHITE FONTCOLOR BLUE BOLD
@ 100,10 LABEL Label_Email VALUE 'e-mail' WIDTH 140 HEIGHT 25 FONT 'Arial' SIZE 09 BACKCOLOR WHITE FONTCOLOR BLUE BOLD
@ 10,120 TEXTBOX T_Codigo VALUE cCodigo WIDTH 60 TOOLTIP 'Code / Código'
@ 40,120 TEXTBOX T_Nome OF Form_2 WIDTH 330 VALUE cNome TOOLTIP 'Name / Nombre' MAXLENGTH 40 ON ENTER Form_2.T_Fone1.SetFocus
@ 70,120 TEXTBOX T_Fone1 OF Form_2 WIDTH 180 VALUE cFone1 TOOLTIP 'Phone / Teléfono' MAXLENGTH 20 ON ENTER Form_2.T_Email.SetFocus
@ 100,120 TEXTBOX T_Email OF Form_2 WIDTH 330 VALUE cEmail TOOLTIP 'E-mail' MAXLENGTH 40 LOWERCASE ON ENTER Form_2.Btn_Salvar.SetFocus
@ 150,40 BUTTON Btn_Salvar OF Form_2 CAPTION '&Salvar / Save' ACTION Salvar_Registro() WIDTH 120 HEIGHT 27 FONT "Arial" SIZE 09 FLAT
@ 150,180 BUTTON Btn_Excluir OF Form_2 CAPTION '&Deletar / Delete' ACTION Excluir_Registro() WIDTH 120 HEIGHT 27 FONT "Arial" SIZE 09 FLAT
@ 150,320 BUTTON Btn_Cancelar OF Form_2 CAPTION '&Cancelar / Cancel' ACTION Form_2.Release WIDTH 120 HEIGHT 27 FONT "Arial" SIZE 09 FLAT
END WINDOW
Form_2.T_Codigo.Enabled := .F.
IF lNovo
Form_2.Btn_Excluir.Enabled := .F.
ENDIF
CENTER WINDOW Form_2
ACTIVATE WINDOW Form_2
RETURN Nil
// ----------------------------------------------------------------------
// Save contact to hDOM memory structure
// Guardar contacto en la estructura hDOM en memoria
// ----------------------------------------------------------------------
FUNCTION Salvar_Registro()
LOCAL cCodigo := ""
LOCAL hNovoContacto
IF Empty( Form_2.T_Nome.Value )
MsgINFO( "Name not specified! / Nome não foi Informado!!", "Agenda" )
Form_2.T_Nome.SetFocus
RETURN Nil
ENDIF
IF lNovo
hDOM["agenda"]["ultimo_id"]++
cCodigo := LTrim( Str( hDOM["agenda"]["ultimo_id"] ) )
ELSE
cCodigo := Form_2.T_Codigo.Value
ENDIF
hNovoContacto := {=>}
hNovoContacto["id"] := Val( cCodigo )
hNovoContacto["name"] := Form_2.T_Nome.Value
hNovoContacto["phone"] := Form_2.T_Fone1.Value
hNovoContacto["email"] := Form_2.T_Email.Value
// Save/Update in hDOM Hash Map
hDOM["agenda"]["contactos"][ cCodigo ] := hNovoContacto
// Save directly to JSON disk file
GuardarAgendaJSON( "agenda.json" )
MsgINFO( "Record " + IIf( lNovo, "Saved / Incluído", "Updated / Alterado!" ), "Agenda" )
PosicionaIndice( Upper( Left( Form_2.T_Nome.Value, 1 ) ) )
Form_2.Release
RETURN Nil
// ----------------------------------------------------------------------
// Delete contact from hDOM and update JSON
// Eliminar contacto de hDOM y actualizar JSON
// ----------------------------------------------------------------------
FUNCTION Excluir_Registro()
LOCAL cCodigo := Form_2.T_Codigo.Value
IF MsgOkCancel( "Confirm record deletion? / Confirma Exclusão do Registro??", "Delete / Excluir" )
IF hb_HHasKey( hDOM["agenda"]["contactos"], cCodigo )
// Delete key from Hash Map
hb_HDel( hDOM["agenda"]["contactos"], cCodigo )
// Update JSON file
GuardarAgendaJSON( "agenda.json" )
MsgINFO( "Record deleted! / Registro Excluído!!", "Agenda" )
Form_2.Release
ENDIF
ENDIF
RETURN Nil
// ----------------------------------------------------------------------
// Load JSON or initialize default hDOM structure
// Cargar JSON o inicializar estructura hDOM por defecto
// ----------------------------------------------------------------------
FUNCTION CargarAgendaJSON( cNombreArchivo )
LOCAL cContenido := ""
LOCAL hResultado := {=>}
IF hb_FileExists( cNombreArchivo )
cContenido := hb_MemoRead( cNombreArchivo )
IF !Empty( cContenido )
hb_jsonDecode( cContenido, @hResultado )
IF !Empty( hResultado )
hDOM := hResultado
RETURN hDOM
ENDIF
ENDIF
ENDIF
// Default structure if file does not exist / Estructura por defecto si no existe
hDOM := {=>}
hDOM["agenda"] := {=>}
hDOM["agenda"]["contactos"] := {=>}
hDOM["agenda"]["ultimo_id"] := 0
RETURN hDOM
// ----------------------------------------------------------------------
// Save hDOM structure to JSON file
// Guardar estructura hDOM a archivo JSON
// ----------------------------------------------------------------------
FUNCTION GuardarAgendaJSON( cNombreArchivo )
LOCAL cJsonTexto := HB_ToJSON( hDOM )
IF !Empty( cJsonTexto )
RETURN hb_MemoWrit( cNombreArchivo, cJsonTexto )
ENDIF
RETURN .F.
// ----------------------------------------------------------------------
// JSON Pure Harbour Serializer / Serializador JSON en Harbour Puro
// ----------------------------------------------------------------------
FUNCTION HB_ToJSON( xVal, nIndent )
LOCAL cType := ValType( xVal )
LOCAL cJson := ""
LOCAL cKey, i, nLen
LOCAL cPad := ""
IF nIndent == Nil
nIndent := 0
ENDIF
cPad := Space( nIndent * 2 )
DO CASE
CASE cType == "H"
cJson := "{" + hb_eol()
nLen := Len( xVal )
i := 0
FOR EACH cKey IN xVal:Keys
i++
cJson += cPad + " " + '"' + hb_ValToStr( cKey ) + '": ' + HB_ToJSON( xVal[ cKey ], nIndent + 1 )
IF i < nLen
cJson += ","
ENDIF
cJson += hb_eol()
NEXT
cJson += cPad + "}"
CASE cType == "A"
cJson := "[" + hb_eol()
nLen := Len( xVal )
FOR i := 1 TO nLen
cJson += cPad + " " + HB_ToJSON( xVal[ i ], nIndent + 1 )
IF i < nLen
cJson += ","
ENDIF
cJson += hb_eol()
NEXT
cJson += cPad + "]"
CASE cType == "C"
cJson := '"' + StrTran( StrTran( xVal, "\", "\\" ), '"', '\"' ) + '"'
CASE cType == "N"
cJson := LTrim( Str( xVal ) )
CASE cType == "L"
cJson := IIF( xVal, "true", "false" )
OTHERWISE
cJson := "null"
ENDCASE
RETURN cJson
// ----------------------------------------------------------------------
// Helper functions for Grid navigation and Indexing
// Funciones auxiliares para la grilla e índices
// ----------------------------------------------------------------------
FUNCTION ValorDaColuna( ControlName, ParentForm, nCol )
LOCAL aRet := {}
IF GetControlType( ControlName, ParentForm ) != "GRID"
RETURN ""
ENDIF
nCol := IIf( nCol == Nil .OR. nCol == 0, 1, nCol )
aRet := GetProperty( ParentForm, ControlName, 'Item', GetProperty( ParentForm, ControlName, 'Value' ) )
IF ValType( aRet ) == "A" .AND. Len( aRet ) >= nCol
RETURN aRet[ nCol ]
ENDIF
RETURN ""
FUNCTION PosicionaIndice( cLetra )
LOCAL i := 0
FOR i := 1 TO 26
IF CHR( i + 64 ) == cLetra
MODIFY CONTROL GIndice OF Form_1 VALUE i
ENDIF
NEXT
Form_1.GIndice.SetFocus
RETURN Nil
FUNCTION Imprimir()
LOCAL cLetra := ValorDaColuna( "GIndice", "Form_1", 1 )
LOCAL cTxt := "=== CONTACTS LIST / LISTA DE CONTACTOS (" + cLetra + ") ===" + hb_eol() + hb_eol()
LOCAL cIdKey, hContacto
IF hb_HHasKey( hDOM, "agenda" ) .AND. hb_HHasKey( hDOM["agenda"], "contactos" )
FOR EACH cIdKey IN hDOM["agenda"]["contactos"]:Keys
hContacto := hDOM["agenda"]["contactos"][ cIdKey ]
IF Upper( Left( hContacto["name"], 1 ) ) == cLetra
cTxt += "ID: " + cIdKey + " | " + hContacto["name"] + " | Tel: " + hContacto["phone"] + hb_eol()
ENDIF
NEXT
ENDIF
MsgInfo( cTxt, "Print Preview / Vista de Impresión" )
RETURN NilCode: Select all
/*
* Agenda de Contatos (2)
* Humberto Fornazier - Março/2003
* hfornazier@brfree.com.br
*
* HMG - Harbour Win32 GUI library - Release 60
* Copyright 2002 Roberto Lopez <mail.box.hmg@gmail.com>
* http://www.hmgforum.com//
*
* Refactored to work with JSON instead of DBF files
* Refactorizado para trabajar con JSON en lugar de archivos DBF
*/
#include "hmg.ch"
#define BLUE { 0, 0, 128 }
PROCEDURE Main()
LOCAL i
// Codepage setting for console and GUI / Configuración de codepage
hb_cdpSelect( "UTF8" )
// Public global variable for memory DOM / Variable global pública para hDOM
PUBLIC hDOM
hDOM := {=>}
// Initialize or load JSON agenda / Inicializar o cargar la agenda JSON
CargarAgendaJSON( "agenda.json" )
PRIVATE lNovo := .F.
DEFINE WINDOW Form_1 ;
AT 0,0 ;
WIDTH 480 ;
HEIGHT 470 ;
TITLE "Agenda de Contactos / Contacts Agenda" ;
MAIN ;
NOMAXIMIZE ;
NOSIZE ;
ON RELEASE GuardarAgendaJSON( "agenda.json" ) ;
BACKCOLOR BLUE
// Index column (A-Z search) / Columna de índice (Búsqueda A-Z)
@ 010,415 GRID GIndice OF Form_1 ;
WIDTH 48 HEIGHT 360 ;
HEADERS {""} WIDTHS { 28 } ;
FONT "Arial" SIZE 09 BOLD ;
TOOLTIP "Click on desired letter / Click en la letra deseada" ;
ON CLICK Pesquisa_Agenda()
// Main contacts Grid / Grilla principal de contactos
@ 010,010 GRID Grid_Agenda ;
WIDTH 398 ;
HEIGHT 360 ;
HEADERS {"Código / Code", "Nome / Name"} ;
WIDTHS { 80, 290 } ;
FONT "Arial" SIZE 09 ;
ON DBLCLICK Novo_Registro( .F. )
// Action Buttons / Botones de acción
@ 385,010 BUTTON Btn_Novo OF Form_1 ;
CAPTION '&Novo / New' ;
ACTION Novo_Registro( .T. ) ;
WIDTH 120 HEIGHT 27 ;
FONT "Arial" SIZE 09 ;
TOOLTIP "New Record / Novo Registro" ;
FLAT
@ 385,165 BUTTON Btn_Imprimir OF Form_1 ;
CAPTION '&Imprimir / Print' ;
ACTION Imprimir() ;
WIDTH 120 HEIGHT 27 ;
FONT "Arial" SIZE 09 ;
TOOLTIP "Print Contacts / Imprimir Contatos" ;
FLAT
@ 385,318 BUTTON Btn_Sair OF Form_1 ;
CAPTION '&Sair / Exit' ;
ACTION Form_1.Release ;
WIDTH 120 HEIGHT 27 ;
FONT "Arial" SIZE 09 ;
TOOLTIP "Exit System / Finalizar Sistema" ;
FLAT
END WINDOW
// Populate A-Z index grid / Poblar el índice A-Z
FOR i := 1 TO 26
ADD ITEM { CHR( i + 64 ) } TO GIndice OF Form_1
NEXT
MODIFY CONTROL GIndice OF Form_1 VALUE 1
Pesquisa_Agenda()
CENTER WINDOW Form_1
ACTIVATE WINDOW Form_1
RETURN
// ----------------------------------------------------------------------
// Filter contacts by selected letter in hDOM
// Filtrar contactos en hDOM según la letra seleccionada
// ----------------------------------------------------------------------
FUNCTION Pesquisa_Agenda()
LOCAL cPesq := ValorDaColuna( "GIndice", "Form_1", 1 )
LOCAL cIdKey, hContacto, cNome
cPesq := IIf( Empty( cPesq ), "A", Upper( cPesq ) )
DELETE ITEM ALL FROM Grid_Agenda OF Form_1
IF hb_HHasKey( hDOM, "agenda" ) .AND. hb_HHasKey( hDOM["agenda"], "contactos" )
FOR EACH cIdKey IN hDOM["agenda"]["contactos"]:Keys
hContacto := hDOM["agenda"]["contactos"][ cIdKey ]
cNome := Upper( hb_HGetDef( hContacto, "name", "" ) )
IF Left( cNome, 1 ) == cPesq
ADD ITEM { cIdKey, hContacto["name"] } TO Grid_Agenda OF Form_1
ENDIF
NEXT
ENDIF
RETURN Nil
// ----------------------------------------------------------------------
// Open New / Edit Contact Form
// Abrir Formulario de Nuevo / Editar Contacto
// ----------------------------------------------------------------------
FUNCTION Novo_Registro( lNovo_Registro )
LOCAL cCodigo := ""
LOCAL cNome := ""
LOCAL cFone1 := ""
LOCAL cEmail := ""
LOCAL hContacto
Form_1.Btn_Novo.Enabled := .F.
Form_1.Btn_Sair.Enabled := .F.
lNovo := lNovo_Registro
IF !lNovo
cCodigo := ValorDaColuna( "Grid_Agenda", "Form_1", 1 )
IF Empty( cCodigo ) .OR. !hb_HHasKey( hDOM["agenda"]["contactos"], cCodigo )
MsgSTOP( "Record " + cCodigo + " not found! / Registro " + cCodigo + " no localizado!", "Agenda" )
Form_1.Btn_Novo.Enabled := .T.
Form_1.Btn_Sair.Enabled := .T.
RETURN Nil
ENDIF
hContacto := hDOM["agenda"]["contactos"][ cCodigo ]
cNome := AllTrim( hb_HGetDef( hContacto, "name", "" ) )
cFone1 := AllTrim( hb_HGetDef( hContacto, "phone", "" ) )
cEmail := AllTrim( hb_HGetDef( hContacto, "email", "" ) )
ENDIF
DEFINE WINDOW Form_2 ;
AT 0,0 ;
WIDTH 490 HEIGHT 230 ;
TITLE "Agenda - " + IIf( lNovo, "New Record / Nuevo Registro", "Editing / Editando " + cCodigo ) ;
MODAL NOSIZE ;
ON RELEASE {|| Form_1.Btn_Novo.Enabled := .T., Form_1.Btn_Sair.Enabled := .T., Pesquisa_Agenda(), Form_1.Grid_Agenda.SetFocus() } ;
BACKCOLOR WHITE
@ 10,10 LABEL Label_Codigo VALUE 'Código / Code' WIDTH 140 HEIGHT 25 FONT 'Arial' SIZE 09 BACKCOLOR WHITE FONTCOLOR BLUE BOLD
@ 40,10 LABEL Label_Nome VALUE 'Nome / Name' WIDTH 140 HEIGHT 25 FONT 'Arial' SIZE 09 BACKCOLOR WHITE FONTCOLOR BLUE BOLD
@ 70,10 LABEL Label_Fone1 VALUE 'Fone / Phone' WIDTH 140 HEIGHT 25 FONT 'Arial' SIZE 09 BACKCOLOR WHITE FONTCOLOR BLUE BOLD
@ 100,10 LABEL Label_Email VALUE 'e-mail' WIDTH 140 HEIGHT 25 FONT 'Arial' SIZE 09 BACKCOLOR WHITE FONTCOLOR BLUE BOLD
@ 10,120 TEXTBOX T_Codigo VALUE cCodigo WIDTH 60 TOOLTIP 'Code / Código'
@ 40,120 TEXTBOX T_Nome OF Form_2 WIDTH 330 VALUE cNome TOOLTIP 'Name / Nombre' MAXLENGTH 40 ON ENTER Form_2.T_Fone1.SetFocus
@ 70,120 TEXTBOX T_Fone1 OF Form_2 WIDTH 180 VALUE cFone1 TOOLTIP 'Phone / Teléfono' MAXLENGTH 20 ON ENTER Form_2.T_Email.SetFocus
@ 100,120 TEXTBOX T_Email OF Form_2 WIDTH 330 VALUE cEmail TOOLTIP 'E-mail' MAXLENGTH 40 LOWERCASE ON ENTER Form_2.Btn_Salvar.SetFocus
@ 150,40 BUTTON Btn_Salvar OF Form_2 CAPTION '&Salvar / Save' ACTION Salvar_Registro() WIDTH 120 HEIGHT 27 FONT "Arial" SIZE 09 FLAT
@ 150,180 BUTTON Btn_Excluir OF Form_2 CAPTION '&Deletar / Delete' ACTION Excluir_Registro() WIDTH 120 HEIGHT 27 FONT "Arial" SIZE 09 FLAT
@ 150,320 BUTTON Btn_Cancelar OF Form_2 CAPTION '&Cancelar / Cancel' ACTION Form_2.Release WIDTH 120 HEIGHT 27 FONT "Arial" SIZE 09 FLAT
END WINDOW
Form_2.T_Codigo.Enabled := .F.
IF lNovo
Form_2.Btn_Excluir.Enabled := .F.
ENDIF
CENTER WINDOW Form_2
ACTIVATE WINDOW Form_2
RETURN Nil
// ----------------------------------------------------------------------
// Save contact to hDOM memory structure
// Guardar contacto en la estructura hDOM en memoria
// ----------------------------------------------------------------------
FUNCTION Salvar_Registro()
LOCAL cCodigo := ""
LOCAL hNovoContacto
IF Empty( Form_2.T_Nome.Value )
MsgINFO( "Name not specified! / Nome não foi Informado!!", "Agenda" )
Form_2.T_Nome.SetFocus
RETURN Nil
ENDIF
IF lNovo
hDOM["agenda"]["ultimo_id"]++
cCodigo := LTrim( Str( hDOM["agenda"]["ultimo_id"] ) )
ELSE
cCodigo := Form_2.T_Codigo.Value
ENDIF
hNovoContacto := {=>}
hNovoContacto["id"] := Val( cCodigo )
hNovoContacto["name"] := Form_2.T_Nome.Value
hNovoContacto["phone"] := Form_2.T_Fone1.Value
hNovoContacto["email"] := Form_2.T_Email.Value
// Save/Update in hDOM Hash Map
hDOM["agenda"]["contactos"][ cCodigo ] := hNovoContacto
// Save directly to JSON disk file
GuardarAgendaJSON( "agenda.json" )
MsgINFO( "Record " + IIf( lNovo, "Saved / Incluído", "Updated / Alterado!" ), "Agenda" )
PosicionaIndice( Upper( Left( Form_2.T_Nome.Value, 1 ) ) )
Form_2.Release
RETURN Nil
// ----------------------------------------------------------------------
// Delete contact from hDOM and update JSON
// Eliminar contacto de hDOM y actualizar JSON
// ----------------------------------------------------------------------
FUNCTION Excluir_Registro()
LOCAL cCodigo := Form_2.T_Codigo.Value
IF MsgOkCancel( "Confirm record deletion? / Confirma Exclusão do Registro??", "Delete / Excluir" )
IF hb_HHasKey( hDOM["agenda"]["contactos"], cCodigo )
// Delete key from Hash Map
hb_HDel( hDOM["agenda"]["contactos"], cCodigo )
// Update JSON file
GuardarAgendaJSON( "agenda.json" )
MsgINFO( "Record deleted! / Registro Excluído!!", "Agenda" )
Form_2.Release
ENDIF
ENDIF
RETURN Nil
// ----------------------------------------------------------------------
// Load JSON or initialize default hDOM structure
// Cargar JSON o inicializar estructura hDOM por defecto
// ----------------------------------------------------------------------
FUNCTION CargarAgendaJSON( cNombreArchivo )
LOCAL cContenido := ""
LOCAL hResultado := {=>}
IF hb_FileExists( cNombreArchivo )
cContenido := hb_MemoRead( cNombreArchivo )
IF !Empty( cContenido )
hb_jsonDecode( cContenido, @hResultado )
IF !Empty( hResultado )
hDOM := hResultado
RETURN hDOM
ENDIF
ENDIF
ENDIF
// Default structure if file does not exist / Estructura por defecto si no existe
hDOM := {=>}
hDOM["agenda"] := {=>}
hDOM["agenda"]["contactos"] := {=>}
hDOM["agenda"]["ultimo_id"] := 0
RETURN hDOM
// ----------------------------------------------------------------------
// Save hDOM structure to JSON file
// Guardar estructura hDOM a archivo JSON
// ----------------------------------------------------------------------
FUNCTION GuardarAgendaJSON( cNombreArchivo )
LOCAL cJsonTexto := HB_ToJSON( hDOM )
IF !Empty( cJsonTexto )
RETURN hb_MemoWrit( cNombreArchivo, cJsonTexto )
ENDIF
RETURN .F.
// ----------------------------------------------------------------------
// JSON Pure Harbour Serializer / Serializador JSON en Harbour Puro
// ----------------------------------------------------------------------
FUNCTION HB_ToJSON( xVal, nIndent )
LOCAL cType := ValType( xVal )
LOCAL cJson := ""
LOCAL cKey, i, nLen
LOCAL cPad := ""
IF nIndent == Nil
nIndent := 0
ENDIF
cPad := Space( nIndent * 2 )
DO CASE
CASE cType == "H"
cJson := "{" + hb_eol()
nLen := Len( xVal )
i := 0
FOR EACH cKey IN xVal:Keys
i++
cJson += cPad + " " + '"' + hb_ValToStr( cKey ) + '": ' + HB_ToJSON( xVal[ cKey ], nIndent + 1 )
IF i < nLen
cJson += ","
ENDIF
cJson += hb_eol()
NEXT
cJson += cPad + "}"
CASE cType == "A"
cJson := "[" + hb_eol()
nLen := Len( xVal )
FOR i := 1 TO nLen
cJson += cPad + " " + HB_ToJSON( xVal[ i ], nIndent + 1 )
IF i < nLen
cJson += ","
ENDIF
cJson += hb_eol()
NEXT
cJson += cPad + "]"
CASE cType == "C"
cJson := '"' + StrTran( StrTran( xVal, "\", "\\" ), '"', '\"' ) + '"'
CASE cType == "N"
cJson := LTrim( Str( xVal ) )
CASE cType == "L"
cJson := IIF( xVal, "true", "false" )
OTHERWISE
cJson := "null"
ENDCASE
RETURN cJson
// ----------------------------------------------------------------------
// Helper functions for Grid navigation and Indexing
// Funciones auxiliares para la grilla e índices
// ----------------------------------------------------------------------
FUNCTION ValorDaColuna( ControlName, ParentForm, nCol )
LOCAL aRet := {}
IF GetControlType( ControlName, ParentForm ) != "GRID"
RETURN ""
ENDIF
nCol := IIf( nCol == Nil .OR. nCol == 0, 1, nCol )
aRet := GetProperty( ParentForm, ControlName, 'Item', GetProperty( ParentForm, ControlName, 'Value' ) )
IF ValType( aRet ) == "A" .AND. Len( aRet ) >= nCol
RETURN aRet[ nCol ]
ENDIF
RETURN ""
FUNCTION PosicionaIndice( cLetra )
LOCAL i := 0
FOR i := 1 TO 26
IF CHR( i + 64 ) == cLetra
MODIFY CONTROL GIndice OF Form_1 VALUE i
ENDIF
NEXT
Form_1.GIndice.SetFocus
RETURN Nil
FUNCTION Imprimir()
LOCAL cLetra := ValorDaColuna( "GIndice", "Form_1", 1 )
LOCAL cTxt := "=== CONTACTS LIST / LISTA DE CONTACTOS (" + cLetra + ") ===" + hb_eol() + hb_eol()
LOCAL cIdKey, hContacto
IF hb_HHasKey( hDOM, "agenda" ) .AND. hb_HHasKey( hDOM["agenda"], "contactos" )
FOR EACH cIdKey IN hDOM["agenda"]["contactos"]:Keys
hContacto := hDOM["agenda"]["contactos"][ cIdKey ]
IF Upper( Left( hContacto["name"], 1 ) ) == cLetra
cTxt += "ID: " + cIdKey + " | " + hContacto["name"] + " | Tel: " + hContacto["phone"] + hb_eol()
ENDIF
NEXT
ENDIF
MsgInfo( cTxt, "Print Preview / Vista de Impresión" )
RETURN NilAttachments
Attachments
Code: Select all
@ 244 ,50 EDITBOX M_Archivo ;
WIDTH 215 ;
HEIGHT 45 ;
FONT "Calibri" SIZE 10 ;
BOLD ;
VALUE '' ;
BACKCOLOR {218,229,243} ;
DISABLEDBACKCOLOR {218,229,243} ;
DISABLEDFONTCOLOR {0, 0, 128} ;
MAXLENGTH 250 ;
NOHSCROLL ;
READONLY ;
TOOLTIP ""
Code: Select all
@ 244 ,50 EDITBOX M_Archivo ;
WIDTH 215 ;
HEIGHT 45 ;
FONT "Calibri" SIZE 10 ;
BOLD ;
VALUE '' ;
BACKCOLOR {218,229,243} ;
DISABLEDBACKCOLOR {218,229,243} ;
DISABLEDFONTCOLOR {0, 0, 128} ;
MAXLENGTH 250 ;
NOHSCROLL ;
READONLY ;
TOOLTIP ""
Code: Select all
Procedure CambiarColores()
// 1. Asignar los colores para estado deshabilitado mediante SetProperty
// Fondo deshabilitado: Gris claro {220, 220, 220}
SetProperty ( "Form_1", "Text_1", "DISABLEDBACKCOLOR", { 220, 220, 220 } )
// Texto deshabilitado: Rojo {255, 0, 0}
SetProperty ( "Form_1", "Text_1", "DISABLEDFONTCOLOR", { 255, 0, 0 } )
// 2. Deshabilitar el control para que se apliquen los colores
SetProperty ( "Form_1", "Text_1", "ENABLED", .F. )
ReturnCode: Select all
Form_1.Text_1.DisabledBackColor := { 220, 220, 220 }
Form_1.Text_1.DisabledFontColor := { 255, 0, 0 }
Form_1.Text_1.Enabled := .F.Code: Select all
Procedure CambiarColores()
// 1. Asignar los colores para estado deshabilitado mediante SetProperty
// Fondo deshabilitado: Gris claro {220, 220, 220}
SetProperty ( "Form_1", "Text_1", "DISABLEDBACKCOLOR", { 220, 220, 220 } )
// Texto deshabilitado: Rojo {255, 0, 0}
SetProperty ( "Form_1", "Text_1", "DISABLEDFONTCOLOR", { 255, 0, 0 } )
// 2. Deshabilitar el control para que se apliquen los colores
SetProperty ( "Form_1", "Text_1", "ENABLED", .F. )
ReturnCode: Select all
Form_1.Text_1.DisabledBackColor := { 220, 220, 220 }
Form_1.Text_1.DisabledFontColor := { 255, 0, 0 }
Form_1.Text_1.Enabled := .F.*********************************************************************************
* Simple Server for test with NETIO
*
* Created by : Paulo Sérgio Durço - 23/10/2009 8:30 Hrs
*
* Thanks Master Roberto Lopez for your great work.
*********************************************************************************
Attachments
*********************************************************************************
* Simple Server for test with NETIO
*
* Created by : Paulo Sérgio Durço - 23/10/2009 8:30 Hrs
*
* Thanks Master Roberto Lopez for your great work.
*********************************************************************************
Attachments
Code: Select all
Build.bat para RESTalkCode: Select all
@ECHO OFF
SETLOCAL
SET Temp1=%~dp0
SET Temp3=%Temp1%&SET Pos=0
:Loop
SET /a Pos+=1
ECHO %Temp3%|FINDSTR /b /c:"SAMPLES" >NUL
IF ERRORLEVEL 1 (
SET Temp3=%Temp3:~1%
IF DEFINED Temp3 GOTO Loop
SET Pos=0
)
SETLOCAL EnableDelayedExpansion
SET "Temp2=%Temp1%"
SET /a Pos=Pos-2
SET Temp1=!Temp2:~0,%Pos%!
IF "%1"=="" GOTO WithOutParam
SET MainFile="%1"
GOTO WithParam
:WithOutParam
:: Compilación secuencial en orden estricto: Servidor y luego Cliente
IF "%NoRun%"=="" (
ECHO Building TalkServer.hbp...
CALL %Temp1%\build64.bat TalkServer.hbp
ECHO.
ECHO Building TalkClient.hbp...
CALL %Temp1%\build64.bat TalkClient.hbp
) ELSE (
ECHO Building TalkServer.hbp ^(NoRun^)...
CALL %Temp1%\build64.bat /n TalkServer.hbp
ECHO.
ECHO Building TalkClient.hbp ^(NoRun^)...
CALL %Temp1%\build64.bat /n TalkClient.hbp
)
GOTO End
:WithParam
IF "%NoRun%"=="" CALL %Temp1%\Build.bat %MainFile%
IF NOT "%NoRun%"=="" CALL %Temp1%\Build.bat /n %MainFile%
:EndCode: Select all
C:\hmg.3.6\SAMPLES\AdvancedCode: Select all
Build.bat para RESTalkCode: Select all
@ECHO OFF
SETLOCAL
SET Temp1=%~dp0
SET Temp3=%Temp1%&SET Pos=0
:Loop
SET /a Pos+=1
ECHO %Temp3%|FINDSTR /b /c:"SAMPLES" >NUL
IF ERRORLEVEL 1 (
SET Temp3=%Temp3:~1%
IF DEFINED Temp3 GOTO Loop
SET Pos=0
)
SETLOCAL EnableDelayedExpansion
SET "Temp2=%Temp1%"
SET /a Pos=Pos-2
SET Temp1=!Temp2:~0,%Pos%!
IF "%1"=="" GOTO WithOutParam
SET MainFile="%1"
GOTO WithParam
:WithOutParam
:: Compilación secuencial en orden estricto: Servidor y luego Cliente
IF "%NoRun%"=="" (
ECHO Building TalkServer.hbp...
CALL %Temp1%\build64.bat TalkServer.hbp
ECHO.
ECHO Building TalkClient.hbp...
CALL %Temp1%\build64.bat TalkClient.hbp
) ELSE (
ECHO Building TalkServer.hbp ^(NoRun^)...
CALL %Temp1%\build64.bat /n TalkServer.hbp
ECHO.
ECHO Building TalkClient.hbp ^(NoRun^)...
CALL %Temp1%\build64.bat /n TalkClient.hbp
)
GOTO End
:WithParam
IF "%NoRun%"=="" CALL %Temp1%\Build.bat %MainFile%
IF NOT "%NoRun%"=="" CALL %Temp1%\Build.bat /n %MainFile%
:EndCode: Select all
C:\hmg.3.6\SAMPLES\AdvancedAttachments
Attachments
Attachments
Attachments
Attachments
MenuFlyout.rar (167.81 KiB)Attachments
MenuFlyout.rar (167.81 KiB)Code: Select all
SetupFlyout( GetFormHandle("MainWin") ) Attachments
Code: Select all
SetupFlyout( GetFormHandle("MainWin") ) Attachments
Code: Select all
Harbour 3.2.0dev (r2304211101)
Copyright (c) 1999-2023, https://harbour.github.io/
In file included from D:/hmg36/harbour64/include/hbdefs.h:52,
from D:/hmg36/harbour64/include/hbvmpub.h:50,
from C:/Users/Marek/AppData/Local/Temp/hbmk_yltb6h.dir/menubuttons.c:7:
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h: In function 'llabs':
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h:735:3: internal compiler error: Illegal instruction
735 | __MINGW_EXTENSION __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
| ^~~~~~~~~~~~~~~~~
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
In file included from D:/hmg36/harbour64/include/hbdefs.h:52,
from D:/hmg36/harbour64/include/hbvmpub.h:50,
from D:/hmg36/harbour64/include/hbapi.h:55,
from C:/Users/Marek/AppData/Local/Temp/hbmk_rse47r.c:4:
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h: In function 'llabs':
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h:735:3: internal compiler error: Illegal instruction
735 | __MINGW_EXTENSION __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
| ^~~~~~~~~~~~~~~~~
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
hbmk2: Error: Running C/C++ compiler. 1
gcc.exe -c -O3 -W -Wall -pipe -ID:/hmg36/harbour64/include -Id:/projekty/testy/menubuttons -ID:/hmg36/include C:/Users/Marek/AppData/Local/Temp/hbmk_yltb6h.dir/menubuttons.c C:/Users/Marek/AppData/Local/Temp/hbmk_rse47r.c
]]>Code: Select all
Harbour 3.2.0dev (r2304211101)
Copyright (c) 1999-2023, https://harbour.github.io/
In file included from D:/hmg36/harbour64/include/hbdefs.h:52,
from D:/hmg36/harbour64/include/hbvmpub.h:50,
from C:/Users/Marek/AppData/Local/Temp/hbmk_yltb6h.dir/menubuttons.c:7:
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h: In function 'llabs':
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h:735:3: internal compiler error: Illegal instruction
735 | __MINGW_EXTENSION __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
| ^~~~~~~~~~~~~~~~~
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
In file included from D:/hmg36/harbour64/include/hbdefs.h:52,
from D:/hmg36/harbour64/include/hbvmpub.h:50,
from D:/hmg36/harbour64/include/hbapi.h:55,
from C:/Users/Marek/AppData/Local/Temp/hbmk_rse47r.c:4:
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h: In function 'llabs':
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h:735:3: internal compiler error: Illegal instruction
735 | __MINGW_EXTENSION __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
| ^~~~~~~~~~~~~~~~~
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
hbmk2: Error: Running C/C++ compiler. 1
gcc.exe -c -O3 -W -Wall -pipe -ID:/hmg36/harbour64/include -Id:/projekty/testy/menubuttons -ID:/hmg36/include C:/Users/Marek/AppData/Local/Temp/hbmk_yltb6h.dir/menubuttons.c C:/Users/Marek/AppData/Local/Temp/hbmk_rse47r.c
]]>Code: Select all
Harbour 3.2.0dev (r2304211101)
Copyright (c) 1999-2023, https://harbour.github.io/
In file included from D:/hmg36/harbour64/include/hbdefs.h:52,
from D:/hmg36/harbour64/include/hbvmpub.h:50,
from C:/Users/Marek/AppData/Local/Temp/hbmk_yltb6h.dir/menubuttons.c:7:
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h: In function 'llabs':
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h:735:3: internal compiler error: Illegal instruction
735 | __MINGW_EXTENSION __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
| ^~~~~~~~~~~~~~~~~
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
In file included from D:/hmg36/harbour64/include/hbdefs.h:52,
from D:/hmg36/harbour64/include/hbvmpub.h:50,
from D:/hmg36/harbour64/include/hbapi.h:55,
from C:/Users/Marek/AppData/Local/Temp/hbmk_rse47r.c:4:
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h: In function 'llabs':
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h:735:3: internal compiler error: Illegal instruction
735 | __MINGW_EXTENSION __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
| ^~~~~~~~~~~~~~~~~
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
hbmk2: Error: Running C/C++ compiler. 1
gcc.exe -c -O3 -W -Wall -pipe -ID:/hmg36/harbour64/include -Id:/projekty/testy/menubuttons -ID:/hmg36/include C:/Users/Marek/AppData/Local/Temp/hbmk_yltb6h.dir/menubuttons.c C:/Users/Marek/AppData/Local/Temp/hbmk_rse47r.c
Code: Select all
Harbour 3.2.0dev (r2304211101)
Copyright (c) 1999-2023, https://harbour.github.io/
In file included from D:/hmg36/harbour64/include/hbdefs.h:52,
from D:/hmg36/harbour64/include/hbvmpub.h:50,
from C:/Users/Marek/AppData/Local/Temp/hbmk_yltb6h.dir/menubuttons.c:7:
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h: In function 'llabs':
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h:735:3: internal compiler error: Illegal instruction
735 | __MINGW_EXTENSION __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
| ^~~~~~~~~~~~~~~~~
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
In file included from D:/hmg36/harbour64/include/hbdefs.h:52,
from D:/hmg36/harbour64/include/hbvmpub.h:50,
from D:/hmg36/harbour64/include/hbapi.h:55,
from C:/Users/Marek/AppData/Local/Temp/hbmk_rse47r.c:4:
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h: In function 'llabs':
D:/hmg36/mingw64/x86_64-w64-mingw32/include/stdlib.h:735:3: internal compiler error: Illegal instruction
735 | __MINGW_EXTENSION __CRT_INLINE long long __cdecl llabs(long long _j) { return (_j >= 0 ? _j : -_j); }
| ^~~~~~~~~~~~~~~~~
libbacktrace could not find executable to open
Please submit a full bug report, with preprocessed source (by using -freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
hbmk2: Error: Running C/C++ compiler. 1
gcc.exe -c -O3 -W -Wall -pipe -ID:/hmg36/harbour64/include -Id:/projekty/testy/menubuttons -ID:/hmg36/include C:/Users/Marek/AppData/Local/Temp/hbmk_yltb6h.dir/menubuttons.c C:/Users/Marek/AppData/Local/Temp/hbmk_rse47r.c
Attachments
Attachments
Attachments
Attachments
Attachments
Attachments
Attachments
Attachments
Code: Select all
DependencyService report
Runtime dependency group: VLC
Status: incomplete
Found:
libvlc.dll
Missing:
libvlccore.dll
plugins\
Suggestion:
Copy libvlccore.dll next to the executable.
Copy the VLC plugins folder next to the executable.
Verify that all files are 64-bit.Code: Select all
DependencyService report
Runtime dependency group: VLC
Status: incomplete
Found:
libvlc.dll
Missing:
libvlccore.dll
plugins\
Suggestion:
Copy libvlccore.dll next to the executable.
Copy the VLC plugins folder next to the executable.
Verify that all files are 64-bit.Attachments
Attachments
Code: Select all
*-------------------------------------------------------------*
Function AbrirPuerto( lRetorno )
*-------------------------------------------------------------*
nHandler := CallDll32( "OpenComFiscal" , "WINFIS32.DLL" , 1 , 0 )
If nHandler >= 0
Principal.StatusBar.Item(2) :="Puerto de impresora OK "
nError := CallDll32( "InitFiscal" , "WINFIS32.DLL" , nHandler )
If nError = 0
lRetorno := .T.
Else
alerror( nError )
Principal.StatusBar.Item(2) := " La impresora no se puede Inicializar"
lRetorno := .T.
Endif
Else
alerror( nHandler )
Principal.StatusBar.Item(2) :=" Hubo un error de abrir puerto Comm "
lRetorno := .T.
Endif
Return ( lRetorno )Code: Select all
*-------------------------------------------------------------*
Function AbrirPuerto( lRetorno )
*-------------------------------------------------------------*
nHandler := OpenComFiscal( 1, 0 )
If nHandler >= 0
Principal.StatusBar.Item(2) := "Puerto de impresora OK "
nError := InitFiscal( nHandler )
If nError = 0
lRetorno := .T.
Else
alerror( nError )
Principal.StatusBar.Item(2) := " La impresora no se puede Inicializar"
lRetorno := .T.
Endif
Else
alerror( nHandler )
Principal.StatusBar.Item(2) := " Hubo un error de abrir puerto Comm "
lRetorno := .T.
Endif
Return ( lRetorno )Code: Select all
*-------------------------------------------------------------*
Function AbrirPuerto( lRetorno )
*-------------------------------------------------------------*
nHandler := CallDll32( "OpenComFiscal" , "WINFIS32.DLL" , 1 , 0 )
If nHandler >= 0
Principal.StatusBar.Item(2) :="Puerto de impresora OK "
nError := CallDll32( "InitFiscal" , "WINFIS32.DLL" , nHandler )
If nError = 0
lRetorno := .T.
Else
alerror( nError )
Principal.StatusBar.Item(2) := " La impresora no se puede Inicializar"
lRetorno := .T.
Endif
Else
alerror( nHandler )
Principal.StatusBar.Item(2) :=" Hubo un error de abrir puerto Comm "
lRetorno := .T.
Endif
Return ( lRetorno )Code: Select all
*-------------------------------------------------------------*
Function AbrirPuerto( lRetorno )
*-------------------------------------------------------------*
nHandler := OpenComFiscal( 1, 0 )
If nHandler >= 0
Principal.StatusBar.Item(2) := "Puerto de impresora OK "
nError := InitFiscal( nHandler )
If nError = 0
lRetorno := .T.
Else
alerror( nError )
Principal.StatusBar.Item(2) := " La impresora no se puede Inicializar"
lRetorno := .T.
Endif
Else
alerror( nHandler )
Principal.StatusBar.Item(2) := " Hubo un error de abrir puerto Comm "
lRetorno := .T.
Endif
Return ( lRetorno )Attachments
Attachments
Attachments
Attachments