Primeros pasos tras el curso…
mayo 30, 2007 en Artículos, Entrada Diario, Velneo
Comentaba en una de las entradas anteriores, que hace poco había acabado el curso virtual de Velneo que incluye la compra de la versión profesional. En lineas generales me pareció muy correcto y cuando se finaliza, al menos se tiene una idea bastante general de lo que te puede ofrecer este entorno de trabajo. Es similar a cuando compramos un libro de introducción a un tema, con la diferencia que en este tipo de cursos y el hecho precisamente de tener un tutor que nos oriente, puede facilitarnos ese aprendizaje en menor tiempo.
Sin embargo, tanto los libros como los cursos, nos dejan en ese punto inicial crítico que yo quise remarcar en el título del blog: “Desde cero”. Me explico y si me lo permitiis utilizare un simil del mundo animal: es semejante al momento en el que el polluelo debe de saltar del nido y probar las alas. Es su primer salto. Y la madre no escatima “picotazos” hasta que le hace saltar (es broma lo de los picotazos) porque ¡no va a quedarse toda la vida en el nido!. Los ejemplos que se viven en los cursos, los que se escriben en los libros, los que leemos en las webs, se escriben como lo que son, ejemplos. Se preparan y se buscan para que la persona que los lee no se pierda en detalles menos importantes y se centre en algunos temas concretos.
Así que al referir desde el titulo esa idea de partir desde cero, hacía alusión a los momentos en los que nos preparamos para intentar adaptar esos conocimientos aprendidos a la vida real, cosa que sin duda ya no resulta tan sencilla.
Podemos, como yo ya me lo he planteado, pensar en poner en marcha algun tipo de desarrollo con esta nueva herramienta. Es cuestión de pensar un poco y ver como rentabilizar los recursos que estamos adquiriendo. En mi caso concreto, disponía de la plantilla de gestión y la de tpv. Pues bueno… ¡adelante!. Vamos a ver donde la podemos colocar para poder verla trabajar en el mundo real. Eso nos dará una idea bastante buena de qué problemas vamos a encontrarnos, y nos permitirá conocer con mas detalle las distintas tablas y sus relaciones. En mi opinión puede ser interesante decantarnos por un comercio mas o menos pequeño, que no nos obligue en un primer momento a modificar demasiados puntos de la plantilla original.
Por otro lado, y dado que ya partimos de la experiencia previa de haber trabajado con otras herramientas, parece hasta cierto punto lógico ver si de alguna forma nos podemos valer de ellas en algo. En el caso de Velneo hemos aprendido durante el curso que el entorno puede ser mejorado mediante la instalación de pluggins que nos permitirán funcionalidades nuevas. Es el ejemplo del pluggin v2Excel, que nos permite manipular la hoja de cálculo del Office. Otro ejemplo puede ser el vODBC para la gestión de bases de datos externas a través de ODBC.
La utilización de estos pluggins es realmente sencilla ya que están correctamente documentados y el mecanismo de llamada de las funciones a través de la invocación de los procesos es sencillo. En ese sentido no creo que tengáis demasiados problemas. Estos temas los iremos abordando un poco mas adelante.
Sin embargo, mientras escribía estas líneas y escudriñaba en la funciones o rutinas disponibles desde Velneo, es dificil no echar de menos algunas de las funciones mas habituales a las que estabamos acostumbrados desde un entorno como Delphi. Disponíamos de mayor número de funciones de apoyo. Se me ocurre por ejemplo el area de la manipulación de fechas, pero podríamos extenernos a otras areas.
Si os parece vamos a jugar un rato…
La idea es intentar hacernos nuestro primer pluggin y para ello nos basta abrir el entorno de delphi y crear una librería que nos pueda servir de ayuda como funciones auxiliares. Se trata tan solo de un ejemplo ¿vale?
Nos permitirá saber si realmente es dificil ampliar nuestro entorno con nuevas funciones y de paso, aprovechar algunas rutinas que podamos haber implementado tiempo atras (si fuera el caso).
Elegimos nueva libreria y tras un rato tecleando veamos que obtenemos:
library firstlib;
uses
Windows,
Messages,
SysUtils,
Dialogs,
calendario in ‘calendario.pas’ {frmFecha};
function Max3(Num1, Num2, Num3: Integer): Integer; stdcall;
begin
Result:= Num1;
if Num2 > Result then Result:= Num2;
if Num3 > Result then Result:= Num3;
end;
function MensajeAlerta(const ATipo: Smallint): Integer; stdcall;
begin
Result:= ATipo;
case ATipo of
0: ShowMessage(
’Mostramos un calendario en una ventana modal.’+#13#10+
’Pulsar en una dia del mismo con un doble click.’+#13#10+
’La variable FECHA asignada a la casilla de texto’+#13#10+
’visualizará el valor’);
1: ShowMessage(
’Vamos a mostrar un cuadro de dialogo.’+#13#10+
’El usuario elige el directorio correspondiente +#13#10+
’Y la variable ARCHIVO asignada a la casilla de texto’+#13#10+
’visualizará el valor’);
else
Result:= -1;
end;
end;
function GetStrDate: PChar; stdcall;
var
MiFecha: TDateTime;
s: String;
res: Array[0..MAX_PATH] of Char;
begin
frmFecha:= TfrmFecha.Create(nil);
try
frmFecha.ShowModal;
MiFecha:= frmFecha.fFecha;
finally
FreeAndNil(frmFecha);
end;
s:= FormatDateTime(‘dd/mm/yyyy’, MiFecha);
StrCopy(res, PChar(s));
Result:= res;
end;
function GetFileName: PChar; stdcall;
var
Dialogo: TOpenDialog;
s: String;
res: Array[0..MAX_PATH] of Char;
begin
Dialogo:= TOpenDialog.Create(nil);
try
if Dialogo.Execute then
s:= Dialogo.FileName;
finally
FreeAndNil(Dialogo);
end;
StrCopy(res, PChar(s));
Result:= res;
end;
{$R *.res}
exports
Max3, MensajeAlerta, GetStrDate, GetFileName;
begin
end.
No reflejo aquí el código de la unidad “calendario.pas” para no extenderme demasiado. Esta unidad será requerida por la librería para mostrar un calendario que nos permitirá elegir una fecha del mismo. Básicamente, tenemos un total de 3 funciones “utiles”:
Max3: Devuelve el mayor de los tres números que se han pasado como parámetros.
GetStrDate: Devuelve una cadena con la fecha elegida por el usuario.
GetFileName: Devuelve una ruta hacia un fichero.
Podéis descargar la librería desde este enlace: firstlib
Y en este otrol vínculo está el codigo fuente de la misma: codigo
Ahora ya es tiempo de abrir el entorno de Velneo e intentar enlazar nuestra librería para que pueda ser usada desde el mismo. Para simplificar, elegimos nuevo proyecto vacío. Una vez que se ha seleccionado la ruta en la que guardamos el proyecto, la ventana principal nos muestra el mínimo contenido que es generado por defecto en la ventana de estructura de datos y que se corresponde con la tabla VMAESTROS. Es decir que ya tenemos un proyecto sobre el que probar nuestra librería.
Veamos…
Tenemos que importar un objeto libreria por lo cual, llamamos a la opción Nuevo Objeto, bien desde los botones de la barra superior
o bien desde el menu de la aplicacion (Objetos -> Nuevo -> Objeto) que nos conducirá a la siguiente ventana.

