NFD updated to 1.1.4

This commit is contained in:
Azaezel 2019-01-01 10:58:53 -06:00
parent 3d94cb5b93
commit b0aa733c4e
6 changed files with 658 additions and 68 deletions

View file

@ -4,6 +4,10 @@
http://www.frogtoss.com/labs
*/
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
/* only locally define UNICODE in this compilation unit */
#ifndef UNICODE
#define UNICODE
@ -19,7 +23,7 @@
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <ShObjIdl.h>
#include <shobjidl.h>
#include "nfd_common.h"
@ -47,9 +51,9 @@ static void CopyWCharToNFDChar( const wchar_t *inStr, nfdchar_t **outStr )
/* includes NULL terminator byte in return */
static size_t GetUTF8ByteCountForWChar( const wchar_t *str )
{
int bytesNeeded = WideCharToMultiByte( CP_UTF8, 0,
str, -1,
NULL, 0, NULL, NULL );
size_t bytesNeeded = WideCharToMultiByte( CP_UTF8, 0,
str, -1,
NULL, 0, NULL, NULL );
assert( bytesNeeded );
return bytesNeeded+1;
}
@ -148,12 +152,12 @@ static nfdresult_t AddFiltersToDialog( ::IFileDialog *fileOpenDialog, const char
}
/* filterCount plus 1 because we hardcode the *.* wildcard after the while loop */
COMDLG_FILTERSPEC *specList = (COMDLG_FILTERSPEC*)NFDi_Malloc( sizeof(COMDLG_FILTERSPEC) * (filterCount + 1) );
COMDLG_FILTERSPEC *specList = (COMDLG_FILTERSPEC*)NFDi_Malloc( sizeof(COMDLG_FILTERSPEC) * ((size_t)filterCount + 1) );
if ( !specList )
{
return NFD_ERROR;
}
for (size_t i = 0; i < filterCount+1; ++i )
for (UINT i = 0; i < filterCount+1; ++i )
{
specList[i].pszName = NULL;
specList[i].pszSpec = NULL;
@ -181,9 +185,8 @@ static nfdresult_t AddFiltersToDialog( ::IFileDialog *fileOpenDialog, const char
if ( *p_filterList == ';' || *p_filterList == '\0' )
{
/* end of filter -- add it to specList */
// Empty filter name -- Windows describes them by extension.
CopyNFDCharToWChar(specbuf, (wchar_t**)&specList[specIdx].pszName);
CopyNFDCharToWChar( specbuf, (wchar_t**)&specList[specIdx].pszName );
CopyNFDCharToWChar( specbuf, (wchar_t**)&specList[specIdx].pszSpec );
memset( specbuf, 0, sizeof(char)*NFD_MAX_STRLEN );
@ -270,6 +273,8 @@ static nfdresult_t AllocPathSet( IShellItemArray *shellItems, nfdpathset_t *path
// Calculate length of name with UTF-8 encoding
bufSize += GetUTF8ByteCountForWChar( name );
CoTaskMemFree(name);
}
assert(bufSize);
@ -304,6 +309,7 @@ static nfdresult_t AllocPathSet( IShellItemArray *shellItems, nfdpathset_t *path
shellItem->GetDisplayName(SIGDN_FILESYSPATH, &name);
int bytesWritten = CopyWCharToExistingNFDCharBuffer(name, p_buf);
CoTaskMemFree(name);
ptrdiff_t index = p_buf - pathSet->buf;
assert( index >= 0 );
@ -353,29 +359,30 @@ static nfdresult_t SetDefaultPath( IFileDialog *dialog, const char *defaultPath
/* public */
nfdresult_t NFD_OpenDialog( const char *filterList,
nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdchar_t **outPath )
{
nfdresult_t nfdResult = NFD_ERROR;
// Init COM library.
HRESULT result = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );
HRESULT coResult = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );
::IFileOpenDialog *fileOpenDialog(NULL);
if ( !SUCCEEDED(result))
if ( !SUCCEEDED(coResult))
{
fileOpenDialog = NULL;
NFDi_SetError("Could not initialize COM.");
goto end;
}
// Create dialog
result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
CLSCTX_ALL, ::IID_IFileOpenDialog,
reinterpret_cast<void**>(&fileOpenDialog) );
HRESULT result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
CLSCTX_ALL, ::IID_IFileOpenDialog,
reinterpret_cast<void**>(&fileOpenDialog) );
if ( !SUCCEEDED(result) )
{
@ -412,6 +419,7 @@ nfdresult_t NFD_OpenDialog( const char *filterList,
if ( !SUCCEEDED(result) )
{
NFDi_SetError("Could not get file path for selected.");
shellItem->Release();
goto end;
}
@ -420,6 +428,7 @@ nfdresult_t NFD_OpenDialog( const char *filterList,
if ( !*outPath )
{
/* error is malloc-based, error message would be redundant */
shellItem->Release();
goto end;
}
@ -436,8 +445,12 @@ nfdresult_t NFD_OpenDialog( const char *filterList,
nfdResult = NFD_ERROR;
}
end:
::CoUninitialize();
end:
if (fileOpenDialog)
fileOpenDialog->Release();
if (SUCCEEDED(coResult))
::CoUninitialize();
return nfdResult;
}
@ -449,10 +462,10 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
nfdresult_t nfdResult = NFD_ERROR;
// Init COM library.
HRESULT result = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );
if ( !SUCCEEDED(result))
HRESULT coResult = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );
if ( !SUCCEEDED(coResult))
{
NFDi_SetError("Could not initialize COM.");
return NFD_ERROR;
@ -461,12 +474,13 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
::IFileOpenDialog *fileOpenDialog(NULL);
// Create dialog
result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
CLSCTX_ALL, ::IID_IFileOpenDialog,
reinterpret_cast<void**>(&fileOpenDialog) );
HRESULT result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
CLSCTX_ALL, ::IID_IFileOpenDialog,
reinterpret_cast<void**>(&fileOpenDialog) );
if ( !SUCCEEDED(result) )
{
fileOpenDialog = NULL;
NFDi_SetError("Could not create dialog.");
goto end;
}
@ -512,6 +526,7 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
if ( AllocPathSet( shellItems, outPaths ) == NFD_ERROR )
{
shellItems->Release();
goto end;
}
@ -528,8 +543,12 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
nfdResult = NFD_ERROR;
}
end:
::CoUninitialize();
end:
if ( fileOpenDialog )
fileOpenDialog->Release();
if (SUCCEEDED(coResult))
::CoUninitialize();
return nfdResult;
}
@ -541,10 +560,10 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
nfdresult_t nfdResult = NFD_ERROR;
// Init COM library.
HRESULT result = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );
if ( !SUCCEEDED(result))
HRESULT coResult = ::CoInitializeEx(NULL,
::COINIT_APARTMENTTHREADED |
::COINIT_DISABLE_OLE1DDE );
if ( !SUCCEEDED(coResult))
{
NFDi_SetError("Could not initialize COM.");
return NFD_ERROR;
@ -553,12 +572,13 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
::IFileSaveDialog *fileSaveDialog(NULL);
// Create dialog
result = ::CoCreateInstance(::CLSID_FileSaveDialog, NULL,
CLSCTX_ALL, ::IID_IFileSaveDialog,
reinterpret_cast<void**>(&fileSaveDialog) );
HRESULT result = ::CoCreateInstance(::CLSID_FileSaveDialog, NULL,
CLSCTX_ALL, ::IID_IFileSaveDialog,
reinterpret_cast<void**>(&fileSaveDialog) );
if ( !SUCCEEDED(result) )
{
fileSaveDialog = NULL;
NFDi_SetError("Could not create dialog.");
goto end;
}
@ -591,6 +611,7 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath);
if ( !SUCCEEDED(result) )
{
shellItem->Release();
NFDi_SetError("Could not get file path for selected.");
goto end;
}
@ -600,6 +621,7 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
if ( !*outPath )
{
/* error is malloc-based, error message would be redundant */
shellItem->Release();
goto end;
}
@ -616,8 +638,12 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
nfdResult = NFD_ERROR;
}
end:
::CoUninitialize();
end:
if ( fileSaveDialog )
fileSaveDialog->Release();
if (SUCCEEDED(coResult))
::CoUninitialize();
return nfdResult;
}
@ -729,7 +755,8 @@ nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath,
ComPtr<IShellItem> pShellItem;
if (!SUCCEEDED(pFileDialog->GetResult(&pShellItem)))
{
return NFD_OKAY;
NFDi_SetError("Could not get shell item from dialog.");
return NFD_ERROR;
}
// Finally get the path