Discusiones sobre Productos NI

cancelar
Mostrando los resultados de 
Buscar en lugar de 
Quiere decir: 

Guardar/Cargar Preferencias al Cerrar/Abrir Labwindow

¡Resuelto!
Ir a solución

Saludos:

 

Realizando una interfaz para un proyecto, se me ha ocurrido darle cierta flexibilidad al usuario añadiendo un panel de preferencias donde el usuario pueda elegir que ventana desea que se carge al inicio, si quiere o no que un proceso se haga automáticamente etc.

El problema está en que todas las selecciones que haga serán válidad mientras esté el programa abierto, pero una vez que se cierra, el valor de los controles vuelve al valor por defecto que tienen.

¿Qué se podría hacer para que al reabrir el programa carge los valores con el que se ha cerrado?¿Guardarlos en una especie de log?

 

Gracias por vuestro tiempo.

0 kudos
Mensaje 1 de 13
4.801 Vistas
Solución
Aceptado por el autor del tema ProyectoUni

Lo que normalmente se hace es almacenar las preferencias del usuario en un archivo u en el registro del sistema y leerlas al iniciar el programa.

En mis aplicaciones siempre añado una función al iniciar, antes de que se cargue el panel principal, en la que hago una serie de controles y operaciones necesarias para que el programa corra sin problemas: averiguar que hayan los archivos añadidos que se necesiten, leer la configuración, iniciar la comunicación con los dispositivos internos u externos que se vayan usando...

 

Para almacenar las informaciones de configuración se puede usar los archivos .INI, por los que el CVI viene con un instrumento que los puede leer y escribir (normalmente está en <cvidir>\toolslib\toolbox\inifile.fp).Puesto que los .INI son archivos de texto, es simple averiguar lo quehace el programa viendolos con un editor de texto.

Sin embargo, otra opción el la de almacenar en el registro del sistema: en este caso también el CVI te proporciona instrumentos, puesto que el el Programmer's Toolbox hay los comandos que se necesitan para obrar sobre el registro (este instrumento se encuentra en <cvidir>\toolslib\toolbox\toolbox.fp)

Si buscas en los ejemplos que vienen con el producto puedes encontrar uno para trabajar con los archivos .INI.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 kudos
Mensaje 2 de 13
4.797 Vistas

Muchas gracias por tu anteior respuesta.

Me ha servido de mucho usar un archivo INI para inicializar todo lo que necesitaba. Por desgracia no todo son algodones y ya ha surgido un problema. El caso es que pido que se tome una variable double del archivo ini de valor 20 o 20.00 da lo mismo, y al cargarla en la variable pointer declarada como double, carga un valor de 20.00000000000 por lo que luego al intentar poner ese valor en un control me da error por que espera un char en vez de un double al ser tan largo.

Me pregunto como solucionar el problema, si hay alguna manera de decir que solo tome dos decimales desde el ini. Te adjunto parte del código por si no me explico bien:

 

double pointer;

 

Ini_GetDouble (Inifile, "Limits", "Posxmin", &pointer);
SetCtrlVal (PanelMotor, PANELLimit_NUMERIC, pointer);
Ini_GetDouble (Inifile, "Limits", "Posxmax", &pointer);
SetCtrlVal (PanelMotor, PANELLimit_NUMERIC_2, pointer);

 

Los controles NUMERIC están puesto como double.

 

También, si ánimo de abusar, pregunto si hay alguna manera de simplificar lo siguiente: Al inicializar tengo que cargar al rededor de 20 valores a unos controles. ¿Se puede hacer algo más corto (por simplificar el código) que escribir un Ini_GetDouble y un SetCtrlVal por cada control?

 

Gracias por tu respuesta que seguro será satisfactoria.

0 kudos
Mensaje 3 de 13
4.770 Vistas

Hola, en tu respuesta creo que hay un malentendido entre el valor de un número y su representación. Voy a esplicarme. Si tu tienes una variable de doble precisión, esta siempre puede ser cargada en un control con el mismo tipo de datos, sin que el número de decimales pueda dar problemas. Lo que pasa es que tal número puede ser mostrado con más o menos decimales el la pantalla, pero esta es sólo una representación visiva del número. Esto es: una variable que contiene el número 12.34567890123 puede ser mostrada en un indicator en la pantalla como 12.34, 12.3 u también como 12.3457 siendo siempre el mismo número que será utilizado en las calculaciones.

