ネイティブファイルを開く、フォルダーの選択、およびファイルの保存ダイアログを携帯的に呼び出す小さなCライブラリ。ダイアログコードを一度書き込み、サポートされているすべてのプラットフォームでネイティブダイアログをポップアップします。 wxwidgetsやqtなどの大規模な依存関係をリンクしないでください。
このライブラリは、Michael Labbeのネイティブファイルダイアログ(MLABBE/NativeFileDialog)に基づいています。
特徴:
C/C++ Source files (*.c;*.cpp)の代わりに(*.c;*.cpp) )Untitled.c )wchar_t )サポートIFileDialogのサポートunique_ptr自動フリー化セマンティクスとオプションのパラメーターを備えたオプションのC ++ラッパー元のネイティブファイルダイアログとの比較:
フレンドリーな名前の機能は、Michael LabbeのライブラリとのAPI互換性を破る主な理由です(したがって、このライブラリはおそらくそれと統合されることはありません)。また、このライブラリに観察可能な違いを引き起こす多くの微調整もあります。
ネイティブファイルダイアログに追加された機能拡張:
wchar_t )サポートunique_ptr auto-freeingセマンティクスとオプションのパラメーターまた、特に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構造体に設定できる引数の完全なリストについては、以下の「すべてのオプション」セクションを参照してください。
SDLやGLFWなどのプラットフォーム抽象化フレームワークを使用している場合は、以下の「プラットフォーム抽象化フレームワークを使用した使用法」セクションも参照してください。