Y desde alli, tras seleccionar con el doble click sobre el objeto librería de funciones (dll), podremos disponer de una ventana donde especificar todos los datos de las funciones de la dll, asi como el nombre de la misma y el estilo.
Rellenamos las casillas adecuadamente, quedando finalmente tal y como nos muestra la ventana:

Ahora no vamos a abordar algunos detalles interesantes sobre las librerias. Si os parece los dejaremos para las siguientes entradas, donde comentaremos que es eso de “stdcall” o los puntos que pueden ser un tanto problematicos en el uso de librerias. Yo por ejemplo he remitido una consulta técnica a Velneo para preguntar sobre cómo gestiona la reserva de memoria el entorno en el caso de cadenas terminadas en nulo o PChar, de cara a evitar cualquier goteo de memoria. Es posible que tenga que rectificar algun detalle de la libreria. Desde Delphi, como ya comentaremos, suele ser habitual reservar memoria desde la función y eliminarla con una llamada desde la misma aplicación que carga la librería. En este caso, he utilizado un array de char para alojar el retorno de la función.
Desgargar el siguiente mapa y lo podéis probar: vlibreria.zip






http://www.danysoft.com/
http://www.embarcadero.com
Delphi Access
Je, ese tipo de integraciones con Delphi las he hecho más de una vez para otros productos. A ver si te puedo decir algo que te sirva, mientras te contestan los de Velneo.
Esa forma de crear el array en la pila no es buena idea. Al salir de la función ese espacio queda disponible y sí, el resultado está ahí, de acuerdo; pero en cualquier momento esa zona de memoria puede sobreescribirse y corromperse el resultado.
Claro que tampoco sería buena idea pasar una cadena: la memoria nunca se devolvería.
Sugerencia: pasar el buffer a Delphi desde Velneo por referencia, si es que se puede hacer, claro. O quizás Velneo ofrece algún tipo de callback para que desde Delphi se pueda reservar memoria usando el gestor de memoria de Velneo.
Hola Nico:
Me alegro mucho de que contestes porque las mismas inquietudes que te planteas las he tenido yo mientras lo escribia. En un primer momento, en las primeras pruebas, utilice una rutina para reservar memoria pero el problema es que despues, desde Velneo, no encuentro la forma de liberarla. Así que opte por un segundo planteamiento que inicialmente disponia la variable de forma global.
Esta segunda posibilidad tampoco me convencía pensando que quizás en un entorno multitarea pudiera ser sobreescrita, por lo que finalmente la moví a la zona local de la función.
Al final del post, comento que hice la consulta a Velneo para intentar averiguar como enfocar el tema para evitar un goteo de memoria o que pueda ser corrompida accidentalmente. Estoy pendiente de recibir algun comentario.
Así que conforme averigue algo lo ire comentando por si puede ayudar a alguien.
Muchas gracias, Nico.
Buenos Días, dime tendrias alguna DLL ehca que serba para llamar el cuadro de diálogo Buscar y Seleccionar Carpeta de Windows, como para que funcione en VELNEO, desde ya gracias