- Métodos de almacenamiento de la información: texto y binario
- Escritura y lectura de archivos en modo simplificado
- Abrir y cerrar archivos
- Gestión de descriptores de archivo
- Seleccionar una codificación para el modo texto
- Escritura y lectura de arrays
- Escritura y lectura de estructuras (archivos binarios)
- Escritura y lectura de variables (archivos binarios)
- Escritura y lectura de variables (archivos de texto)
- Gestión de la posición en un expediente
- Obtención de las propiedades de un archivo
- Forzar escritura de caché en disco
- Eliminación de un archivo y comprobación de su existencia
- Copia y desplazamiento de archivos
- Búsqueda de archivos y carpetas
- Trabajar con carpetas
- Cuadro de diálogo de selección de archivos o carpetas
Cuadro de diálogo de selección de archivos o carpetas
En el grupo de funciones para trabajar con archivos y carpetas, hay una que permite solicitar interactivamente al usuario el nombre de un archivo o carpeta, así como un grupo de archivos para pasar esta información a un programa MQL. La llamada a la función FileSelectDialog hace que aparezca en el terminal una ventana estándar de Windows para seleccionar archivos y carpetas.
Dado que el diálogo interrumpe la ejecución del programa MQL hasta que se cierra, la llamada a la función sólo se permite en dos tipos de programas MQL que se ejecutan en hilos separados: EAs y scripts (véase Tipos de programas MQL). El uso de esta función está prohibido en indicadores y servicios: los primeros se ejecutan en el hilo de interfaz del terminal (y detenerlos congelaría la actualización de los gráficos de los instrumentos correspondientes), mientras que los segundos se ejecutan en segundo plano y no pueden acceder a la interfaz de usuario.
Todos los elementos del sistema de archivos con los que trabaja la función se encuentran dentro de la «sandbox», es decir, en el directorio de la copia actual del terminal o del agente de pruebas (si el programa se ejecuta en el probador), en la subcarpeta MQL5/Files.
Si la bandera FSD_COMMON_FOLDER está presente en el parámetro flags (ver más adelante), se utiliza una «sandbox» común de todos los terminales Users/<user>...MetaQuotes/Terminal/Common/Files.
El aspecto del cuadro de diálogo depende del sistema operativo Windows. A continuación se muestra una de las posibles opciones de interfaz.
Cuadro de diálogo de selección de archivos y carpetas de Windows
int FileSelectDialog(const string caption, const string initDir, const string filter,
uint flags, string &filenames[], const string defaultName)
La función muestra un cuadro de diálogo estándar de Windows para abrir o crear un archivo o seleccionar una carpeta. El título se especifica en el parámetro caption. Si el valor es NULL, se utiliza el título estándar: «Abrir» para leer o «Guardar como» para escribir un archivo, o «Seleccionar carpeta», en función de las banderas del parámetro flags.
El parámetro initDir permite establecer la carpeta inicial para la que se abrirá el cuadro de diálogo. Si se establece en NULL, se mostrará el contenido de la carpeta MQL5/Files. La misma carpeta se utiliza si se especifica una ruta inexistente en initDir.
Mediante el parámetro filter puede limitar el conjunto de extensiones de archivo que se mostrarán en el cuadro de diálogo. Los archivos de otros formatos quedarán ocultos. NULL significa sin restricciones.
El formato de la cadena filter es el siguiente:
"<description 1>|<extension 1>|<description 2>|<extension 2>..." |
Cualquier cadena se admite como description. Puede escribir cualquier filtro con los caracteres sustituidos '*' y '?' de los que hablamos en la sección Búsqueda de archivos y carpetas como extensions. El símbolo '|' es un delimitador.
Dado que la descripción y la extensión adyacentes forman un par relacionado lógicamente, el número total de elementos de la línea debe ser par, y el número de delimitadores, impar.
Cada combinación de descripción y extensión genera una selección independiente en la lista desplegable del cuadro de diálogo. La descripción se muestra al usuario y la extensión se utiliza para filtrar.
Por ejemplo, «Documentos de texto (*.txt)|*.txt|Todos los archivos (*.*)|*.*», mientras que la primera extensión «Documentos de texto (*.txt)|*.txt» se seleccionará como tipo de archivo por defecto.
En el parámetro flags puede indicar una máscara de bits que especifique los modos de funcionamiento mediante el operador '|'. Para ello se definen las siguientes constantes:
- FSD_WRITE_FILE - modo de escritura de archivos («Guardar como»). En ausencia de esta bandera, se utiliza por defecto el modo de lectura («Abrir»). Si esta bandera está presente, la entrada de un nuevo nombre arbitrario está siempre permitida, independientemente de la bandera FSD_FILE_MUST_EXIST.
- FSD_SELECT_FOLDER - modo de selección de carpetas (sólo una y sólo las existentes). Con esta bandera, todas las otras banderas excepto FSD_COMMON_FOLDER son ignoradas o causan un error. No se puede solicitar explícitamente la creación de una carpeta, pero es posible crear interactivamente una carpeta en el cuadro de diálogo y seleccionarla inmediatamente.
- FSD_ALLOW_MULTISELECT - permiso para seleccionar múltiples archivos en modo lectura. Esta bandera se ignora si se especifica FSD_WRITE_FILE o FSD_SELECT_FOLDER.
- FSD_FILE_MUST_EXIST - los archivos seleccionados deben existir. Si el usuario intenta especificar un nombre arbitrario, el cuadro de diálogo mostrará una advertencia y permanecerá abierto. Esta bandera se ignora si se especifica el modo FSD_WRITE_FILE.
- FSD_COMMON_FOLDER - el cuadro de diálogo se abre para una «sandbox» común de todos los terminales cliente.
La función rellenará un array de cadenas filenames con los nombres de los archivos o carpetas seleccionados. Si el array es dinámico, su tamaño cambia para ajustarse a la cantidad real de datos; en concreto, se expande o trunca hasta 0 si no se ha seleccionado nada. Si el array es fijo, debe ser lo suficientemente grande como para aceptar los datos esperados. De lo contrario, se producirá un error 4007 (ARRAY_RESIZE_ERROR).
El parámetro defaultName especifica el nombre de archivo/carpeta por defecto, que será sustituido en el campo de entrada correspondiente inmediatamente después de abrir el cuadro de diálogo. Si el parámetro es NULL, el campo estará inicialmente vacío.
Si se establece el parámetro defaultName, entonces durante las pruebas no visuales del programa MQL, la llamada FileSelectDialog devolverá 1 y el propio valor defaultName se copiará en el array filenames.
La función devuelve el número de elementos seleccionados (0 si el usuario no ha seleccionado nada), o -1 si se ha producido un error.
Vea ejemplos de cómo funciona la función en el script FileSelect.mq5. En la función OnStart, llamaremos secuencialmente a FileSelectDialog con diferentes configuraciones. Mientras el usuario seleccione algo (no haga clic en el botón «Cancelar» del cuadro de diálogo), la prueba continúa hasta el último paso (incluso si la función se ejecuta con un código de error).
void OnStart()
|
Primero, pediremos al usuario un archivo de la carpeta «MQL5Book». Puede seleccionar un archivo existente o introducir un nuevo nombre (porque no hay ninguna bandera FSD_FILE_MUST_EXIST).
Print("Open a file");
|
Suponiendo que la carpeta contenga al menos 5 archivos de la entrega del libro, aquí se selecciona uno de ellos.
Entonces haremos una petición similar en modo «para escribir» (con la bandera FSD_WRITE_FILE).
Print("Save as a file");
|
Aquí el usuario también podrá seleccionar tanto un archivo existente como introducir un nuevo nombre. El programador debe comprobar si el usuario va a sobrescribir un archivo existente (el cuadro de diálogo no genera advertencias).
Ahora vamos a comprobar la selección de múltiples archivos (FSD_ALLOW_MULTISELECT) en un array dinámico.
if(PRTF(FileSelectDialog(NULL, "MQL5book", NULL,
|
La presencia de la bandera FSD_FILE_MUST_EXIST significa que el cuadro de diálogo mostrará una advertencia y permanecerá abierto si intenta introducir un nuevo nombre.
Si intentamos seleccionar más de un archivo en un array de tamaño fijo de forma similar, obtendremos un error.
Print("Open multiple files (fixed, choose more than 1 file for error)");
|
Por último, vamos a revisar las operaciones con carpetas (FSD_SELECT_FOLDER).
Print("Select a folder");
|
En este caso, se especifica la subcarpeta «nonexistent» como ruta de inicio, por lo que el cuadro de diálogo se abrirá en la raíz de la «sandbox» MQL5/Files. Allí elegimos «MQL5book».
Si realizamos una combinación no válida de banderas, obtendremos otro error.
if(PRTF(FileSelectDialog(NULL, "MQL5book", NULL,
|
Debido a un error, la función no modificó el array pasado, y el antiguo elemento «MQL5Book» permaneció en él.
En esta prueba comprobamos deliberadamente los resultados sólo para 0 con el fin de demostrar todas las opciones, independientemente de la presencia de errores. En un programa real, compruebe el resultado de la función teniendo en cuenta los errores, es decir, con condiciones para tres resultados: elección realizada (>0), elección no realizada (==0) y error (<0).