mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-14 22:34:09 +02:00
361 lines
No EOL
12 KiB
Beef
361 lines
No EOL
12 KiB
Beef
|
|
#if BF_PLATFORM_WINDOWS
|
|
namespace System.IO
|
|
{
|
|
class FolderBrowserDialog : CommonDialog
|
|
{
|
|
public enum FolderKind
|
|
{
|
|
Open,
|
|
Save
|
|
}
|
|
|
|
String mSelectedPath = new String() ~ delete _;
|
|
public bool ShowNewFolderButton;
|
|
String mDescriptionText = new String() ~ delete _;
|
|
bool mSelectedPathNeedsCheck;
|
|
static FolderBrowserDialog sCurrentThis;
|
|
FolderKind mFolderKind;
|
|
|
|
public this(FolderKind kind = .Open)
|
|
{
|
|
mFolderKind = kind;
|
|
Reset();
|
|
}
|
|
|
|
public StringView SelectedPath
|
|
{
|
|
get
|
|
{
|
|
return mSelectedPath;
|
|
}
|
|
|
|
set
|
|
{
|
|
mSelectedPath.Set(value);
|
|
}
|
|
}
|
|
|
|
public StringView Description
|
|
{
|
|
get
|
|
{
|
|
return mDescriptionText;
|
|
}
|
|
|
|
set
|
|
{
|
|
mDescriptionText.Set(value);
|
|
}
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
mSelectedPath.Clear();
|
|
mDescriptionText.Clear();
|
|
mSelectedPathNeedsCheck = false;
|
|
ShowNewFolderButton = true;
|
|
}
|
|
|
|
protected Result<DialogResult> RunDialog_New(Windows.HWnd hWndOwner, FolderBrowserDialog.COM_IFileDialog* fileDialog)
|
|
{
|
|
//COM_IFileDialogEvents evts;
|
|
/*COM_IFileDialogEvents.VTable funcs;
|
|
funcs.QueryInterface = (self, riid, result) =>
|
|
{
|
|
return .E_FAIL;
|
|
};
|
|
funcs.AddRef = (self) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
funcs.Release = (self) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
funcs.OnFileOk = (self, fileDialog) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
funcs.OnFolderChanging = (self, fileDialog, folder) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
funcs.OnFolderChange = (self, fileDialog) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
funcs.OnSelectionChange = (self, fileDialog) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
funcs.OnShareViolation = (self, fileDialog, result) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
funcs.OnTypeChange = (self, fileDialog) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
funcs.OnOverwrite = (self, fileDialog, item, result) =>
|
|
{
|
|
return .OK;
|
|
};
|
|
evts.[Friend]mVT = &funcs;
|
|
fileDialog.VT.Advise(fileDialog, &evts, var adviseCookie);*/
|
|
|
|
if (!mSelectedPath.IsEmpty)
|
|
{
|
|
COM_IShellItem* folderShellItem = null;
|
|
Windows.SHCreateItemFromParsingName(mSelectedPath.ToScopedNativeWChar!(), null, COM_IShellItem.sIID, (void**)&folderShellItem);
|
|
if (folderShellItem != null)
|
|
{
|
|
fileDialog.VT.SetDefaultFolder(fileDialog, folderShellItem);
|
|
folderShellItem.VT.Release(folderShellItem);
|
|
}
|
|
}
|
|
|
|
fileDialog.VT.SetOptions(fileDialog, .PICKFOLDERS);
|
|
fileDialog.VT.Show(fileDialog, hWndOwner);
|
|
|
|
DialogResult result = .Cancel;
|
|
|
|
mSelectedPath.Clear();
|
|
COM_IShellItem* shellItem = null;
|
|
fileDialog.VT.GetResult(fileDialog, out shellItem);
|
|
if (shellItem != null)
|
|
{
|
|
char16* cStr = null;
|
|
if (shellItem.VT.GetDisplayName(shellItem, .FILESYSPATH, out cStr) == .OK)
|
|
{
|
|
let str = scope String..Append(cStr);
|
|
mSelectedPath.Append(str);
|
|
Windows.COM_IUnknown.CoTaskMemFree(cStr);
|
|
result = .OK;
|
|
}
|
|
shellItem.VT.Release(shellItem);
|
|
}
|
|
|
|
fileDialog.VT.Release(fileDialog);
|
|
return .Ok(result);
|
|
}
|
|
|
|
protected override Result<DialogResult> RunDialog(Windows.HWnd hWndOwner)
|
|
{
|
|
FolderBrowserDialog.COM_IFileDialog* fileDialog = null;
|
|
Windows.COM_IUnknown.HResult hr;
|
|
//if (mFolderKind == .Open)
|
|
hr = Windows.COM_IUnknown.CoCreateInstance(ref FolderBrowserDialog.COM_IFileDialog.sCLSID, null, .INPROC_SERVER, ref FolderBrowserDialog.COM_IFileDialog.sIID, (void**)&fileDialog);
|
|
//else
|
|
//hr = Windows.COM_IUnknown.CoCreateInstance(ref FolderBrowserDialog.COM_FileSaveDialog.sCLSID, null, .INPROC_SERVER, ref FolderBrowserDialog.COM_FileSaveDialog.sIID, (void**)&fileDialog);
|
|
if (hr == 0)
|
|
return RunDialog_New(hWndOwner, fileDialog);
|
|
|
|
int pidlRoot = 0;
|
|
//Windows.SHGetSpecialFolderLocation(hWndOwner, (int32)mRootFolder, ref pidlRoot);
|
|
if (pidlRoot == (int)0)
|
|
{
|
|
Windows.SHGetSpecialFolderLocation(hWndOwner, Windows.CSIDL_DESKTOP, ref pidlRoot);
|
|
if (pidlRoot == (int)0)
|
|
return .Err;
|
|
}
|
|
|
|
int32 mergedOptions = (int32)Windows.BrowseInfos.NewDialogStyle;
|
|
if (!ShowNewFolderButton)
|
|
mergedOptions |= (int32)Windows.BrowseInfos.HideNewFolderButton;
|
|
|
|
String displayName = scope String(Windows.MAX_PATH);
|
|
|
|
Windows.WndProc callback = => FolderBrowserDialog_BrowseCallbackProc;
|
|
|
|
Windows.BrowseInfo bi;
|
|
bi.mHWndOwner = hWndOwner;
|
|
bi.mIdlRoot = pidlRoot;
|
|
bi.mDisplayName = displayName;
|
|
bi.mTitle = mDescriptionText;
|
|
bi.mFlags = mergedOptions;
|
|
bi.mCallback = callback;
|
|
bi.mLParam = 0;
|
|
bi.mImage = 0;
|
|
|
|
sCurrentThis = this;
|
|
int pidlRet = Windows.SHBrowseForFolder(ref bi);
|
|
sCurrentThis = null;
|
|
|
|
if (pidlRet == (int)0)
|
|
return DialogResult.Cancel;
|
|
|
|
char8* selectedPathCStr = scope char8[Windows.MAX_PATH]*;
|
|
Windows.SHGetPathFromIDList(pidlRet, selectedPathCStr);
|
|
mSelectedPath.Clear();
|
|
mSelectedPath.Append(selectedPathCStr);
|
|
|
|
return DialogResult.OK;
|
|
}
|
|
|
|
public static int FolderBrowserDialog_BrowseCallbackProc(Windows.HWnd hWnd, int32 msg, int wParam, int lParam)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case Windows.BFFM_INITIALIZED:
|
|
// Indicates the browse dialog box has finished initializing. The lpData value is zero.
|
|
if (sCurrentThis.mSelectedPath.Length != 0)
|
|
{
|
|
// Try to select the folder specified by selectedPath
|
|
Windows.SendMessageW(hWnd, Windows.BFFM_SETSELECTIONA, 1, (int)(void*)sCurrentThis.mSelectedPath.ToScopedNativeWChar!());
|
|
}
|
|
break;
|
|
case Windows.BFFM_SELCHANGED:
|
|
// Indicates the selection has changed. The lpData parameter points to the item identifier list for the newly selected item.
|
|
int selectedPidl = lParam;
|
|
if (selectedPidl != (int)0)
|
|
{
|
|
char8* pszSelectedPath = scope char8[Windows.MAX_PATH]*;
|
|
// Try to retrieve the path from the IDList
|
|
bool isFileSystemFolder = Windows.SHGetPathFromIDList(selectedPidl, pszSelectedPath);
|
|
Windows.SendMessageW(hWnd, Windows.BFFM_ENABLEOK, 0, (int)(isFileSystemFolder ? 1 : 0));
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
struct FDE_SHAREVIOLATION_RESPONSE;
|
|
struct FDE_OVERWRITE_RESPONSE;
|
|
|
|
struct COM_IFileDialogEvents : Windows.COM_IUnknown
|
|
{
|
|
public struct VTable : Windows.COM_IUnknown.VTable
|
|
{
|
|
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFileOk;
|
|
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* psiFolder) OnFolderChanging;
|
|
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnFolderChange;
|
|
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnSelectionChange;
|
|
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, FDE_SHAREVIOLATION_RESPONSE* pResponse) OnShareViolation;
|
|
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog) OnTypeChange;
|
|
public function HResult(COM_IFileDialogEvents* self, COM_IFileDialog* fileDialog, COM_IShellItem* shellItem, FDE_OVERWRITE_RESPONSE* response) OnOverwrite;
|
|
|
|
}
|
|
}
|
|
|
|
struct COM_IShellItem : Windows.COM_IUnknown
|
|
{
|
|
public static Guid sIID = .(0x43826d1e, 0xe718, 0x42ee, 0xbc, 0x55, 0xa1, 0xe2, 0x61, 0xc3, 0x7b, 0xfe);
|
|
|
|
public enum SIGDN : uint32
|
|
{
|
|
NORMALDISPLAY = 0x00000000, // SHGDN_NORMAL
|
|
PARENTRELATIVEPARSING = 0x80018001, // SHGDN_INFOLDER | SHGDN_FORPARSING
|
|
DESKTOPABSOLUTEPARSING = 0x80028000, // SHGDN_FORPARSING
|
|
PARENTRELATIVEEDITING = 0x80031001, // SHGDN_INFOLDER | SHGDN_FOREDITING
|
|
DESKTOPABSOLUTEEDITING = 0x8004c000, // SHGDN_FORPARSING | SHGDN_FORADDRESSBAR
|
|
FILESYSPATH = 0x80058000, // SHGDN_FORPARSING
|
|
URL = 0x80068000, // SHGDN_FORPARSING
|
|
PARENTRELATIVEFORADDRESSBAR = 0x8007c001, // SHGDN_INFOLDER | SHGDN_FORPARSING | SHGDN_FORADDRESSBAR
|
|
PARENTRELATIVE = 0x80080001 // SHGDN_INFOLDER
|
|
}
|
|
|
|
public struct VTable : Windows.COM_IUnknown.VTable
|
|
{
|
|
public function HResult(COM_IShellItem* self, void* pbc, ref Guid bhid, ref Guid riid, void** ppv) BindToHandler;
|
|
public function HResult(COM_IShellItem* self, out COM_IShellItem* ppsi) GetParent;
|
|
public function HResult(COM_IShellItem* self, SIGDN sigdnName, out char16* ppszName) GetDisplayName;
|
|
public function HResult(COM_IShellItem* self, uint sfgaoMask, out uint psfgaoAttribs) GetAttributes;
|
|
public function HResult(COM_IShellItem* self, COM_IShellItem* psi, uint32 hint, out int32 piOrder) Compare;
|
|
|
|
}
|
|
public new VTable* VT
|
|
{
|
|
get
|
|
{
|
|
return (.)mVT;
|
|
}
|
|
}
|
|
}
|
|
|
|
struct COMDLG_FILTERSPEC
|
|
{
|
|
public char16* pszName;
|
|
public char16* pszSpec;
|
|
}
|
|
|
|
enum FDAP : uint32
|
|
{
|
|
FDAP_BOTTOM = 0x00000000,
|
|
FDAP_TOP = 0x00000001,
|
|
}
|
|
|
|
public struct COM_IFileDialog : Windows.COM_IUnknown
|
|
{
|
|
public static Guid sIID = .(0x42f85136, 0xdb7e, 0x439c, 0x85, 0xf1, 0xe4, 0x07, 0x5d, 0x13, 0x5f, 0xc8);
|
|
public static Guid sCLSID = .(0xdc1c5a9c, 0xe88a, 0x4dde, 0xa5, 0xa1, 0x60, 0xf8, 0x2a, 0x20, 0xae, 0xf7);
|
|
|
|
///s
|
|
public enum FOS : uint32
|
|
{
|
|
OVERWRITEPROMPT = 0x00000002,
|
|
STRICTFILETYPES = 0x00000004,
|
|
NOCHANGEDIR = 0x00000008,
|
|
PICKFOLDERS = 0x00000020,
|
|
FORCEFILESYSTEM = 0x00000040,
|
|
ALLNONSTORAGEITEMS = 0x00000080,
|
|
NOVALIDATE = 0x00000100,
|
|
ALLOWMULTISELECT = 0x00000200,
|
|
PATHMUSTEXIST = 0x00000800,
|
|
FILEMUSTEXIST = 0x00001000,
|
|
CREATEPROMPT = 0x00002000,
|
|
SHAREAWARE = 0x00004000,
|
|
NOREADONLYRETURN = 0x00008000,
|
|
NOTESTFILECREATE = 0x00010000,
|
|
HIDEMRUPLACES = 0x00020000,
|
|
HIDEPINNEDPLACES = 0x00040000,
|
|
NODEREFERENCELINKS = 0x00100000,
|
|
DONTADDTORECENT = 0x02000000,
|
|
FORCESHOWHIDDEN = 0x10000000,
|
|
DEFAULTNOMINIMODE = 0x20000000
|
|
}
|
|
|
|
public struct VTable : Windows.COM_IUnknown.VTable
|
|
{
|
|
public function HResult(COM_IFileDialog* self, Windows.HWnd parent) Show;
|
|
public function HResult(COM_IFileDialog* self, uint cFileTypes, COMDLG_FILTERSPEC* rgFilterSpec) SetFileTypes;
|
|
public function HResult(COM_IFileDialog* self, uint iFileType) SetFileTypeIndex;
|
|
public function HResult(COM_IFileDialog* self, out uint piFileType) GetFileTypeIndex;
|
|
public function HResult(COM_IFileDialog* self, COM_IFileDialogEvents* pfde, out uint pdwCookie) Advise;
|
|
public function HResult(COM_IFileDialog* self, uint dwCookie) Unadvise;
|
|
public function HResult(COM_IFileDialog* self, FOS fos) SetOptions;
|
|
public function HResult(COM_IFileDialog* self, out FOS pfos) GetOptions;
|
|
public function HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetDefaultFolder;
|
|
public function HResult(COM_IFileDialog* self, COM_IShellItem* psi) SetFolder;
|
|
public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetFolder;
|
|
public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetCurrentSelection;
|
|
public function HResult(COM_IFileDialog* self, char16* pszName) SetFileName;
|
|
public function HResult(COM_IFileDialog* self, out char16* pszName) GetFileName;
|
|
public function HResult(COM_IFileDialog* self, char16* pszTitle) SetTitle;
|
|
public function HResult(COM_IFileDialog* self, char16* pszText) SetOkButtonLabel;
|
|
public function HResult(COM_IFileDialog* self, char16* pszLabel) SetFileNameLabel;
|
|
public function HResult(COM_IFileDialog* self, out COM_IShellItem* ppsi) GetResult;
|
|
public function HResult(COM_IFileDialog* self, COM_IShellItem* psi, FDAP fdap) AddPlace;
|
|
public function HResult(COM_IFileDialog* self, char16* pszDefaultExtension) SetDefaultExtension;
|
|
public function HResult(COM_IFileDialog* self, int hr) Close;
|
|
public function HResult(COM_IFileDialog* self, ref Guid guid) SetClientGuid;
|
|
public function HResult(COM_IFileDialog* self) ClearClientData;
|
|
public function HResult(COM_IFileDialog* self, void* pFilter) SetFilter;
|
|
}
|
|
public new VTable* VT
|
|
{
|
|
get
|
|
{
|
|
return (.)mVT;
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct COM_FileSaveDialog : COM_IFileDialog
|
|
{
|
|
public static new Guid sIID = .(0x84bccd23, 0x5fde, 0x4cdb, 0xae, 0xa4, 0xaf, 0x64, 0xb8, 0x3d, 0x78, 0xab);
|
|
public static new Guid sCLSID = .(0xC0B4E2F3, 0xBA21, 0x4773, 0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B);
|
|
}
|
|
}
|
|
}
|
|
#endif |