Una pequeña biblioteca C que invoca el archivo nativo, se abre el archivo, la carpeta seleccione y los diálogo Guardar archivos. Escriba el código de diálogo una vez y haga que aparezca diálogo nativos en todas las plataformas compatibles. Evite vincular grandes dependencias como WXWidgets y Qt.
Esta biblioteca se basa en el cuadro de diálogo de archivos nativos de Michael Labbe (MLABBE/NativeFileDialog).
Características:
C/C++ Source files (*.c;*.cpp) Ej (*.c;*.cpp)Untitled.c )wchar_t ) Soporte en WindowsIFileDialog de Vista en Windowsunique_ptr y parámetros opcionales, para aquellos que usan esta biblioteca de C ++Comparación con el diálogo de archivos nativos originales:
La característica de nombres amigables es la razón principal para romper la compatibilidad de la API con la biblioteca de Michael Labbe (y por lo tanto, esta biblioteca probablemente nunca se fusionará con ella). También hay una serie de ajustes que causan diferencias observables en esta biblioteca.
Características agregadas en el cuadro de diálogo de archivo nativo extendido:
wchar_t ) Soporte en Windowsunique_ptr liberador automático y parámetros opcionalesTambién hay una refractar por código significativa, especialmente para la implementación de Windows.
El Wiki realiza un seguimiento de los enlaces de lenguaje conocidos y proyectos populares conocidos que dependen de esta biblioteca.
#include <nfd.h>
#include <stdio.h>
#include <stdlib.h>
int main ( void )
{
NFD_Init ();
nfdu8char_t * outPath ;
nfdu8filteritem_t filters [ 2 ] = { { "Source code" , "c,cpp,cc" }, { "Headers" , "h,hpp" } };
nfdopendialogu8args_t args = { 0 };
args . filterList = filters ;
args . filterCount = 2 ;
nfdresult_t result = NFD_OpenDialogU8_With ( & outPath , & args );
if ( result == NFD_OKAY )
{
puts ( "Success!" );
puts ( outPath );
NFD_FreePathU8 ( outPath );
}
else if ( result == NFD_CANCEL )
{
puts ( "User pressed cancel." );
}
else
{
printf ( "Error: %sn" , NFD_GetError ());
}
NFD_Quit ();
return 0 ;
} El U8 / u8 en NFDE se refiere a la API para UTF-8 caracteres ( char ), que la mayoría de los consumidores probablemente desean. También está disponible una versión N / n , que utiliza el tipo de caracteres nativo ( wchar_t en Windows y char en otras plataformas).
Para obtener la lista completa de argumentos que puede establecer en la estructura args , consulte la sección "Todas las opciones" a continuación.
Si está utilizando un marco de abstracción de plataforma como SDL o GLFW, consulte también la sección "Uso con un marco de abstracción de plataforma" a continuación.






Si su proyecto usa CMake, simplemente agregue las siguientes líneas a su cmakelists.txt:
add_subdirectory(path/to/nativefiledialog-extended)
target_link_libraries(MyProgram PRIVATE nfd)
Asegúrese de tener también las dependencias necesarias.
Cuando se incluye como subproyecto, los programas de muestra no se crean y el objetivo de instalación está deshabilitado de forma predeterminada. Agregue -DNFD_BUILD_TESTS=ON para crear programas de muestra y -DNFD_INSTALL=ON para habilitar el objetivo de instalación.
Si desea construir la biblioteca estática independiente, ejecute los siguientes comandos (a partir del directorio raíz del proyecto):
Para GCC y Clang:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
Para MSVC:
mkdir build
cd build
cmake ..
cmake --build . --config Release
Los comandos anteriores realizarán un directorio build y construirán el proyecto (en modo de lanzamiento) allí. Si está desarrollando NFDE, es posible que desee hacer -DCMAKE_BUILD_TYPE=Debug / --config Debug para construir una versión de depuración de la biblioteca.
Al construir como una biblioteca independiente, se construyen programas de muestra y el objetivo de instalación está habilitado de forma predeterminada. Agregue -DNFD_BUILD_TESTS=OFF para deshabilitar los programas de muestra de construcción y -DNFD_INSTALL=OFF para deshabilitar el objetivo de instalación.
En Linux, si desea usar el portal de escritorio Flatpak en lugar de GTK, agregue -DNFD_PORTAL=ON . (De lo contrario, se utilizará GTK). Consulte la sección "Uso" a continuación para obtener más información.
Consulte el archivo de compilación de CI para algunos comandos de compilación de ejemplo.
Las versiones recientes de Visual Studio tienen soporte de CMake integrado en el IDE. Debería poder "abrir carpeta" en el directorio de Root Project, y Visual Studio reconocerá y configurará el proyecto de manera adecuada. A partir de ahí, podrá establecer configuraciones para la liberación de depuración vs, y para x86 vs x64. Para obtener más información, consulte la página de Microsoft Docs. Esto se ha probado para trabajar en Visual Studio 2019, y probablemente también funcione en Visual Studio 2017.
src/include a su ruta de búsqueda de incluido.nfd.lib o nfd_d.lib a la lista de bibliotecas estáticas para vincular (para la liberación o depuración, respectivamente).build/<debug|release>/<arch> a la ruta de búsqueda de la biblioteca. Asegúrese de que libgtk-3-dev esté instalado en su sistema.
Asegúrese de que libdbus-1-dev esté instalado en su sistema.
En MacOS, agregue AppKit y UniformTypeIdentifiers a la lista de marcos.
En Windows (tanto MSVC como MingW), asegúrese de construir contra ole32.lib , uuid.lib y shell32.lib .
Para abrir un diálogo, establece opciones en una estructura y luego pasa esa estructura a una función NFDE, por ejemplo:
nfdopendialogu8args_t args = { 0 };
args . filterList = filters ;
args . filterCount = 2 ;
nfdresult_t result = NFD_OpenDialogU8_With ( & outPath , & args ); Todas las opciones son opcionales y pueden establecerse individualmente (cero inicialización establece todas las opciones a valores predeterminados razonables), excepto filterList y filterCount que debe estar establecido o ambas nocitadas.
Las versiones futuras de NFDE pueden agregar opciones adicionales al final de la estructura de argumentos sin aumentar el número de versión principal, por lo que para garantizar la compatibilidad de la API hacia atrás, no debe asumir que la estructura tiene una longitud o número específico de campos. Puede suponer que la initalización cero de la estructura continuará estableciendo todas las opciones en valores predeterminados razonables, por lo que es aceptable asignar {0} a la estructura. Para aquellos que construyen bibliotecas compartidas de NFDE, la compatibilidad ABI hacia atrás está garantizada por un índice de versión interna ( NFD_INTERFACE_VERSION ), que se espera que sea transparente para los consumidores.
Opendialog / opendialogmultiple :
typedef struct {
const nfdu8filteritem_t * filterList ;
nfdfiltersize_t filterCount ;
const nfdu8char_t * defaultPath ;
nfdwindowhandle_t parentWindow ;
} nfdopendialogu8args_t ;Savedialog :
typedef struct {
const nfdu8filteritem_t * filterList ;
nfdfiltersize_t filterCount ;
const nfdu8char_t * defaultPath ;
const nfdu8char_t * defaultName ;
nfdwindowhandle_t parentWindow ;
} nfdsavedialogu8args_t ;Pickfolder / Pickfoldmultiple :
typedef struct {
const nfdu8char_t * defaultPath ;
nfdwindowhandle_t parentWindow ;
} nfdpickfolderu8args_t ;filterList y filterCount : configure estos para personalizar el filtro de archivo (aparece como un menú desplegable en Windows y Linux, pero simplemente oculta archivos en macOS). Establezca filterList en un puntero al inicio de la matriz de elementos de filtro y filterCount el número de elementos de filtro en esa matriz. Consulte la sección "Filtro de filtro de archivo" a continuación para más detalles.defaultPath : configure esto en la carpeta predeterminada a la que debe abrir el diálogo (en Windows, si hay una carpeta utilizada recientemente, se abre a esa carpeta en lugar de la carpeta que pasa, a menos que la opción NFD_OVERRIDE_RECENT_WITH_DEFAULT Build esté configurada en ON).defaultName : (solo para Savedialog) Establezca esto en el nombre del archivo que debe estar prefirido en el cuadro de diálogo.parentWindow : configure esto en el mango de la ventana nativa del padre de este diálogo. Consulte la sección "Uso con un marco de abstracción de plataforma" para más detalles. También es posible pasar un mango incluso si no usa un marco de abstracción de plataforma. Consulte el directorio test por ejemplo (ambos C y C ++).
Si enciende la opción de construir el directorio test ( -DNFD_BUILD_TESTS=ON ), entonces build/bin contendrá los programas de prueba compilados.
También hay un ejemplo SDL2, que debe habilitarse por separado con -DNFD_BUILD_SDL2_TESTS=ON . Requiere que SDL2 se instale en su máquina.
Los ejemplos compilados (incluido el ejemplo SDL2) también se cargan como artefactos para las acciones de GitHub, y se pueden descargar desde allí.
Los archivos se pueden filtrar mediante grupos de extensión de archivo:
nfdu8filteritem_t filters [ 2 ] = { { "Source code" , "c,cpp,cc" }, { "Headers" , "h,hpp" } };Un filtro de archivo es un par de cadenas que comprenden el nombre amigable y la especificación (las extensiones de múltiples archivos están separadas por comas).
Se puede aprobar una lista de filtros de archivos como argumento al invocar la biblioteca.
Siempre se agrega un filtro comodín a cada diálogo.
Nota: En MacOS, los diálogos de archivo no tienen nombres amigables y no hay forma de cambiar entre filtros, por lo que las especificaciones del filtro se combinan (por ejemplo, "C, CPP, CC, H, HPP"). La especificación del filtro tampoco se muestra explícitamente al usuario. Este es el comportamiento habitual de MacOS y los usuarios lo esperan.
Nota 2: debe asegurarse de que la cadena de especificación no esté vacía y que cada extensión de archivo tenga al menos un carácter. De lo contrario, pueden surgir cosas malas (es decir, comportamiento indefinido).
Nota 3: En Linux, la extensión del archivo se agrega (si falta) cuando el usuario presiona hacia abajo en el botón "Guardar". La extensión del archivo adjunto permanecerá visible para el usuario, incluso si se muestra un indicador de sobrescrito y el usuario presiona "Cancelar".
Nota 4: En Windows, el parámetro de carpeta predeterminado solo se usa si no hay una carpeta recientemente utilizada disponible, a menos que la opción NFD_OVERRIDE_RECENT_WITH_DEFAULT Build esté configurada en ON. De lo contrario, la carpeta predeterminada será la carpeta que se usó por última vez. Internamente, la implementación de Windows llama a ifiledialog :: setDefaultFolder (ishellitem). Este es el comportamiento habitual de Windows y los usuarios lo esperan.
Un cuadro de diálogo Abierto de archivo que admite múltiples selecciones produce un ratero, que es una abstracción delgada sobre la colección específica de la plataforma. Hay dos formas de iterar sobre un camino:
Este método tiene acceso similar a la matriz en la ruta, y es el más fácil de usar. Sin embargo, en ciertas plataformas (Linux y posiblemente Windows), se necesita O (n 2 ) en total para iterar todo el camino, porque la implementación específica de la plataforma subyacente utiliza una lista vinculada.
Ver test_opendialogMultiple.c.
Este método utiliza un objeto enumerador para iterar las rutas en la ruta. Se garantiza que tomará el tiempo en total para iterar todo el camino.
Ver test_opendialogMultiple_enum.c.
Esta API es experimental y está sujeta a cambios.
Puede definir las siguientes macros antes de incluir nfd.h / nfd.hpp :
NFD_NATIVE : Defina esto antes NFD_OpenDialogU8 incluir nfd.h para hacer alias de funciones no sufijo y typedefs (p NFD_OpenDialog Ej NFD_OpenDialogN Esta macro no afecta el envoltorio C ++ nfd.hpp .NFD_THROWS_EXCEPTIONS : (solo C ++) Defina esto antes de incluir nfd.hpp para hacer NFD::Guard Construction Throw std::runtime_error si NFD_Init falla. De lo contrario, no hay forma de detectar el fracaso en la construcción de NFD::Guard . Macros que podrían definirse por nfd.h :
NFD_DIFFERENT_NATIVE_FUNCTIONS : definido si las versiones nativas y UTF-8 de las funciones son diferentes (es decir, compilación para Windows); no definido de otra manera. Si no se define NFD_DIFFERENT_NATIVE_FUNCTIONS , entonces las versiones UTF-8 de las funciones son alias para las versiones nativas. Esto podría ser útil si está escribiendo una función que desea proporcionar sobrecargas dependiendo de si las funciones nativas y las funciones UTF-8 son las mismas. (Nativo es UTF-16 ( wchar_t ) para Windows y UTF-8 ( char ) para Mac/Linux). Se sabe que NFDE trabaja con SDL2 y GLFW, y también debe funcionar con otra plataforma Abstraction Framworks. Esta sección explica cómo usar NFDE correctamente con dichos marcos.
El argumento parentWindow le permite al usuario darle al diálogo a un padre.
Si usa SDL2, incluya <nfd_sdl2.h> y llame a la siguiente función para configurar el mango de la ventana principal:
NFD_GetNativeWindowFromSDLWindow ( sdlWindow /* SDL_Window* */ , & args . parentWindow ); Si usa GLFW3, defina los macros GLFW_EXPOSE_NATIVE_* apropiados descritos en la página de acceso nativo de GLFW e incluya <nfd_glfw3.h> y llame a la siguiente función para configurar el mango de la ventana principal:
NFD_GetNativeWindowFromGLFWWindow ( glfwWindow /* GLFWwindow* */ , & args . parentWindow ); Si está utilizando otro marco de abstracción de plataforma, o no utilizando dicho marco, puede establecer args.parentWindow manualmente.
Se admiten Win32 (Windows), Cocoa (MacOS) y X11 (Linux) Windows. Pasar una ventana de Wayland (Linux) actualmente no hace nada (es decir, el diálogo actúa como si no tuviera un padre), pero es probable que el soporte se agregue en el futuro.
Para hacer una ventana (en este caso, el cuadro de diálogo del archivo) permanecer por encima de otra ventana, debemos declarar la ventana inferior como padre de la ventana superior. Esto evita que la ventana de diálogo desaparezca detrás de la ventana principal si el usuario hace clic en la ventana principal mientras el diálogo está abierto. Mantener el diálogo sobre la ventana que lo invocó es el comportamiento esperado en todos los sistemas operativos compatibles, por lo que se recomienda pasar el mango de la ventana principal si es posible.
Debe inicializar NFDE después de inicializar el marco, y probablemente debería desinitializar NFDE antes de desinicializar el marco. Esto se debe a que algunos marcos esperan ser inicializados en una "pizarra limpia", y pueden configurar el sistema de manera diferente de NFDE. NFD_Init generalmente es muy cuidadoso de no interrumpir la configuración existente a menos que sea necesario, y NFD_Quit restaura la configuración de nuevo exactamente a lo que era antes de la inicialización.
Un ejemplo con SDL2:
// Initialize SDL2 first
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0) {
// display some error here
}
// Then initialize NFDe
if (NFD_Init() != NFD_OKAY) {
// display some error here
}
/*
Your main program goes here
*/
NFD_Quit(); // deinitialize NFDe first
SDL_Quit(); // Then deinitialize SDL2
En Linux, puede usar la implementación del portal en lugar de GTK, que abrirá el selector de archivos "nativo" seleccionado por el sistema operativo o personalizado por el usuario. El usuario debe tener xdg-desktop-portal y un backend adecuado instalado (esto viene preinstalado con las distribuciones de escritorio más comunes), de lo contrario se devolverá NFD_ERROR .
Para usar la implementación del portal, agregue -DNFD_PORTAL=ON el comando de compilación.
*Nota: El selector de carpetas solo se admite en org.freedesktop.portal.filechooser Versión de la interfaz> = 3, que corresponde a la versión XDG-desktop-portal> = 1.7.1. NFD_PickFolder() consultará la versión de interfaz en tiempo de ejecución y devolverá NFD_ERROR si la versión es demasiado baja.
A diferencia de Windows y MacOS, Linux no tiene un selector de archivos horneado en el sistema operativo. Aplicaciones de Linux que desean un selector de archivos generalmente enlazan con una biblioteca que proporciona una (como GTK, como en la captura de pantalla de Linux anterior). Esta es una solución principalmente aceptable que usan muchas aplicaciones, pero puede hacer que el selector de archivos parezca extranjero en distribuciones que no son GTK.
Flatpak se introdujo en 2015, y con él vino una interfaz estandarizada para abrir un selector de archivos. Las aplicaciones que usan esta interfaz no necesitaban venir con un selector de archivos, y podrían usar la proporcionada por FlatPak. Esta interfaz se conoció como el portal de escritorio, y su uso se expandió a aplicaciones que no son de Flatpak. Ahora, la mayoría de las principales distribuciones de escritorio Linux vienen con el portal de escritorio instalado, con sellos de archivos que se ajustan al tema de la distribución. Los usuarios también pueden instalar un backend de portal diferente si lo desea. Actualmente hay tres backends conocidos con soporte de selección de archivos: GTK, KDE y LXQT; Los backends de GNOME y XAPP dependen del GTK para esta funcionalidad. El backend de XAPP ha sido diseñado para canela, compañero y XFCE. Otros entornos de escritorio no parecen tener actualmente un backend de portal.
Info.plist según la documentación de Apple. (Es posible obligar a NFDE a usar los TIPS permitidos al agregar -DNFD_USE_ALLOWEDCONTENTTYPES_IF_AVAILABLE=OFF en su comando CMake Build, pero esto no se recomienda. Si necesita admitir versiones de macOS más antiguos, debe establecer el objetivo de despliegue correcto en su lugar.GetOpenFileName . (No hay planes para apoyar esto; de todos modos no debería usar Windows XP).Utilice el rastreador de problemas de GitHub para informar errores o para contribuir a este repositorio. No dude en enviar informes de errores de cualquier tipo.
Bernard Teo (ME) y otros contribuyentes para todo lo que no era del diálogo de archivos nativos de Michael Labbe.
Michael Labbe por su increíble biblioteca de diálogo de archivos nativos, y los otros contribuyentes a esa biblioteca.
Gran parte de este ReadMe también se ha copiado del ReadMe del repositorio de diálogo de archivos nativos originales.
Todo en este repositorio se distribuye bajo la licencia ZLIB, al igual que la biblioteca original de diálogo de archivos nativos.
No proporciono ningún apoyo pagado. Michael Labbe parece proporcionar apoyo pagado para su biblioteca al momento de escribir.