Lo que en mi opinión está pasando en tu programa es que por algun motivo estás intentando pasar un número a una variable texto y de ahí el error "expected char but found double". Esto puede pasar por estar utilizando una referencia incorrecta al panel en el que está el control: por ejemplo porque el control está en una hoja de un tab y estás usando el panel handle del panel en el que se encuentra el tab. Si este es el caso, debes considerar que cada hoja de un tab control realmente es un panel separado con su propio handle, lo que se obtiene con el comando GetPanelHandleFromTabPage: usando tal handle en el SetCtrlVal ya no tendrás algun problema.

 

 

 

Ahora bien, por lo que se refiere a los múltiples valores, creo que hay dos maneras para simplificar la tarea de leer muchos valores:

 

1. Usar un arreglo de controles y leer / escribir en un loop

 

int  control[10];     // Arreglo de control IDs

 

// Crear el arreglo de controles

control[0] =  PANELLimit_NUMERIC;

control[1] =  PANELLimit_NUMERIC_2;

....

 

// Leer del .INI y escribir en los controles

char  item[16] ;

 

for (i= 0; i < 20; i++) {

  sprintf (item, "Campo %d", i+1);

  Ini_GetDouble (Inifile, "Limits", item, &pointer);

  SetCtrlVal (panelHandle, control[i], pointer);

}

 

2. Formatear todos los números en un texto largo y escanear tal texto en un arreglo de números

 

El .INI será de tal forma:

 

[Limits]

Pos = "12.1; 12.2; 12.3; ........"

 

// Leer del .INI

char  string[256];

double  arreglo[20];

 

Ini_GetStringIntoBuffer (IniFile, "Limits", "pos", 256);

Scan  (string, "%20f[x]", arreglo);

 

// Poner en los controles

SetCtrlVal (panelHandle,  PANELLimit_NUMERIC, arreglo[0]);

SetCtrlVal (panelHandle,  PANELLimit_NUMERIC_2, arreglo[1]);

....

 

Sin embargo, en esta manera notar tu archivo .INI va perdiendo la capacidad de dar informaciones, ya que es muy diferente tener campos como "Pos X min", Pos X max" u tener "Campo 1", "Campo 2" u también "Limites =12.1, 12.3...". Personalmente prefiero tener un .INI que muestre claramente de qué variable se trate en cada campo sacrificando un poco por esto la función que lee / escribe el archivo, ya que prefiero poder revisar el .INI fuera del programa sin necesitar una "hoja de traducción". Pero reconozco que esta es questión de preferencias personales: ahora que tienes alguna información sobre el asunto puedes realizar la solución que prefieras.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 kudos
Mensaje 4 de 13
4.762 Vistas

Muchas gracias por tu respuesta.

Una vez más ha sido de gran ayuda. Al final me he decantado por  asignar a cada control una variable genérica y luego usar un for, por que después los controles son facilmente reconocibles en el Ini, en este caso.

 

 

0 kudos
Mensaje 5 de 13
4.711 Vistas

Una última pregunta, espero. ¿Pueden realizarse scripts con labwindows? Dicho de otro modo, me explico. Quiero controlar desde una interfaz de labwindows ciertos controles de otro programa. Para ello he utilizado el programa AutoHotkey para crear algunos scripts:


Run C:\Program Files\SPECS\SpecsLab2\bin\HSA3500Juggler.exe
Sleep 2000
ControlClick Connect,HSA3500 Juggler
Sleep 2000
ControlClick OK,Select
return

 

Así cuando mando ejecutar este programa desde mi interfaz me abre y conecta cierto programa. Pero el problema reside en que, en labwindows tengo unos controles númericos que me gustaría transmitir al otro programa. He probado mandando cierto número de un programa a otro usando los siguientes comandos:

 

ControlGetText TextEP,Edit,Juggler
ControlSetText Edit3,%TextEP%,HyperCam

 

