mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +00:00
Updates Native File Dialogs lib to enable browsing and selecting of folders, instead of just files.
This commit is contained in:
parent
4f78143dc8
commit
f657f774ce
7 changed files with 250 additions and 15 deletions
|
|
@ -9,13 +9,17 @@
|
|||
#define UNICODE
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
// Explicitly setting NTDDI version, this is necessary for the MinGW compiler
|
||||
#define NTDDI_VERSION NTDDI_VISTA
|
||||
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
||||
#endif
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <ShObjIdl.h>
|
||||
|
||||
#include "nfd_common.h"
|
||||
|
||||
|
||||
|
|
@ -359,14 +363,15 @@ nfdresult_t NFD_OpenDialog( const char *filterList,
|
|||
HRESULT result = ::CoInitializeEx(NULL,
|
||||
::COINIT_APARTMENTTHREADED |
|
||||
::COINIT_DISABLE_OLE1DDE );
|
||||
|
||||
::IFileOpenDialog *fileOpenDialog(NULL);
|
||||
|
||||
if ( !SUCCEEDED(result))
|
||||
{
|
||||
NFDi_SetError("Could not initialize COM.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
::IFileOpenDialog *fileOpenDialog(NULL);
|
||||
|
||||
// Create dialog
|
||||
result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
|
||||
CLSCTX_ALL, ::IID_IFileOpenDialog,
|
||||
|
|
@ -616,3 +621,133 @@ nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
|
|||
|
||||
return nfdResult;
|
||||
}
|
||||
|
||||
class AutoCoInit
|
||||
{
|
||||
public:
|
||||
AutoCoInit()
|
||||
{
|
||||
mResult = ::CoInitializeEx(NULL,
|
||||
::COINIT_APARTMENTTHREADED |
|
||||
::COINIT_DISABLE_OLE1DDE);
|
||||
}
|
||||
|
||||
~AutoCoInit()
|
||||
{
|
||||
if (SUCCEEDED(mResult))
|
||||
{
|
||||
::CoUninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT Result() const { return mResult; }
|
||||
private:
|
||||
HRESULT mResult;
|
||||
};
|
||||
|
||||
// VS2010 hasn't got a copy of CComPtr - this was first added in the 2003 SDK, so we make our own small CComPtr instead
|
||||
template<class T>
|
||||
class ComPtr
|
||||
{
|
||||
public:
|
||||
ComPtr() : mPtr(NULL) { }
|
||||
~ComPtr()
|
||||
{
|
||||
if (mPtr)
|
||||
{
|
||||
mPtr->Release();
|
||||
}
|
||||
}
|
||||
|
||||
T* Ptr() const { return mPtr; }
|
||||
T** operator&() { return &mPtr; }
|
||||
T* operator->() const { return mPtr; }
|
||||
private:
|
||||
// Don't allow copy or assignment
|
||||
ComPtr(const ComPtr&);
|
||||
ComPtr& operator = (const ComPtr&) const;
|
||||
T* mPtr;
|
||||
};
|
||||
|
||||
nfdresult_t NFD_PickFolder(const nfdchar_t *defaultPath,
|
||||
nfdchar_t **outPath)
|
||||
{
|
||||
// Init COM
|
||||
AutoCoInit autoCoInit;
|
||||
if (!SUCCEEDED(autoCoInit.Result()))
|
||||
{
|
||||
NFDi_SetError("CoInitializeEx failed.");
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
// Create the file dialog COM object
|
||||
ComPtr<IFileDialog> pFileDialog;
|
||||
if (!SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog,
|
||||
NULL,
|
||||
CLSCTX_ALL,
|
||||
IID_PPV_ARGS(&pFileDialog))))
|
||||
{
|
||||
NFDi_SetError("CoCreateInstance for CLSID_FileOpenDialog failed.");
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
// Set the default path
|
||||
if (SetDefaultPath(pFileDialog.Ptr(), defaultPath) != NFD_OKAY)
|
||||
{
|
||||
NFDi_SetError("SetDefaultPath failed.");
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
// Get the dialogs options
|
||||
DWORD dwOptions = 0;
|
||||
if (!SUCCEEDED(pFileDialog->GetOptions(&dwOptions)))
|
||||
{
|
||||
NFDi_SetError("GetOptions for IFileDialog failed.");
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
// Add in FOS_PICKFOLDERS which hides files and only allows selection of folders
|
||||
if (!SUCCEEDED(pFileDialog->SetOptions(dwOptions | FOS_PICKFOLDERS)))
|
||||
{
|
||||
NFDi_SetError("SetOptions for IFileDialog failed.");
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
// Show the dialog to the user
|
||||
const HRESULT result = pFileDialog->Show(NULL);
|
||||
if (result == HRESULT_FROM_WIN32(ERROR_CANCELLED))
|
||||
{
|
||||
return NFD_CANCEL;
|
||||
}
|
||||
else if (!SUCCEEDED(result))
|
||||
{
|
||||
NFDi_SetError("Show for IFileDialog failed.");
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
// Get the shell item result
|
||||
ComPtr<IShellItem> pShellItem;
|
||||
if (!SUCCEEDED(pFileDialog->GetResult(&pShellItem)))
|
||||
{
|
||||
return NFD_OKAY;
|
||||
}
|
||||
|
||||
// Finally get the path
|
||||
wchar_t *path = NULL;
|
||||
if (!SUCCEEDED(pShellItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &path)))
|
||||
{
|
||||
NFDi_SetError("GetDisplayName for IShellItem failed.");
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
// Convert string
|
||||
CopyWCharToNFDChar(path, outPath);
|
||||
CoTaskMemFree(path);
|
||||
if (!*outPath)
|
||||
{
|
||||
// error is malloc-based, error message would be redundant
|
||||
return NFD_ERROR;
|
||||
}
|
||||
|
||||
return NFD_OKAY;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue