April/May 2019
=========
* Fix: Class TWindow method Center() was not updating the window coordinates.
Now it is ok.
* Fix: Minor fix in Class TRibbonBar Method PaintFld() to remove a painting artifact
under some circunstances.
* Fix: source\function\imgtxtio.prg: The functions FW_SayText() and
FW_DrawImage() are not restoring the BkMode of the device context,
after changing to transparent. Fixed now.
* Enhancement: TPrinter class: If method Say() is called with a Text
color, the changed color becomes to default to all subsequent calls
of this method.
New CLASSDATA lResetSayColors INIT .f.
If this is set to .t., calls to Say() with a text color apply to
that say only and does not affect subsequent says.
* Enhancement in display/printing of multi-line text:
Functions DrawTextEx(), FW_SayText() and method SayText() of Window and
Printer classes can output single line or multi line text to fit inside
the rectangle specified. When the entire multi-line text can not fit
inside the specified rectangle, the remaining text is returned in the
parameter cText, if cText is called by reference. If the returned text is
not empty, the programmer can decide where to print the remaining text, ie.,
in a separate page, column or ignore.
Usage:
oPrn:SayText( row, col, @cText, width, height, ... )
* XBrowse:
- New DATA bPaintBack. If specified, this codeblock is used to paint background of
the browse, instead of the inbuilt logic.
- Incremental filter in Array browse can now be used even when lAutoSort is false.
Previously trying to use incremental filters without autosort was giving runtime
errors.
- Enhancement: method EditSource( lNew, cFieldList, aInitVals )
New parameter aInitVals: If specified, non-empty values in the array are
pre-assigned to the corresponding fields in case of new (blank) records.
http://forums.fivetechsupport.com/viewt ... 28#p221428
- New DATA clCurrency of TXBrwColumn: Default nil.
Can be set to .T. or any currency symbol. If .t., the default currency symbol or
the assigned currecny symbol is added to the picture clause and dislayed left
aligned in the column.
- Fix to Method GoRight: When oBrw:lTransparent := .t., and cursor is moved right with
arrow key, highlight is not cleared from the previous cells. Fixed
- Autosort: Even autosort is not specified when browse is created, internally
browse is kept ready for autosort. Programmer can toggle oBrw:lAutosort anytime
during runtime to make it work.
- SetCheck() settings are disturbed when the methods SetArray(), etc. are called
during runtime. Fixed.
- Incremental filters with DBF are replacing the existing filters. Now the
existing fitlers are respected and incremental filter is treated as an
additional filter.
* New function AShuffle( aArray ) --> aArray
Sorts a given array in a random order.
* New function DBF_ApplyParams( cExpr, aParams ) --> cExpr
Substitutes the '?' place holders in cExpr with the correspoding values in
aParams and returns the full expression.
Example:
cName := "T"
dDate := DTOS( "20000101" )
cFilter := ;
DBF_ApplyParams( "UPPER(FIRST) = ? .AND. HIREDATE >= ?", ;
{ cName, dDate } ) -->
"UPPER(FIRST) = "T" .AND. HIREDATE >= 0d20000101"
SET FILTER TO &cFilter
* New function FW_DbFilterBlock() --> bFilterExp
Harbour functin DBFILTER() returns the filter condition as string
This function returns the codeblock used for filter
* database.prg.
- New: Method SetFilter( cFilter, aParams ): aParms is added as second parameter.
aParams is an array of values to be inserted in the place holders marked with ?.
aParams can also be a codeblock which returns an array when evaluated.
Usage:
oDbf:SetFilter( "UPPER(FIRST) = ? .AND. HIREDATE >= ?", ;
{ cName, dDate } )
- New: Method Refilter( aParams ): Resets the filter using previously used
filter experession with the new paramters
- Enhancement: When relation is set to another Tdatabase object, using the
method SetRelation(), load method of the related database is automatically
called when the record pointer of the main table is moved. There is no more
any need to call oRelatedTable:Load()
- Fix: oDbf:Blank(), assign values and calling oDbf:Save() is not working when
eof is .t. Fixed now.
- Fix: oDbf:Append() without parameters appends blank. But oDbf:Load() needs to
be called for assigning values and saving. Now oDbf:Append() calls Load() also.
- New method Browse( [cTitle], [acFields] ) --> Self
* adofuncs.prg, xbrowse.prg, datarow.prg: Improved ascertainment of fieldlen,
fielddec in case of types adDouble and adSingle in ADO, where attributes
Precision and NumericScale are left unspecified.
* New function FW_ArrayAsRecordSet( [aArray], [aStruct] ) --> oAdoRecordSet
Either aArray or aStruct or both must be specified.
aArray should be a two-dimensional array.
aStruct can be a structure similar to DBF structure
If aArray is specified, aStruct can be empty or Structure or list of fields.
The function returns an ADO recordset, not connected to any database, but
can be edited, appended, deleted and navigated like any other recordset.
At any time, array of data can be retrieved with aData := RsGetRows( oRs )
Source: \fwh\source\function\adofuncs.prg
Sample: \fwh\samples\arr2rs.prg
* Fix: Method MapCol( cFieldName, cPrompt ) of tdatabase class.
If an earlier field name is longer than the fieldname and its initial
characters match the fieldname (eg. "DATE1", "DATE"), the prompt is mapped
to the earlier column. Fixed.
* Enhancement: command XBREPORT. New additional clause [TO PDF <cPdf>]. If specified,
the report will be saved as cPdf
* New function XEdit( [uSource], [cFieldList], [lNew] )
Provides Edit dialog of the current record (optionally a new record) of uSource.
- uSource: Can be Alias, Array, Hash, RecordSet, MariaDB RowSet, Dolphin,
TMySql,PostGre Query object and defaults to the current Alias()
- cFieldList: Optionally a comma delimited list of fields. Defaults to all fields
- lNew: If .t., display as blank record and appends when saved. Defaults to .f.
* New function XReport( [uSource], [acFields], [cPdf] )
Quickly generates a report for preview. Optionally saves the report to PDF
- uSource: Can be Alias, Array, Hash, RecordSet, MariaDB RowSet, Dolphin,
TMySql,PostGre Query object and defaults to the current Alias().
A dbf file name also can be specified which will be opened via RDDSETDEFAULT()
and closed after generation of the report.
- acFields: Optional comma delimited list or array of fields names.
- cPdf: Optional. if specifed, the report will be saved to the pdf file name
* Fix: bar.prg: Method BtnAdjust() encounters runtime error if a control other than
btnbmp is placed on the buttonbar. Fixed.
* New CLASSDATA bSetup in class TPreview. If assigned, the codeblock is evaluated with
oPreview and oWnd as parameters just before activating the preview window.
Example Usage:
RPrevUserBtns( nil, 2007 )
TPreview():bSetup := <|oPreview, oWnd|
WITH OBJECT oWnd:oBar
:aControls[ 10 ]:End()
ADel( :aControls, 10, .t. )
:BtnAdjust()
END
return nil
>
This removes the Email button from the bar.
* Enhancement: TDataRow class (FW_Record)
- oRec := FW_Record():New( cDataSource, cFieldList, lNew, aInitVals )
New parameter aInitVals. If specified, non empty values in the array
are pre-assigned to the corresponding fields in case of New (append)
records.
- New method SetInitVals( aInitVals ): In case of new (blank record) initial values
can be pre-assigned with this method.
* Enhancement: When the number format "@X" is used, negative numbers are
treated as debits and displayed with suffix of " DB". In some regions, users
prefer displaying " DR" instead of " DB".
If the 6th new parameter of FWNumFormat(...) is set to .T., xbrowse and report
display " DR" in the place of " DB".
* New function CurrencySymbol( [cNewSymbol] ) --> cPreviousSymbol
By default, the currency symbol is $, £, € or Rupee, depending on the Region
set by FWNumFormat( "A/B/E/I" ). Programmer can set any other different symbol.
* New function FW_DBINSERT(). Moves data from current record down and creates a
blank record in place of current record
* Enhancement: uValBlank( aArray ) blank arrays also
- uValBlank( aArray ) --> returns the array with all elements blank
- uValBlank( hHash ) --> returns Hash with all values blank
- uValBlank( number ) --> now preserves the decimal places
* Enhancement: Report class: If numeric values are formatted prefixing currency
symbol, the symbol is printed left aligned in the column.
* Enhancement: XBrowser.prg: Now uses buttonbar instead of individual btnbmps.
* New function SegoeMDL2() --> .t. if Segoe MDL2 Assets font is available
* Case insensitive string comparision and matching:
- New function FW_AT( cSearch, [@]cString, [nStart], [nEnd], [ lWholeWord],
[lSkipQuotes],[@cFound], cReplace, lAll )
--> nAt (or aMatches, if lAll is .t. )
Same as AT() or HB_AT(), but case insensitive, if the first 4 params are used.
Eg: FW_ATI( "O lInA", "Antonio Linares" ) --> 7
Additional features:
cSearch can be a string or array of strings. In case of array, the earliest occurance
is reported.
If lWholeWord is .t., only whole words are matched.
Eg: FW_ATI( "EAR", "Years Hear Ear", nil, nil, .T. ) --> 12, but not 2.
If lSkipQuotes is .t., the search skips any text inside quotes, "...", '...' or [...]
Eg: FW_ATI( "NEAR", 'He said "it is near" but it is not near', nil, nil, nil, .t. )
--> 36 but not 16
If @cFound is specified as 7th parameter by reference, the exact match found in the
string is returned. Eg: In the above case it returns "near".
If cReplace is specified as 8th parameter and cString is by reference, cFound is
replaced by cReplace.
It the 9th parameter lAll is set to .T., all matches are returned as Array. In case of
cReplace, all occurances are replaced by cReplace.
- New function FW_STRICMP(): Compares the two strings ignoring the case.
Respect SET EXACT off/on setting, subject to override
Usage1: FW_StrICmp( cStr1, cStr2, [lExact] ) --> -1,0,+1 for less than,
equal or greater than. 3rd parameter, if specified, overrides SET EXACT
setting
Usage2: FW_StrICmp( cStr1, cCompOperator, cStr2, [lExact] ) --> .f. / .t.
Eg: FW_StrICmp( c1, ">=", c2, [nil,.t.,.f.] ) --> .t./.f.
Operator "==" forces exact comparison. In other cases 4th paramter specifies
if comparision is exact and if omitted, default setting is used.
* FWMariaDB:
- Fix: When the sql query contains "order by field desc " followed by "limit",
rowset object is not recognising the order as descending. Fixed.
* TDataRow (FW_Record):
- Fix: In case of append records, method Undo() is not restoring default values
set by method SetDefault( fld, uDefault ). Fixed
- Fix: In case of append records, default values set by SetDefault() method are
being displayed but not saved, if not modified by the user. Fixed.
- Edit dialog buttons: The wingding fonts used for the buttons are not properly
displayed in the recent versions of Windows10. Resolved by using SegoeMDL2Assets
if installed.
* ORM
Released 1st version ORM, under development.
Supports dbase,foxpro,msaccess,mssql,mysql,oracle with ADO and mysql with ADO,
Dolphin and FWMariaLib.
- Class ORM_Connection
Syntax:
- oConnection := ORM_Connection():New( rdbms, server, database, user, password )
where rdbms can be mysql, mssql, oracle, etc for ADO or dolphin / fwmariadb for
mysql with these libraries
// OR //
- oConnection := ORM_Connection():New( oAdoConn (or) oDolphinServ (or) oFwCon )
Methods:
New()
Tables() // list of tables
HasTable( cTable ) --> lExists
Table( cTable ) --> ORM_Table Object
Close()
- Class ORM_Table()
Table object can be instantiated either by calling
oTable := oConnection:Table( cTableName )
or
oTable := ORM_Table():New( oConnection, cTableName )
Methods:
Navigation: First(), Last(), Next(), Prev(), Move(n), MoveTo( n )
Others:
Select( aFields )
Where( Field, [cOperator], Value )
OrderBy( field )
Get( [field )
XBrowse( [fieldlist] )
Edit()
Sum(field), Max(field), Min(field), Avg(field)
GroupBy( fields )
Find( primarykeyval ) or Find( field, value )
* New Class: TDockPnel
- New style container, please revise code of samples and wiki
http://wiki.fivetechsoft.com/doku.php?i ... _tdockpnel
- Samples: Testdock01.prg, Testdock02.prg, TestDock04.prg
* TGet.prg: When a bitmap is assigned for action clause, the bitmap
resource is not released. Fixed.
* function FW_ArrayToDBF( aArray, cFieldList, ... ): Enhancements:
- cFieldList can contain "*", which is expanded to full list of fields
- cFieldList can contain "RECNO()". In such cases, the records are
written to that RecNo() if not empty and appended if empty.
* New function FW_UTCTOLOCAL( tUtc ) --> tLocalTime
* New function FW_TimeZoneName() --> local time zone name
New FTDN May/Mayo 2019 (FWH 19.05)
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: New FTDN May/Mayo 2019 (FWH 19.05)
And
* TPanel class: New Method Redefine ( look fivewin.ch for definition )
* TPanel class: New Method Redefine ( look fivewin.ch for definition )
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: New FTDN May/Mayo 2019 (FWH 19.05)
Abril/Mayo 2019
===============
* Corrección: En el método Center() de la clase TWindow, no actualizaba las coordenadas de la ventana.
Ahora está corregido.
* Correción: Pequeña corrección en el método PaintFld() de la clase TRibbonBar para eliminar un mal
efecto de pintado en algunas circustancias.
* Corrección: En source\function\imgtxtio.prg: Las funciones FW_SayText() y FW_DrawImage() no estaban
devolviendo el "BkMode" del contexto del dispositivo después de cambiar a transparente. Corregido ahora.
* Mejora: En la clase TPrinter: Si el método Say() es llamado con un texto en color, el color cambiado
se convierte en predeterminado para todas las llamadas subsiguientes de este método.
Nuevo CLASSDATA lResetSayColors INIT .f.
Si es puesto a .T., las llamadas a Say() con un color de texto se aplican solo a ese Say() y no afectan
a los siguientes.
* Mejora: En mostrar/imprimir texto multilínea:
Las funciones DrawTextEx(), FW_SayText() y el método SayText() de las clases TWindow y TPrinter pueden
generar texto de una sola línea o de varias líneas para encajar dentro del rectángulo especificado.
Cuando todo el texto de varias líneas no puede caber dentro del rectángulo especificado, el texto restante
se devuelve en el parámetro cText, si cText se llama por referencia. Si el texto devuelto no está vacío,
el programador puede decidir dónde imprimir el texto restante, es decir, en una página separada, columna
o ignorar.
Uso: oPrn:SayText( row, col, @cText, width, height, ... )
* XBrowse:
- Nueva DATA bPaintBack. Si se especifica, este bloque de código se usa para dibujar el fondo del "xbrowse",
en lugar de la lógica incorporada.
- El filtro incremental en un "browse" de matrices ahora se puede usar incluso cuando lAutoSort es falso.
Anteriormente, al tratar de usar filtros incrementales sin autoordenación daba errores de tiempo de ejecución.
- Mejora: En el método EditSource( lNew, cFieldList, aInitVals )
Nuevo parámetro aInitVals: Si se especifica, los valores no vacíos en la matriz se asignan previamente a los
campos correspondientes en caso de que haya nuevos registros (en blanco).
http://forums.fivetechsupport.com/viewt ... 28#p221428
- Nueva DATA clCurrency para TXBrwColumn: Por defecto NIL.
Se puede establecer a .T. o cualquier símbolo de moneda. Si es .T., el símbolo de moneda predeterminado o el símbolo
de moneda asignado se agrega a la cláusula "PICTURE" y se muestra alineado a la izquierda en la columna.
- Correción en le método GoRight: Cuando oBrw:lTransparent := .T., y el cursor se mueve hacia la derecha con la tecla
de flecha, el resaltado no se borra de las celdas anteriores. Corregido.
- Autosort: Incluso si no se especifica autoordenación cuando se crea el browse, internamente el browse se mantiene
preparado para autoordenación.
El programador puede alternar oBrw:lAutosort en cualquier momento durante el tiempo de ejecución para que funcione.
- Corrección en SetCheck(): Los ajustes de SetCheck() se alteran cuando los métodos SetArray(), etc..., son llamados
durante el tiempo de ejecución. Corregido.
- Los filtros incrementales con DBFs reemplazan los filtros existentes. Ahora se respetan los filtros existentes y
el filtro incremental es tratado como un filtro adicional.
* Nueva función AShuffle( aArray ) --> aArray
Ordena una matriz dada en orden aleatorio.
* Nueva función DBF_ApplyParams( cExpr, aParams ) --> cExpr
Sustituye en el lugar donde está ? en cExpr por el valor correspondiente en aParams y devuelve la expresión completa.
Ejemplo:
cName := "T"
dDate := DTOS( "20000101" )
cFilter := ;
DBF_ApplyParams( "UPPER(FIRST) = ? .AND. HIREDATE >= ?", ;
{ cName, dDate } ) -->
"UPPER(FIRST) = "T" .AND. HIREDATE >= 0d20000101"
SET FILTER TO &cFilter
* Nueva función FW_DbFilterBlock() --> bFilterExp
La función de Harbour DBFILTER() devuelve la condición del filtro como una cadena de caracteres.
Esta función devuelve el bloque de código usado por el filtro.
* Database.prg
- Nuevo: Método SetFilter( cFilter, aParams ): se ha añadido aParams como segundo parámetro.
aParams es una matriz de valores para ser insertada en el lugar marcado por el símbolo ?.
aParams también puede ser un bloque de código que devuelve una matriz cuando es evaluado.
Uso:
oDbf:SetFilter( "UPPER(FIRST) = ? .AND. HIREDATE >= ?", ;
{ cName, dDate } )
- Nuevo: Método Refilter( aParams ): Restablece el filtro utilizando la expresión de filtro
utilizada previamente con los nuevos parámetros.
- Mejora: Cuando la relación se establece con otro objeto TDatabase, utilizando el método
SetRelation(), el método de carga de la base de datos relacionada se llama automáticamente
cuando se mueve el puntero de registro de la tabla principal.
No hay más necesidad de llamar a oRelatedTable:Load().
- Corrección: oDbf:Blank(), asigna valores y llama a oDbf:Save() no funciona cuando EOF es puesto a .T.
Corregido ahora.
- Corrección: oDbf:Append() sin parámetros añade un registro en blanco. Pero oDbf:Load() necesita
ser llamada para asignar valores y grabarlos. Ahora oDbf:Append() llama también a oDbf:Load().
- Nuevo: Método Browse( [cTitle], [acFields] ) --> Self
* adofuncs.prg, xbrowse.prg, datarow.prg: Mejorada la comprobación de fieldlen, fielddec en caso
de los tipos adDouble y adSingle en ADO, dónde los atributos "Precision" y "NumericScale" no
se especifican.
En el caso de _ numéricos en ADO, oField:Precision es equivalente a FIELDLEN() y
oField:NumericScale es equivalente a FIELDDEC().Sin embargo, la Precisión no cuenta el espacio requerido
para la posición decimal.
Hay muchos tipos numéricos en ADO. En _ como adSingle, adDouble, estos valores difieren en la
forma en que se crea la tabla y difieren de un servidor a otro y de un proveedor a otro. En _,
el campo puede ser el resultado de un cálculo. Debemos tener cuidado al derivar los valores fieldlen y
fielddec de "Precision" y "NumericScale", manejando los valores excepcionales con cuidado. Esta lógica se ha
mejorado en esta versión, teniendo en cuenta algunas de nuestras experiencias recientes.
* Nuevo: Función FW_ArrayAsRecordSet( [aArray], [aStruct] ) --> oAdoRecordSet
Deben especificarse aArray o aStruct o ambos. aArray debe ser una matriz bidimensional.
aStruct puede ser una estructura similar a la estructura de una DBF. Si se especifica aArray, aStruct puede
estar vacío o una lista de campos.
La función devuelve un conjunto de registros ADO, no conectado a ninguna base de datos, pero puede editarse,
agregarse, eliminarse y navegarse como cualquier otro conjunto de registros.
En cualquier momento, la matriz de datos se puede recuperar con aData: = RsGetRows (oRs)
Fuente: \fwh\source\function\adofuncs.prg
Ejemplo: \fwh\samples\arr2rs.prg
* Corrección: En el método MapCol( cFieldName, cPrompt ) de la clase TDatabase.
Si un nombre de campo anterior es más largo que el nombre de campo y sus caracteres iniciales
coinciden con el nombre de campo (por ejemplo, "FECHA1", "FECHA"), se asigna a la columna anterior.
Corregido.
* Mejora: Comando XBREPORT. Nueva clausula adicional [TO PDF <cPdf>]. Si se especifica, el informe
será grabado como PDF (cPdf).
* Nuevo: Función XEdit( [uSource], [cFieldList], [lNew] )
Proporciona un cuadro de diálogo para la edición del registro actual (opcionalmente un nuevo registro) de uSource.
- uSource: Puede ser un alias,una matriz, un hash, conjunto de registros, un conjunto de filas de MariaDB,
Dolphin, TMySql, un objeto de consulta PostgreSQL y por defecto el alias actual.
- cFieldList: Opcionalmente una lista de campos separados por comas. Por defecto todos _.
- lNew: Si es .T., muestra un registro en blanco y lo añade cuando graba. Por defecto es .F.
* Nuevo: Función XReport( [uSource], [acFields], [cPdf] )
- uSource: Puede ser un alias,una matriz, un hash, conjunto de registros, un conjunto de filas de MariaDB,
Dolphin, TMySql, un objeto de consulta PostgreSQL y por defecto el alias actual.
También se puede especificar un nombre de archivo dbf que se abrirá a través de RDDSETDEFAULT() y se cerrará
después de la generación del informe.
- acFields: Opcional, lista separada por comas o una matriz de nombres de campo.
- cPdf: Opcional. Si se especifica, el informe será guardado como fichero PDF.
* Corrección: En bar.prg: El método BtnAdjust() da un error de tiempo de ejecución si se coloca un
control distinto de btnbmp en la barra de botones.
* Nuevo: CLASSDATA bSetup en la clase TPreview. Si se asigna, el bloque de código es evaluado con oPreview y
oWnd como parámetros justo antes de activar la ventana de vista previa.
Ejemplo de uso:
RPrevUserBtns( nil, 2007 )
TPreview():bSetup := <|oPreview, oWnd|
WITH OBJECT oWnd:oBar
:aControls[ 10 ]:End()
ADel( :aControls, 10, .t. )
:BtnAdjust()
END
return nil
>
Esto elimina el botón de "Correo" de la barra.
* Mejora: Clase TDataRow (FW_Record)
- oRec := FW_Record():New( cDataSource, cFieldList, lNew, aInitVals )
Nuevo parámetro aInitVals. Si se especifica, los valores no vacíos en la matriz son preasignados
a _ correspondientes en caso de añadir nuevos registros.
- Nuevo método SetInitVals( aInitVals ): En caso de nuevos registros (registros en blanco), los valores iniciales
se pueden asignar previamente con este método.
* Mejora: Cuando se usa el formato "@X", los números negativos se tratan como débitos y se muestran con el sufijo " DB".
En algunas regiones, los usuarios prefieren mostrar " DR" en lugar de " DB".
Si el _ parámetro nuevo de FWNumFormat(...) se establece en .T., Xbrowse y los informes muestran " DR" en lugar de " DB".
* Nuevo: Función CurrencySymbol( [cNewSymbol] ) --> cPreviousSymbol
Por defecto, el simbolo de moneda es $, £, € or Rupee, dependiendo de la Region puesta por FWNumFormat( "A/B/E/I" ).
El programador puede configurar cualquier otro símbolo diferente.
* Nuevo: Función FW_DBINSERT(). Mueve los datos del registro actual hacia abajo y crea un registro en blanco en lugar
del registro actual.
* Mejora: uValBlank( aArray )
- uValBlank( aArray ) --> Devuelve una matriz con todos los elementos en blanco
- uValBlank( hHash ) --> Devuelve un hash con todos elementos en blanco
- uValBlank( number ) --> Ahora conserva los lugares decimales
* Mejora: En la clase TReport: Si los valores numéricos están formateados prefijando el símbolo de moneda, el símbolo se
imprime alineado a la izquierda en la columna.
* Mejora: XBrowser.prg: Ahora usa una barra de botones en lugar de botones bmp individuales.
* Nuevo: Función SegoeMDL2() --> .T.
Si la fuente Segoe MDL2 Assets está disponible.
* Comparación y comparación de cadenas, insensible a mayúsculas y minúsculas:
- Nueva función FW_AT( cSearch, [@]cString, [nStart], [nEnd], [ lWholeWord],
[lSkipQuotes],[@cFound], cReplace, lAll )
--> nAt (o aMatches, si lAll es .T. )
Igual que AT() o HB_AT(), pero no distingue entre mayúsculas y minúsculas, si se utilizan los primeros 4 parámetros.
Ejemplo: FW_AT( "O lInA", "Antonio Linares" ) --> 7
Características adicionales:
cSearch puede ser una cadena o matriz de cadenas. En caso de matriz, se informa de la aparición más temprana.
Si lWholeWord es .T., sólo coinciden las palabras completas.
Ejemplo: FW_AT( "EAR", "Years Hear Ear", nil, nil, .T. ) --> 12, pero no 2.
Si lSkipQuotes es .T., la búsqueda salta cualquier texto entre comillas, "...", '...' o [...]
Ejemplo: FW_AT( "NEAR", 'He said "it is near" but it is not near', nil, nil, nil, .T. )
--> 36 pero no 16.
Si @cFound se especifica como séptimo parámetro por referencia, se devuelve la coincidencia exacta encontrada en la cadena.
Ejemplo: En el caso anterior devuelve "near".
Si cReplace se especifica como octavo parámetro y cString es por referencia, cFound se reemplaza por cReplace.
Si el noveno parámetro lAll se establece en .T., todas las coincidencias se devuelven como una matriz.
En el caso de cReplace, todas las apariciones se reemplazan por cReplace.
- Nueva función FW_StrICmp(): Compara _ de caracteres ignorando minúsculas y mayúsculas.
Respecto al ajuste SET EXACT OFF/ON, se sobreescribe el asunto.
Uso 1: FW_StrICmp( cStr1, cStr2, [lExact] ) --> -1,0,+1 para menos, igual o mayor.
El tercer parámetro, si se especifica, anula la configuración de SET EXACT.
Uso 2: FW_StrICmp( cStr1, cCompOperator, cStr2, [lExact] ) --> .F. / .T.
Ejemplo: FW_StrICmp( c1, ">=", c2, [nil,.T.,.F.] ) --> .T./.F.
El operador "==" fuerza la comparación exacta.
En _, el cuarto parámetro especifica si la comparación es exacta y si se omite, se utiliza la configuración
predeterminada.
* FWMariaDB:
- Corrección: Cuando la consulta SQL contiene "order by field desc" seguido de "límit", el objeto de conjunto de filas
no reconoce el orden como descendente. Corregido.
* TDataRow (FW_Record):
- Corrección: En el caso de los registros añadidos, el método Undo() no está restaurando los valores por defecto
establecidos por el método SetDefault(fld, uDefault). Corregido.
- Corrección: En el caso de los registros añadidos, los valores predeterminados establecidos por el método SetDefault()
se muestran pero no se guardan, si no son modificados por el usuario. Corregido.
- Botones de edición de diálogos: las fuentes de ala usadas para los botones no se muestran correctamente en las versiones
recientes de Windows 10. Resuelto utilizando la fuente Segoe MDL2 Assets si está instalada.
* ORM
Lanzada la primera versión ORM, en desarrollo.
Soporta DBase, Foxpro, MS Access, Microsoft SQL Server, MySQL, Oracle con ADO, y MySQL con ADO, Dolphin y FWMariaLib.
- Clase ORM_Connection
Sintáxis:
- oConnection := ORM_Connection():New( rdbms, server, database, user, password )
donde rdbms puede ser MySQL, Microsoft SQL Server, Oracle, etc... para ADO o Dolphin / FWMariaDB para MySQL con estas librerías.
// o //
- oConnection := ORM_Connection():New( oAdoConn (or) oDolphinServ (or) oFwCon )
Métodos:
New()
Tables() // Lista de tablas
HasTable( cTable ) --> lExists
Table( cTable ) --> ORM_Table Object
Close()
- Class ORM_Table()
Se puede crear una instancia del objeto de tabla mediante una llamada
oTable := oConnection:Table( cTableName )
o
oTable := ORM_Table():New( oConnection, cTableName )
Métodos:
Navegación: First(), Last(), Next(), Prev(), Move(n), MoveTo( n )
Otros:
Select( aFields )
Where( Field, [cOperator], Value )
OrderBy( field )
Get( [field )
XBrowse( [fieldlist] )
Edit()
Sum(field), Max(field), Min(field), Avg(field)
GroupBy( fields )
Find( primarykeyval ) or Find( field, value )
* Nuevo: Clase TDockPnel
- Nuevo contenedor de estilo, por favor revise el código de ejemplos y el wiki
http://wiki.fivetechsoft.com/doku.php?i ... _tdockpnel
- Ejemplos: Testdock01.prg, Testdock02.prg, TestDock04.prg
* TGet.prg: Cuando se asigna un mapa de bits para la cláusula "ACTION", el recurso de mapa de bits
no se libera. Corregido.
* Función FW_ArrayToDBF( aArray, cFieldList, ... ): Mejoras:
- cFieldList puede contener "*", el cual se sustituye por la lista completa de campos.
- cFieldList puede contener "RECNO()". En tales casos, los registros se escriben en ese RecNo() si no
están vacíos y se añaden si están vacíos.
* Nueva función FW_UTCTOLOCAL( tUtc ) --> tLocalTime
* Nueva función FW_TimeZoneName() --> nombre de la zona horaria local
* Clase TPanel: Nuevo método Redefine() // Por favor revise FiveWin.ch para la definición
===============
* Corrección: En el método Center() de la clase TWindow, no actualizaba las coordenadas de la ventana.
Ahora está corregido.
* Correción: Pequeña corrección en el método PaintFld() de la clase TRibbonBar para eliminar un mal
efecto de pintado en algunas circustancias.
* Corrección: En source\function\imgtxtio.prg: Las funciones FW_SayText() y FW_DrawImage() no estaban
devolviendo el "BkMode" del contexto del dispositivo después de cambiar a transparente. Corregido ahora.
* Mejora: En la clase TPrinter: Si el método Say() es llamado con un texto en color, el color cambiado
se convierte en predeterminado para todas las llamadas subsiguientes de este método.
Nuevo CLASSDATA lResetSayColors INIT .f.
Si es puesto a .T., las llamadas a Say() con un color de texto se aplican solo a ese Say() y no afectan
a los siguientes.
* Mejora: En mostrar/imprimir texto multilínea:
Las funciones DrawTextEx(), FW_SayText() y el método SayText() de las clases TWindow y TPrinter pueden
generar texto de una sola línea o de varias líneas para encajar dentro del rectángulo especificado.
Cuando todo el texto de varias líneas no puede caber dentro del rectángulo especificado, el texto restante
se devuelve en el parámetro cText, si cText se llama por referencia. Si el texto devuelto no está vacío,
el programador puede decidir dónde imprimir el texto restante, es decir, en una página separada, columna
o ignorar.
Uso: oPrn:SayText( row, col, @cText, width, height, ... )
* XBrowse:
- Nueva DATA bPaintBack. Si se especifica, este bloque de código se usa para dibujar el fondo del "xbrowse",
en lugar de la lógica incorporada.
- El filtro incremental en un "browse" de matrices ahora se puede usar incluso cuando lAutoSort es falso.
Anteriormente, al tratar de usar filtros incrementales sin autoordenación daba errores de tiempo de ejecución.
- Mejora: En el método EditSource( lNew, cFieldList, aInitVals )
Nuevo parámetro aInitVals: Si se especifica, los valores no vacíos en la matriz se asignan previamente a los
campos correspondientes en caso de que haya nuevos registros (en blanco).
http://forums.fivetechsupport.com/viewt ... 28#p221428
- Nueva DATA clCurrency para TXBrwColumn: Por defecto NIL.
Se puede establecer a .T. o cualquier símbolo de moneda. Si es .T., el símbolo de moneda predeterminado o el símbolo
de moneda asignado se agrega a la cláusula "PICTURE" y se muestra alineado a la izquierda en la columna.
- Correción en le método GoRight: Cuando oBrw:lTransparent := .T., y el cursor se mueve hacia la derecha con la tecla
de flecha, el resaltado no se borra de las celdas anteriores. Corregido.
- Autosort: Incluso si no se especifica autoordenación cuando se crea el browse, internamente el browse se mantiene
preparado para autoordenación.
El programador puede alternar oBrw:lAutosort en cualquier momento durante el tiempo de ejecución para que funcione.
- Corrección en SetCheck(): Los ajustes de SetCheck() se alteran cuando los métodos SetArray(), etc..., son llamados
durante el tiempo de ejecución. Corregido.
- Los filtros incrementales con DBFs reemplazan los filtros existentes. Ahora se respetan los filtros existentes y
el filtro incremental es tratado como un filtro adicional.
* Nueva función AShuffle( aArray ) --> aArray
Ordena una matriz dada en orden aleatorio.
* Nueva función DBF_ApplyParams( cExpr, aParams ) --> cExpr
Sustituye en el lugar donde está ? en cExpr por el valor correspondiente en aParams y devuelve la expresión completa.
Ejemplo:
cName := "T"
dDate := DTOS( "20000101" )
cFilter := ;
DBF_ApplyParams( "UPPER(FIRST) = ? .AND. HIREDATE >= ?", ;
{ cName, dDate } ) -->
"UPPER(FIRST) = "T" .AND. HIREDATE >= 0d20000101"
SET FILTER TO &cFilter
* Nueva función FW_DbFilterBlock() --> bFilterExp
La función de Harbour DBFILTER() devuelve la condición del filtro como una cadena de caracteres.
Esta función devuelve el bloque de código usado por el filtro.
* Database.prg
- Nuevo: Método SetFilter( cFilter, aParams ): se ha añadido aParams como segundo parámetro.
aParams es una matriz de valores para ser insertada en el lugar marcado por el símbolo ?.
aParams también puede ser un bloque de código que devuelve una matriz cuando es evaluado.
Uso:
oDbf:SetFilter( "UPPER(FIRST) = ? .AND. HIREDATE >= ?", ;
{ cName, dDate } )
- Nuevo: Método Refilter( aParams ): Restablece el filtro utilizando la expresión de filtro
utilizada previamente con los nuevos parámetros.
- Mejora: Cuando la relación se establece con otro objeto TDatabase, utilizando el método
SetRelation(), el método de carga de la base de datos relacionada se llama automáticamente
cuando se mueve el puntero de registro de la tabla principal.
No hay más necesidad de llamar a oRelatedTable:Load().
- Corrección: oDbf:Blank(), asigna valores y llama a oDbf:Save() no funciona cuando EOF es puesto a .T.
Corregido ahora.
- Corrección: oDbf:Append() sin parámetros añade un registro en blanco. Pero oDbf:Load() necesita
ser llamada para asignar valores y grabarlos. Ahora oDbf:Append() llama también a oDbf:Load().
- Nuevo: Método Browse( [cTitle], [acFields] ) --> Self
* adofuncs.prg, xbrowse.prg, datarow.prg: Mejorada la comprobación de fieldlen, fielddec en caso
de los tipos adDouble y adSingle en ADO, dónde los atributos "Precision" y "NumericScale" no
se especifican.
En el caso de _ numéricos en ADO, oField:Precision es equivalente a FIELDLEN() y
oField:NumericScale es equivalente a FIELDDEC().Sin embargo, la Precisión no cuenta el espacio requerido
para la posición decimal.
Hay muchos tipos numéricos en ADO. En _ como adSingle, adDouble, estos valores difieren en la
forma en que se crea la tabla y difieren de un servidor a otro y de un proveedor a otro. En _,
el campo puede ser el resultado de un cálculo. Debemos tener cuidado al derivar los valores fieldlen y
fielddec de "Precision" y "NumericScale", manejando los valores excepcionales con cuidado. Esta lógica se ha
mejorado en esta versión, teniendo en cuenta algunas de nuestras experiencias recientes.
* Nuevo: Función FW_ArrayAsRecordSet( [aArray], [aStruct] ) --> oAdoRecordSet
Deben especificarse aArray o aStruct o ambos. aArray debe ser una matriz bidimensional.
aStruct puede ser una estructura similar a la estructura de una DBF. Si se especifica aArray, aStruct puede
estar vacío o una lista de campos.
La función devuelve un conjunto de registros ADO, no conectado a ninguna base de datos, pero puede editarse,
agregarse, eliminarse y navegarse como cualquier otro conjunto de registros.
En cualquier momento, la matriz de datos se puede recuperar con aData: = RsGetRows (oRs)
Fuente: \fwh\source\function\adofuncs.prg
Ejemplo: \fwh\samples\arr2rs.prg
* Corrección: En el método MapCol( cFieldName, cPrompt ) de la clase TDatabase.
Si un nombre de campo anterior es más largo que el nombre de campo y sus caracteres iniciales
coinciden con el nombre de campo (por ejemplo, "FECHA1", "FECHA"), se asigna a la columna anterior.
Corregido.
* Mejora: Comando XBREPORT. Nueva clausula adicional [TO PDF <cPdf>]. Si se especifica, el informe
será grabado como PDF (cPdf).
* Nuevo: Función XEdit( [uSource], [cFieldList], [lNew] )
Proporciona un cuadro de diálogo para la edición del registro actual (opcionalmente un nuevo registro) de uSource.
- uSource: Puede ser un alias,una matriz, un hash, conjunto de registros, un conjunto de filas de MariaDB,
Dolphin, TMySql, un objeto de consulta PostgreSQL y por defecto el alias actual.
- cFieldList: Opcionalmente una lista de campos separados por comas. Por defecto todos _.
- lNew: Si es .T., muestra un registro en blanco y lo añade cuando graba. Por defecto es .F.
* Nuevo: Función XReport( [uSource], [acFields], [cPdf] )
- uSource: Puede ser un alias,una matriz, un hash, conjunto de registros, un conjunto de filas de MariaDB,
Dolphin, TMySql, un objeto de consulta PostgreSQL y por defecto el alias actual.
También se puede especificar un nombre de archivo dbf que se abrirá a través de RDDSETDEFAULT() y se cerrará
después de la generación del informe.
- acFields: Opcional, lista separada por comas o una matriz de nombres de campo.
- cPdf: Opcional. Si se especifica, el informe será guardado como fichero PDF.
* Corrección: En bar.prg: El método BtnAdjust() da un error de tiempo de ejecución si se coloca un
control distinto de btnbmp en la barra de botones.
* Nuevo: CLASSDATA bSetup en la clase TPreview. Si se asigna, el bloque de código es evaluado con oPreview y
oWnd como parámetros justo antes de activar la ventana de vista previa.
Ejemplo de uso:
RPrevUserBtns( nil, 2007 )
TPreview():bSetup := <|oPreview, oWnd|
WITH OBJECT oWnd:oBar
:aControls[ 10 ]:End()
ADel( :aControls, 10, .t. )
:BtnAdjust()
END
return nil
>
Esto elimina el botón de "Correo" de la barra.
* Mejora: Clase TDataRow (FW_Record)
- oRec := FW_Record():New( cDataSource, cFieldList, lNew, aInitVals )
Nuevo parámetro aInitVals. Si se especifica, los valores no vacíos en la matriz son preasignados
a _ correspondientes en caso de añadir nuevos registros.
- Nuevo método SetInitVals( aInitVals ): En caso de nuevos registros (registros en blanco), los valores iniciales
se pueden asignar previamente con este método.
* Mejora: Cuando se usa el formato "@X", los números negativos se tratan como débitos y se muestran con el sufijo " DB".
En algunas regiones, los usuarios prefieren mostrar " DR" en lugar de " DB".
Si el _ parámetro nuevo de FWNumFormat(...) se establece en .T., Xbrowse y los informes muestran " DR" en lugar de " DB".
* Nuevo: Función CurrencySymbol( [cNewSymbol] ) --> cPreviousSymbol
Por defecto, el simbolo de moneda es $, £, € or Rupee, dependiendo de la Region puesta por FWNumFormat( "A/B/E/I" ).
El programador puede configurar cualquier otro símbolo diferente.
* Nuevo: Función FW_DBINSERT(). Mueve los datos del registro actual hacia abajo y crea un registro en blanco en lugar
del registro actual.
* Mejora: uValBlank( aArray )
- uValBlank( aArray ) --> Devuelve una matriz con todos los elementos en blanco
- uValBlank( hHash ) --> Devuelve un hash con todos elementos en blanco
- uValBlank( number ) --> Ahora conserva los lugares decimales
* Mejora: En la clase TReport: Si los valores numéricos están formateados prefijando el símbolo de moneda, el símbolo se
imprime alineado a la izquierda en la columna.
* Mejora: XBrowser.prg: Ahora usa una barra de botones en lugar de botones bmp individuales.
* Nuevo: Función SegoeMDL2() --> .T.
Si la fuente Segoe MDL2 Assets está disponible.
* Comparación y comparación de cadenas, insensible a mayúsculas y minúsculas:
- Nueva función FW_AT( cSearch, [@]cString, [nStart], [nEnd], [ lWholeWord],
[lSkipQuotes],[@cFound], cReplace, lAll )
--> nAt (o aMatches, si lAll es .T. )
Igual que AT() o HB_AT(), pero no distingue entre mayúsculas y minúsculas, si se utilizan los primeros 4 parámetros.
Ejemplo: FW_AT( "O lInA", "Antonio Linares" ) --> 7
Características adicionales:
cSearch puede ser una cadena o matriz de cadenas. En caso de matriz, se informa de la aparición más temprana.
Si lWholeWord es .T., sólo coinciden las palabras completas.
Ejemplo: FW_AT( "EAR", "Years Hear Ear", nil, nil, .T. ) --> 12, pero no 2.
Si lSkipQuotes es .T., la búsqueda salta cualquier texto entre comillas, "...", '...' o [...]
Ejemplo: FW_AT( "NEAR", 'He said "it is near" but it is not near', nil, nil, nil, .T. )
--> 36 pero no 16.
Si @cFound se especifica como séptimo parámetro por referencia, se devuelve la coincidencia exacta encontrada en la cadena.
Ejemplo: En el caso anterior devuelve "near".
Si cReplace se especifica como octavo parámetro y cString es por referencia, cFound se reemplaza por cReplace.
Si el noveno parámetro lAll se establece en .T., todas las coincidencias se devuelven como una matriz.
En el caso de cReplace, todas las apariciones se reemplazan por cReplace.
- Nueva función FW_StrICmp(): Compara _ de caracteres ignorando minúsculas y mayúsculas.
Respecto al ajuste SET EXACT OFF/ON, se sobreescribe el asunto.
Uso 1: FW_StrICmp( cStr1, cStr2, [lExact] ) --> -1,0,+1 para menos, igual o mayor.
El tercer parámetro, si se especifica, anula la configuración de SET EXACT.
Uso 2: FW_StrICmp( cStr1, cCompOperator, cStr2, [lExact] ) --> .F. / .T.
Ejemplo: FW_StrICmp( c1, ">=", c2, [nil,.T.,.F.] ) --> .T./.F.
El operador "==" fuerza la comparación exacta.
En _, el cuarto parámetro especifica si la comparación es exacta y si se omite, se utiliza la configuración
predeterminada.
* FWMariaDB:
- Corrección: Cuando la consulta SQL contiene "order by field desc" seguido de "límit", el objeto de conjunto de filas
no reconoce el orden como descendente. Corregido.
* TDataRow (FW_Record):
- Corrección: En el caso de los registros añadidos, el método Undo() no está restaurando los valores por defecto
establecidos por el método SetDefault(fld, uDefault). Corregido.
- Corrección: En el caso de los registros añadidos, los valores predeterminados establecidos por el método SetDefault()
se muestran pero no se guardan, si no son modificados por el usuario. Corregido.
- Botones de edición de diálogos: las fuentes de ala usadas para los botones no se muestran correctamente en las versiones
recientes de Windows 10. Resuelto utilizando la fuente Segoe MDL2 Assets si está instalada.
* ORM
Lanzada la primera versión ORM, en desarrollo.
Soporta DBase, Foxpro, MS Access, Microsoft SQL Server, MySQL, Oracle con ADO, y MySQL con ADO, Dolphin y FWMariaLib.
- Clase ORM_Connection
Sintáxis:
- oConnection := ORM_Connection():New( rdbms, server, database, user, password )
donde rdbms puede ser MySQL, Microsoft SQL Server, Oracle, etc... para ADO o Dolphin / FWMariaDB para MySQL con estas librerías.
// o //
- oConnection := ORM_Connection():New( oAdoConn (or) oDolphinServ (or) oFwCon )
Métodos:
New()
Tables() // Lista de tablas
HasTable( cTable ) --> lExists
Table( cTable ) --> ORM_Table Object
Close()
- Class ORM_Table()
Se puede crear una instancia del objeto de tabla mediante una llamada
oTable := oConnection:Table( cTableName )
o
oTable := ORM_Table():New( oConnection, cTableName )
Métodos:
Navegación: First(), Last(), Next(), Prev(), Move(n), MoveTo( n )
Otros:
Select( aFields )
Where( Field, [cOperator], Value )
OrderBy( field )
Get( [field )
XBrowse( [fieldlist] )
Edit()
Sum(field), Max(field), Min(field), Avg(field)
GroupBy( fields )
Find( primarykeyval ) or Find( field, value )
* Nuevo: Clase TDockPnel
- Nuevo contenedor de estilo, por favor revise el código de ejemplos y el wiki
http://wiki.fivetechsoft.com/doku.php?i ... _tdockpnel
- Ejemplos: Testdock01.prg, Testdock02.prg, TestDock04.prg
* TGet.prg: Cuando se asigna un mapa de bits para la cláusula "ACTION", el recurso de mapa de bits
no se libera. Corregido.
* Función FW_ArrayToDBF( aArray, cFieldList, ... ): Mejoras:
- cFieldList puede contener "*", el cual se sustituye por la lista completa de campos.
- cFieldList puede contener "RECNO()". En tales casos, los registros se escriben en ese RecNo() si no
están vacíos y se añaden si están vacíos.
* Nueva función FW_UTCTOLOCAL( tUtc ) --> tLocalTime
* Nueva función FW_TimeZoneName() --> nombre de la zona horaria local
* Clase TPanel: Nuevo método Redefine() // Por favor revise FiveWin.ch para la definición
- Silvio.Falconi
- Posts: 4956
- Joined: Thu Oct 18, 2012 7:17 pm
Re: New FTDN May/Mayo 2019 (FWH 19.05)
I have tried both testdock01 and 02
make errors
make errors
Code: Select all
Application
===========
Path and name: C:\Work\fwh\samples\testdock02.Exe (32 bits)
Size: 4,145,152 bytes
Compiler version: Harbour 3.2.0dev (r1712141320)
FiveWin version: FWH 19.05
C compiler version: Borland/Embarcadero C++ 7.3 (32-bit)
Windows version: 6.1, Build 7601 Service Pack 1
Time from start: 0 hours 0 mins 0 secs
Error occurred at: 06/18/19, 12:44:47
Error description: Error BASE/1004 Message not found: TGRAPH:SETARRAYFONTS
Args:
[ 1] = O TGRAPH
Stack Calls
===========
Called from: => __ERRRT_SBASE( 0 )
Called from: ../../../tobject.prg => TGRAPH:ERROR( 0 )
Called from: ../../../tobject.prg => (b)HBOBJECT( 0 )
Called from: ../../../tobject.prg => TGRAPH:MSGNOTFOUND( 0 )
Called from: ../../../tobject.prg => TGRAPH:SETARRAYFONTS( 0 )
Called from: testdock02.prg => TEST2( 394 )
Called from: testdock02.prg => (b)CREADOCKS( 216 )
Called from: .\source\internal\TDOCKPNEL.PRG => TDOCKPNEL:PAINTPNELH( 814 )
Called from: .\source\internal\TDOCKPNEL.PRG => TDOCKPNEL:PAINTCTRLSPNELP( 739 )
Called from: .\source\internal\TDOCKPNEL.PRG => (b)TDOCKPNEL_CREATEPNELP( 660 )
Called from: .\source\classes\TPANEL.PRG => TPANEL:PAINT( 162 )
Called from: .\source\classes\TPANEL.PRG => (b)TPANEL( 23 )
Called from: .\source\classes\TPANEL.PRG => TPANEL:DISPLAY( 0 )
Called from: .\source\classes\CONTROL.PRG => TPANEL:HANDLEEVENT( 1767 )
Called from: .\source\classes\WINDOW.PRG => _FWH( 3546 )
Called from: => UPDATEWINDOW( 0 )
Called from: .\source\classes\WINDOW.PRG => TWINDOW:ACTIVATE( 1055 )
Called from: testdock02.prg => TESTDOCKPNEL( 98 )
Called from: testdock02.prg => MAIN( 62 )
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
Re: New FTDN May/Mayo 2019 (FWH 19.05)
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.