Para que coga de un lado y lo copie en el otro. El problema es q una de las variables de cada comando es el texto de control que quiero que localice o su ClassNN que creo que es el ID del control. El problema es que la interfaz que creo con labwindows por mucho que ponga un nombre y referencia a cada contro, luego cuando se ejecuta el programa cada botón no tienen ningún ClassNN. He usado  el windows Spy para ver, y en casi todo los programas me indica el  ID de los controles menos en la interfaz creada con Labwindows.

 

Me gustaría saber, si se puede mediante configuración del programa decir que al crear el instalador también guarde y muestre el ClassNN, o si no se puede, si hay algún modo de hacer lo mismo que deseo hacer desde Labwindows mediante sus propios comandos.

 

Gracias

0 kudos
Mensaje 6 de 13
4.708 Vistas

Creo recordar que la interfaz del CVI no respecta los estándard de Windows sino en algunos elementos. Puedes reperir el handle de los thread con GetCVIWindowHandle u GetCVIWindowHandleForCurrThread, pero esto tan solo te sirve para registrar mensajes al programa y me parece que no se puede utilizar para individuar los controles en los paneles del programa.

 

Una opción que puedes usar es reperir los elementos dentro de tu programa y pasarlos como parametros al otro programa (u a un .bat que lanze el programa si esto no acepta parámetros) al correrlo con el Sytem () u el LaunchExecutable () dentro del CVI.

 

Otra opción puede ser una interfaz por ActiveX con tu programa pero solo si ésto ofrece tal alternativa y fornece la documentación apropiada.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 kudos
Mensaje 7 de 13
4.702 Vistas

Hola:

Primero unas disculpas, por que lo que voy a escribir aquí dista del tema del título, pero me he vuelto loco buscando como crear nuevo tema, y esta vez no lo he encontrado. También pido disculpas por que la pregunta que voy a realizar, puede parecer bastante sencilla, y debe de serlo, pero no funciona.

 

El caso es el siguiente:

 

Uso un while donde tengo dos condiciones. ¿La forma de hacer un OR con esas dos opciones es usando || esto no?

 Cuando uso la siguiente condición while(value!=0) funciona, cuando el valor es 0 sale.

 Si uso while(NC<NumColumn) Cuando el número de columnas es mayor a la variable NC sale también.

Pero si uso while((value!=0)||(NC<NumColumn)) para que en cualquiera de los dos casos salga, no lo hace, se queda dentro.

 

La pregunta es si estoy usando bien el símbolo de or o es que en labwindows aunque sea C es otro. O si la estructura del while no es correcta.

 

Gracias y perdón como ya he dicho.

0 kudos
Mensaje 8 de 13
4.643 Vistas

Cuando uso la siguiente condición while(value!=0) funciona, cuando el valor es 0 sale. Correcto

Si uso while(NC<NumColumn) Cuando el número de columnas es mayor a la variable NC sale también. No: sale si el número de columnas es mayor u igual a la variable

 

¿La forma de hacer un OR con esas dos opciones es usando || esto no?  Si

 

Pero si uso while((value!=0)||(NC<NumColumn)) para que en cualquiera de los dos casos salga, no lo hace, se queda dentro.

En realidad esto es correcto: con esta instrucción basta con que una de las condiciones sea averiguada para que el programa quede dentro del bucle while. Para salir del while es necesario que ambas condiciones no sean verdaderas (esto es: value debe ser >0 y contemporaneamente NC >= NumColumns)

Para salir del while para una condición sola es necesario ponerlas en AND.

 

En casos parecidos al tuyo, yo pongo un breakpoint en la instrucción while y cuando el programa se para voy a ver el valor de las variables y veo el resultado de las comparaciones: este tip puede serte de alguna utilidad en semplificar la tarea de ver los valores.

 

Mensaje editado por Roberto Bozzolo


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Mensaje 9 de 13
4.635 Vistas

Una vez más gracias por tu rápida y siempre satisfactoria respuesta. No lo he probado aun, pero con lo que me has dicho ya puedo resolver el problema.

He hecho click en lo de kudos y ha aparecido un 1. Espero no haber hecho malo, precisamente quería dar un aprobado a la respuesta no se si el kudos es justo lo contrario o no.

 

0 kudos
Mensaje 10 de 13
4.626 Vistas