プロジェクトがcmakeを使用している場合は、次の行をcmakelists.txtに追加するだけです。
add_subdirectory(path/to/nativefiledialog-extended)
target_link_libraries(MyProgram PRIVATE nfd)
必要な依存関係もあることを確認してください。
サブプロジェクトとして含まれる場合、サンプルプログラムは構築されず、デフォルトでインストールターゲットが無効になります。 -DNFD_BUILD_TESTS=ONをオンにして、サンプルプログラムと-DNFD_INSTALL=ONなり、インストールターゲットを有効にします。
スタンドアロンの静的ライブラリを構築する場合は、次のコマンドを実行します(Project Root Directoryから開始):
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 offビルディングサンプルプログラムと-DNFD_INSTALL=OFF無効にして、インストールターゲットを無効にします。
Linuxでは、GTKの代わりにFlatpakデスクトップポータルを使用する場合は、 -DNFD_PORTAL=ONを追加します。 (それ以外の場合は、GTKが使用されます。)詳細については、以下の「使用法」セクションを参照してください。
いくつかの例のビルドコマンドについては、CIビルドファイルを参照してください。
Visual Studioの最近のバージョンには、IDEにCmakeサポートが組み込まれています。 Project Root Directoryで「フォルダーを開く」ことができるはずであり、Visual Studioはプロジェクトを適切に認識して構成します。そこから、デバッグ対リリース、およびX86対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では、Frameworksのリストに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すべてのオプションを合理的なデフォルトに設定します)。
NFDEの将来のバージョンは、メジャーバージョン番号にぶつかることなく、引数構造体の最後に追加のオプションを追加する場合があるため、逆方向のAPI互換性を確保するために、構造体に特定の長さまたは数のフィールドがあると仮定してはなりません。構造体のゼロイナイト化が引き続きすべてのオプションを合理的なデフォルトに設定し続けると仮定する可能性があるため、 {0}構造体に割り当てることは許容されます。 NFDEの共有ライブラリを構築する人の場合、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 :これをダイアログを開くデフォルトフォルダーに設定します(Windowsで、最近使用されたフォルダーがある場合、 NFD_OVERRIDE_RECENT_WITH_DEFAULTビルドオプションがオンに設定されていない限り、渡すフォルダーの代わりにそのフォルダーに開きます)。defaultName :( SaveDialogのみ)これをダイアログで事前に入力する必要があるファイル名に設定します。parentWindow :このダイアログの親のネイティブウィンドウハンドルにこれを設定します。詳細については、「プラットフォーム抽象化フレームワークを使用した使用法」セクションを参照してください。プラットフォーム抽象化フレームワークを使用していなくても、ハンドルを渡すこともできます。 たとえばコード(C ++の両方)については、 testディレクトリを参照してください。
testディレクトリ( -DNFD_BUILD_TESTS=ON )をビルドするオプションをオンにした場合、 build/binにはコンパイルされたテストプログラムが含まれます。
また、 -DNFD_BUILD_SDL2_TESTS=ONで個別に有効にする必要があるSDL2の例もあります。 SDL2をマシンにインストールする必要があります。
コンパイルされた例(SDL2の例を含む)も、GitHubアクションにアーティファクトとしてアップロードされ、そこからダウンロードできます。
ファイルは、ファイル拡張機能グループによってフィルタリングできます。
nfdu8filteritem_t filters [ 2 ] = { { "Source code" , "c,cpp,cc" }, { "Headers" , "h,hpp" } };ファイルフィルターは、友好的な名前と仕様を含む文字列のペアです(複数のファイル拡張機能はコンマ分離されています)。
ライブラリを呼び出す際に、ファイルフィルターのリストを引数として渡すことができます。
すべてのダイアログに常にワイルドカードフィルターが追加されます。
注:macosでは、ファイルダイアログにはフレンドリーな名前がなく、フィルター間を切り替える方法がないため、フィルター仕様が組み合わされます(「C、CPP、CC、H、HPP」など)。フィルター仕様は、ユーザーに明示的に表示されることもありません。これは通常のmacosの行動であり、ユーザーはそれを期待しています。
注2:仕様文字列が空ではないこと、およびすべてのファイル拡張機能が少なくとも1つの文字があることを確認する必要があります。それ以外の場合、悪いことが続く可能性があります(つまり、未定義の動作)。
注3:Linuxでは、ユーザーが「保存」ボタンを押し下げると、ファイル拡張子が追加されます(欠落している場合)。上書きプロンプトが表示され、ユーザーが「キャンセル」を押している場合でも、Appededファイル拡張子がユーザーに表示されたままになります。
注4:Windowsでは、 NFD_OVERRIDE_RECENT_WITH_DEFAULTビルドオプションがオンに設定されていない限り、デフォルトのフォルダーパラメーターは最近使用されているフォルダーがない場合にのみ使用されます。それ以外の場合、デフォルトのフォルダーは、最後に使用されたフォルダーになります。内部的には、Windowsの実装はIfiledialog :: SetDefaultFolder(iShellitem)を呼び出します。これは通常のWindowsの動作であり、ユーザーはそれを期待しています。
複数の選択をサポートするファイル開くダイアログは、パスセットを生成します。これは、プラットフォーム固有のコレクションに対する薄い抽象化です。パスセットを繰り返す方法は2つあります。
この方法は、パスセットでの配列のようなアクセスを行い、最も使いやすいです。ただし、特定のプラットフォーム(Linux、および場合によってはWindows)では、基礎となるプラットフォーム固有の実装がリンクリストを使用するため、パスセット全体を反復するには合計でO(n 2 )時間がかかります。
test_opendialogmultiple.cを参照してください。
この方法では、列挙器オブジェクトを使用して、パスセットのパスを反復します。パスセット全体を繰り返すには、合計でO(n)時間がかかることが保証されています。
test_opendialogmultiple_enum.cを参照してください。
このAPIは実験的であり、変更される場合があります。
nfd.h / nfd.hppを含める前に、次のマクロを定義できます。
NFD_NATIVE : nfd.hを含める前に、これを定義して、UTF-8関数のエイリアス( NFD_OpenDialogU8など)の代わりに、ネイティブ関数( NFD_OpenDialogNなど)の非吸引機能名とtypedefs( NFD_OpenDialog )エイリアスを作成します。このマクロは、C ++ラッパーnfd.hppに影響しません。NFD_THROWS_EXCEPTIONS :(c ++のみ) nfd.hppを含める前にこれを定義して、 NFD::Guard construction throw std::runtime_error NFD_Initが失敗した場合。それ以外の場合、 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で動作することが知られており、他のプラットフォーム抽象化フラムワークでも動作する必要があります。このセクションでは、このようなフレームワークで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の代わりにポータル実装を使用できます。GTKは、OSが選択したか、ユーザーがカスタマイズした「ネイティブ」ファイル選択者を開きます。ユーザーはxdg-desktop-portalと適切なバックエンドがインストールされている必要があります(これには、最も一般的なデスクトップディストリビューNFD_ERRORがプリインストールされています)。
ポータルの実装を使用するには、buildコマンドに-DNFD_PORTAL=ON追加します。
*注:フォルダーピッカーは、corg.freedesktop.portal.filechooserインターフェイスバージョン> = 3でのみサポートされています。 NFD_PickFolder()実行時にインターフェイスバージョンをクエリし、バージョンが低すぎる場合はNFD_ERRORを返します。
WindowsやMacOSとは異なり、Linuxにはファイル選択者がオペレーティングシステムに焼き付けられていません。ファイルを選択したいLinuxアプリケーションは、通常、1つを提供するライブラリ(上記のLinuxスクリーンショットなど)を提供するライブラリにリンクします。これは、多くのアプリケーションが使用するほとんど許容可能なソリューションですが、ファイル選択者を非GTKディストリビューションで外来に見せることができます。
Flatpakは2015年に導入され、ファイル選択者を開くための標準化されたインターフェイスが導入されました。このインターフェイスを使用するアプリケーションは、ファイル選択者を搭載する必要はなく、Flatpakが提供するものを使用できます。このインターフェイスはデスクトップポータルとして知られるようになり、その使用は非フラットパックアプリケーションに拡大しました。現在、ほとんどの主要なデスクトップLinuxディストリビューションには、ディストリビューションのテーマに合ったファイル選択者が備わっているデスクトップポータルがインストールされています。ユーザーは、必要に応じて別のポータルバックエンドをインストールすることもできます。現在、ファイル選択サポートを備えた3つの既知のバックエンドがあります:GTK、KDE、およびLXQT。 GNOMEおよびXAPPバックエンドは、この機能についてGTKのバックエンドに依存します。 Xapp Backendは、シナモン、メイト、XFCE用に設計されています。他のデスクトップ環境には現在、ポータルバックエンドがあるようには見えません。
Info.plistファイルのデータ型を定義する必要があります。 ( -DNFD_USE_ALLOWEDCONTENTTYPES_IF_AVAILABLE=OFFをCMAKEビルドコマンドに追加することにより、NFDEにAlovedFileTypesを使用させることができますが、これは推奨されません。古いMacOSバージョンをサポートする必要がある場合は、代わりに正しい展開目標を設定する必要があります。GetOpenFileNameなどのWindows XPのレガシーダイアログはサポートしていません。 (これをサポートする計画はありません。とにかくWindows XPを使用するべきではありません。)GitHub Issue Trackerを使用して、バグを報告するか、このリポジトリに貢献してください。あらゆる種類のバグレポートをお気軽に送信してください。
Michael Labbeのネイティブファイルダイアログからのものではないすべてのものについて、Bernard Teo(私)と他の貢献者。
彼の素晴らしいネイティブファイルのダイアログライブラリ、およびそのライブラリへの他の貢献者のためのマイケルラブベ。
このREADMEの多くは、元のネイティブファイルダイアログリポジトリのREADMEからもコピーされています。
このリポジトリのすべては、元のネイティブファイルダイアログライブラリと同様に、ZLIBライセンスの下に配布されます。
有料のサポートは提供していません。 Michael Labbeは、執筆時点で彼の図書館に有料のサポートを提供しているようです。