기본 파일 열기, 폴더 선택 및 파일 저장 대화 상자를 포장적으로 호출하는 작은 C 라이브러리. 대화 코드를 한 번 작성하고 모든 지원되는 플랫폼에서 기본 대화 상자를 나타냅니다. WXWIDGET 및 QT와 같은 큰 종속성을 연결하지 마십시오.
이 라이브러리는 Michael Labbe의 기본 파일 대화 상자 (MLABBE/NATIVELFILEDIALOG)를 기반으로합니다.
특징:
C/C++ Source files (*.c;*.cpp) 대신 (*.c;*.cpp) )를 지원하는 플랫폼에서Untitled.c )wchar_t ) 지원IFileDialog 에 대한 지원unique_ptr 자동 무료원본 기본 파일 대화 상자와 비교 :
친절한 이름 기능은 Michael Labbe의 라이브러리와 API 호환성을 깨는 주된 이유입니다 (따라서이 라이브러리는 절대로 병합되지 않을 것입니다). 이 라이브러리에서 관찰 가능한 차이를 유발하는 많은 조정이 있습니다.
기본 파일에 추가 된 기능이 확장되었습니다.
wchar_t ) 지원unique_ptr 자동 무료특히 Windows 구현에는 중요한 코드 굴절도 있습니다.
Wiki는 알려진 언어 바인딩 과이 라이브러리에 의존하는 알려진 인기 프로젝트를 추적합니다.
#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 ;
} NFDE의 U8 / u8 대부분의 소비자가 원하는 UTF-8 문자 ( char )의 API를 나타냅니다. N / n 버전도 사용할 수 있으며 기본 문자 유형 (Windows에서는 wchar_t 및 다른 플랫폼의 char )을 사용합니다.
args Struct에서 설정할 수있는 전체 인수 목록은 아래의 "모든 옵션"섹션을 참조하십시오.
SDL 또는 GLFW와 같은 플랫폼 추상화 프레임 워크를 사용하는 경우 아래의 "플랫폼 추상화 프레임 워크 사용"섹션도 참조하십시오.






프로젝트가 cmake를 사용하는 경우 cmakelists.txt에 다음 줄을 추가하십시오.
add_subdirectory(path/to/nativefiledialog-extended)
target_link_libraries(MyProgram PRIVATE nfd)
필요한 종속성도 있는지 확인하십시오.
하위 프로젝트로 포함되면 샘플 프로그램이 구축되지 않고 설치 대상이 기본적으로 비활성화됩니다. 설치 대상을 활성화하려면 -DNFD_BUILD_TESTS=ON 추가하고 -DNFD_INSTALL=ON .
독립형 정적 라이브러리를 구축하려면 다음 명령을 실행하십시오 (프로젝트 루트 디렉토리에서 시작) :
GCC 및 Clang의 경우 :
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
MSVC의 경우 :
mkdir build
cd build
cmake ..
cmake --build . --config Release
위의 명령은 build 디렉토리를 만들고 프로젝트 (릴리스 모드)를 빌드합니다. nfde를 개발하는 경우 -DCMAKE_BUILD_TYPE=Debug / --config Debug 대신 도서관의 디버그 버전을 빌드 할 수 있습니다.
독립형 라이브러리로 구축 할 때 샘플 프로그램이 구축되고 설치 대상이 기본적으로 활성화됩니다. 추가 -DNFD_BUILD_TESTS=OFF 샘플 프로그램을 비활성화하려면 꺼짐 샘플 프로그램 및 -DNFD_INSTALL=OFF 비활성화하여 설치 대상을 비활성화하십시오.
Linux에서 GTK 대신 FlatPak 데스크톱 포털을 사용하려면 -DNFD_PORTAL=ON 추가하십시오. (그렇지 않으면 GTK가 사용됩니다.) 자세한 내용은 아래의 "사용"섹션을 참조하십시오.
빌드 명령의 예제는 CI 빌드 파일을 참조하십시오.
최근 버전의 Visual Studio에는 IDE에 CMAKE 지원이 내장되어 있습니다. Project Root 디렉토리에서 "폴더 열기"를 할 수 있어야하며 Visual Studio는 프로젝트를 적절하게 인식하고 구성합니다. 거기에서 디버그 대 릴리스 및 x86 vs x64에 대한 구성을 설정할 수 있습니다. 자세한 내용은 Microsoft Docs 페이지를 참조하십시오. 이것은 Visual Studio 2019에서 작업하도록 테스트되었으며 아마도 Visual Studio 2017에서도 작동합니다.
src/include 추가하십시오.nfd.lib 또는 nfd_d.lib 추가하여 링크 (각각 릴리스 또는 디버그)를 추가하십시오.build/<debug|release>/<arch> 추가하십시오. libgtk-3-dev 시스템에 설치되어 있는지 확인하십시오.
시스템에 libdbus-1-dev 설치되어 있는지 확인하십시오.
MACOS에서는 프레임 워크 목록에 AppKit 및 UniformTypeIdentifiers 추가하십시오.
Windows (MSVC 및 MINGW)에서 ole32.lib , uuid.lib 및 shell32.lib 에 대해 구축하고 있는지 확인하십시오.
대화 상자를 열려면 구조물에서 옵션을 설정 한 다음 해당 구조물을 NFDE 기능으로 전달합니다.
nfdopendialogu8args_t args = { 0 };
args . filterList = filters ;
args . filterCount = 2 ;
nfdresult_t result = NFD_OpenDialogU8_With ( & outPath , & args ); 모든 옵션은 선택 사항이며 filterList 및 FilterCount를 제외하고는 설정 또는 둘 다 UNSET가 남아 있어야하는 FilterList 및 filterCount 제외하고는 개별적으로 설정 될 수 있습니다 (제로 초기화는 모든 옵션을 합리적인 기본값으로 설정합니다).
NFDE의 향후 버전은 주요 버전 번호를 충돌시키지 않고 인수 구조의 끝에 추가 옵션을 추가 할 수 있으므로 뒤로 API 호환성을 보장하기 위해 구조물에 특정 길이 또는 필드 수가 있다고 가정해서는 안됩니다. 구조물의 초기화가 모든 옵션을 합리적인 기본값으로 계속 설정할 것이라고 가정 할 수 있으므로 {0} 구조물에 할당하는 것이 허용됩니다. NFDE의 공유 라이브러리를 구축하는 경우, Backward ABI 호환성은 내부 버전 인덱스 ( NFD_INTERFACE_VERSION )에 의해 보장되며, 이는 소비자에게 투명 할 것으로 예상됩니다.
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 / PickfolderMultiple :
typedef struct {
const nfdu8char_t * defaultPath ;
nfdwindowhandle_t parentWindow ;
} nfdpickfolderu8args_t ;filterList 및 filterCount : 파일 필터를 사용자 정의하도록 설정하십시오 (Windows 및 Linux의 드롭 다운 메뉴로 나타나지만 MacOS의 파일을 숨 깁니다). filterList 필터 항목 배열의 시작 부분에 포인터로 설정하고 해당 배열의 필터 항목 수에 filterCount 하십시오. 자세한 내용은 아래의 "파일 필터 구문"섹션을 참조하십시오.defaultPath : 대화 상자가 열리는 기본 폴더로 설정하십시오 (최근에 사용 된 폴더가있는 경우 NFD_OVERRIDE_RECENT_WITH_DEFAULT 옵션이 켜지지 않는 한 전달한 폴더 대신 해당 폴더가 열립니다).defaultName : (savedialog 만) 대화 상자에서 사전 채워야하는 파일 이름으로 설정하십시오.parentWindow :이 대화 상자의 부모의 기본 창 핸들로 설정하십시오. 자세한 내용은 "플랫폼 추상화 프레임 워크 사용"섹션을 참조하십시오. 플랫폼 추상화 프레임 워크를 사용하지 않더라도 핸들을 전달할 수도 있습니다. 예를 들어 코드 (C 및 C ++)의 예를 들어 test 디렉토리를 참조하십시오.
test 디렉토리 ( -DNFD_BUILD_TESTS=ON )를 빌드하는 옵션을 켜면 build/bin 에는 컴파일 된 테스트 프로그램이 포함됩니다.
SDL2 예제도 있습니다.이 예제는 -DNFD_BUILD_SDL2_TESTS=ON 으로 별도로 활성화해야합니다. 시스템에 SDL2를 설치해야합니다.
컴파일 된 예제 (SDL2 예 포함)도 GitHub 액션에 대한 인공물로 업로드되며 거기에서 다운로드 할 수 있습니다.
파일 확장 그룹별로 파일을 필터링 할 수 있습니다.
nfdu8filteritem_t filters [ 2 ] = { { "Source code" , "c,cpp,cc" }, { "Headers" , "h,hpp" } };파일 필터는 친숙한 이름과 사양을 포함하는 한 쌍의 문자열입니다 (여러 파일 확장자는 쉼표로 구분됩니다).
라이브러리를 호출 할 때 파일 필터 목록을 인수로 전달할 수 있습니다.
와일드 카드 필터는 항상 모든 대화 상자에 추가됩니다.
참고 : MACOS에서 파일 대화에는 친숙한 이름이 없으며 필터간에 전환 할 방법이 없으므로 필터 사양이 결합됩니다 (예 : "C, CPP, CC, H, HPP"). 필터 사양은 또한 사용자에게 명시 적으로 표시되지 않습니다. 이것은 일반적인 MACOS 동작이며 사용자는이를 기대합니다.
참고 2 : 사양 문자열이 비어 있고 모든 파일 확장자에 하나 이상의 문자가 있는지 확인해야합니다. 그렇지 않으면 나쁜 일이 발생할 수 있습니다 (즉, 정의되지 않은 행동).
참고 3 : Linux에서 사용자가 "저장"버튼을 누르면 파일 확장자가 추가됩니다 (누락 된 경우). 추가 된 파일 확장자는 덮어 쓰기 프롬프트가 표시되고 사용자가 "취소"를 누르더라도 사용자에게 보이는 상태로 유지됩니다.
참고 4 : Windows에서 NFD_OVERRIDE_RECENT_WITH_DEFAULT 옵션이 ON으로 설정되지 않는 한 최근에 사용 된 폴더가없는 경우에만 기본 폴더 매개 변수가 사용됩니다. 그렇지 않으면 기본 폴더는 마지막으로 사용 된 폴더입니다. 내부적으로 Windows 구현은 ifiledialog :: setDefaultfolder (ishellitem)를 호출합니다. 이것은 일반적인 Windows 동작이며 사용자는이를 기대합니다.
다중 선택을 지원하는 파일 열기 대화 상자는 PathSet을 생성하며, 이는 플랫폼 별 컬렉션보다 얇은 추상화입니다. PathSet을 반복하는 두 가지 방법이 있습니다.
이 방법은 PathSet에서 배열과 같은 액세스를 수행하며 사용하기가 가장 쉽습니다. 그러나 특정 플랫폼 (Linux 및 Windows)에서는 기본 플랫폼 별 구현이 링크 된 목록을 사용하기 때문에 전체 경로 세트를 반복하는 데 O (N 2 )가 총 시간이 걸립니다.
test_opendialogmultiple.c를 참조하십시오.
이 방법은 열거 자체를 사용하여 PathSet의 경로를 반복합니다. 전체 경로 세트를 반복하기 위해 O (N) 시간이 총 시간을 보장합니다.
test_opendialogmultiple_enum.c를 참조하십시오.
이 API는 실험적이며 변경 될 수 있습니다.
nfd.h / nfd.hpp 포함시키기 전에 다음 매크로를 정의 할 수 있습니다.
NFD_NATIVE : UTF-8 기능 (예 : NFD_OpenDialogU8 ) 대신 기본 함수 (예 : NFD_OpenDialog )에 대한 비 초석 기능 이름 및 typedefs (예 : NFD_OpenDialogN ) 별칭을 만들기 위해 nfd.h 포함시키기 전에이 내용을 정의하십시오. 이 매크로는 C ++ 래퍼 nfd.hpp 영향을 미치지 않습니다.NFD_THROWS_EXCEPTIONS : (C ++ 만 해당) NFD::Guard 구성을 위해 nfd.hpp NFD_Init 하기 전에 이것을 정의 std::runtime_error . 그렇지 않으면 NFD::Guard 구성에서 실패를 감지 할 방법이 없습니다. nfd.h 에 의해 정의 될 수있는 매크로 :
NFD_DIFFERENT_NATIVE_FUNCTIONS : 기능의 기본 및 UTF-8 버전이 다른 경우 정의 (예 : Windows의 컴파일); 그렇지 않으면 정의되지 않았습니다. NFD_DIFFERENT_NATIVE_FUNCTIONS 정의되지 않으면 UTF-8 버전의 기능은 기본 버전의 별칭입니다. 기본 함수 및 UTF-8 함수가 동일한지 여부에 따라 오버로드를 제공하려는 함수를 작성하는 경우 유용 할 수 있습니다. (원본은 Windows의 경우 UTF-16 ( wchar_t ) 및 Mac/Linux의 경우 UTF-8 ( char )입니다.) NFDE는 SDL2 및 GLFW와 함께 작동하는 것으로 알려져 있으며 다른 플랫폼 추상화 Framworks 와도 협력해야합니다. 이 섹션에서는 이러한 프레임 워크와 함께 NFDE를 올바르게 사용하는 방법을 설명합니다.
parentWindow 인수를 통해 사용자는 대화 상자에게 부모에게 제공 할 수 있습니다.
sdl2를 사용하는 경우 <nfd_sdl2.h> 포함시키고 다음 함수를 호출하여 부모 창 핸들을 설정하십시오.
NFD_GetNativeWindowFromSDLWindow ( sdlWindow /* SDL_Window* */ , & args . parentWindow ); GLFW3를 사용하는 경우 GLFW 기본 액세스 페이지에 설명 된 적절한 GLFW_EXPOSE_NATIVE_* 매크로를 정의 한 다음 <nfd_glfw3.h> 를 포함시키고 다음 함수를 호출하여 부모 창 핸들을 설정하십시오.
NFD_GetNativeWindowFromGLFWWindow ( glfwWindow /* GLFWwindow* */ , & args . parentWindow ); 다른 플랫폼 추상화 프레임 워크를 사용하거나 그러한 프레임 워크를 사용하지 않는 경우 args.parentWindow 수동으로 설정할 수 있습니다.
Win32 (Windows), Cocoa (MacOS) 및 X11 (Linux) Windows가 지원됩니다. Wayland (Linux) 창을 통과하는 것은 현재 아무것도하지 않습니다 (즉, 대화 상자는 부모가없는 것처럼 행동합니다). 그러나 향후 지원이 추가 될 것입니다.
창을 만들려면 (이 경우 파일 대화 상자) 다른 창 위에 머무르려면 하단 창을 상단 창의 부모로 선언해야합니다. 대화 상자가 열려있는 동안 사용자가 상위 창을 클릭하면 대화 창이 상위 창 뒤에 사라지는 것을 막습니다. 창 위에 대화 상자를 유지하는 모든 지원되는 운영 체제에서 예상되는 동작이므로 가능한 경우 상위 창 손잡이를 통과하는 것이 좋습니다.
프레임 워크를 초기화 한 후 NFDE를 초기화해야하며 프레임 워크를 비인화하기 전에 NFDE를 탈피해야 할 것입니다. 이는 일부 프레임 워크가 "깨끗한 슬레이트"에서 초기화 될 것으로 예상되며 NFDE와 다른 방식으로 시스템을 구성 할 수 있기 때문입니다. NFD_Init 는 일반적으로 필요한 경우 기존 구성을 방해하지 않도록 매우주의를 기울이며 NFD_Quit 초기화 전의 구성으로 정확하게 구성을 복원합니다.
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
Linux에서는 GTK 대신 포털 구현을 사용할 수 있습니다.이 구현은 OS에서 선택하거나 사용자가 사용자 정의한 "기본"파일 선택기를 열 수 있습니다. 사용자는 xdg-desktop-portal 과 적절한 백엔드가 설치되어 있어야합니다 (가장 일반적인 데스크톱 배포판이 사전 설치되어 있음). 그렇지 않으면 NFD_ERROR 반환됩니다.
포털 구현을 사용하려면 빌드 명령에 -DNFD_PORTAL=ON 추가하십시오.
*참고 : 폴더 피커는 org.freedesktop.portal.filechooser 인터페이스 버전> = 3에서만 지원됩니다. NFD_PickFolder() 런타임에서 인터페이스 버전을 쿼리하고 버전이 너무 낮은 경우 NFD_ERROR 반환합니다.
Windows 및 MacOS와 달리 Linux에는 파일 Chooser가 운영 체제에 구워지지 않습니다. 파일 선택기를 원하는 Linux 애플리케이션은 일반적으로 위의 Linux 스크린 샷에서와 같이 GTK와 같은 라이브러리를 제공하는 라이브러리와 연결됩니다. 이것은 많은 애플리케이션이 사용하는 대부분 허용되는 솔루션이지만 GTK 배포판에서 파일 선택기를 외래로 보이게 할 수 있습니다.
Flatpak은 2015 년에 소개되었으며 파일 선택기를 열기위한 표준화 된 인터페이스가 나왔습니다. 이 인터페이스를 사용하는 응용 프로그램에는 파일 선택기가 제공 될 필요가 없었으며 FlatPak에서 제공하는 것을 사용할 수 있습니다. 이 인터페이스는 데스크탑 포털로 알려지고 사용 된 사용은 Flatpak 응용 프로그램으로 확장되었습니다. 이제 대부분의 주요 데스크톱 Linux 배포판에는 Desktop Portal이 설치되어 있으며 배포판 테마에 맞는 파일 선택기가 있습니다. 원하는 경우 사용자는 다른 포털 백엔드를 설치할 수도 있습니다. 현재 파일 선택자 지원으로 알려진 세 가지 백엔드가 있습니다 : GTK, KDE 및 LXQT; 그놈과 Xapp 백엔드는이 기능에 대한 GTK에 의존합니다. Xapp 백엔드는 계피, 메이트 및 XFCE 용으로 설계되었습니다. 다른 데스크탑 환경에는 현재 포털 백엔드가없는 것 같습니다.
Info.plist 파일의 데이터 유형을 정의해야합니다. ( -DNFD_USE_ALLOWEDCONTENTTYPES_IF_AVAILABLE=OFF 추가하여 NFDE가 허용 필기체를 사용하도록 강요 할 수 있지만 권장되지는 않지만 이전 MACOS 버전을 지원할 필요가있는 경우 올바른 배포 대상을 설정해야합니다.GetOpenFileName 과 같은 Windows XP의 레거시 대화 상자를 지원하지 않습니다. (이를 지원할 계획이 없습니다. 어쨌든 Windows XP를 사용하지 않아야합니다.)GitHub 문제 추적기를 사용하여 버그를보고 하거나이 저장소에 기여하십시오. 모든 종류의 버그 보고서를 자유롭게 제출하십시오.
Bernard Teo (ME) 및 Michael Labbe의 기본 파일 대화 상자에서 얻은 모든 것에 대한 다른 기고자.
그의 멋진 기본 파일 대화 라이브러리와 다른 라이브러리에 기여한 Michael Labbe.
이 readme의 대부분은 원래 기본 파일 대화 상자 리포지토리의 readme에서 복사되었습니다.
이 저장소의 모든 것은 원래 기본 파일 대화 라이브러리와 마찬가지로 Zlib 라이센스에 따라 배포됩니다.
나는 유료 지원을 제공하지 않습니다. Michael Labbe는 글을 쓰는 시점에 자신의 도서관에 대한 유급 지원을 제공하는 것으로 보입니다.