I needed a better select folder dialog option PowerBuilder's default GetFolder option.
The base PB function is too basic in many ways.
I found the "Common Item Dialog" solution Bruce Armstrong presented a while back and after some fiddling got it working the way I needed to but needing to have .NET Framework installed seems overkill, along with the GAC and registry configuration steps to get it work and hopefully my installation program is smart and good enough to get it all done properly for as many windows installs as possible. That's the problem, so many windows OS install varieties in the user base and trusting that MS wont change something that breaks this important feature ...
I also suspect the .NET version used to compile the FolderBrowser dll was v2 and I have to decide if I should be updating to .net 4 or not before going too much farther down this rabbit hole.
We are talking about the new Select Folder (example below anonymized)
vs the PB Stock GetFolder
Is there any other easier "PowerBuilder Only" way to pop open the more enhanced get folder using the updated "Common Item Dialog" using PB only code or functions rather than resorting to anything external?
Does anyone know if Appeon is planning on enhancements to add some additional support for the newer modernized common item dialog's as base calls in PB? (Hint)
Anyone else work with the new updated common item dialog that has any input to share would be appreciated.
Thanks
Maybe it'll fix the problem (if the FolderBrowser itself doesn't change any 'internal' directories by accessing files.
regards.
SetCurrentDirectory or ChangeDirectory all did not work.
However, good news is it was much simpler than i imagined, I just opened the FolderBrowser2 sample source in Visual Studios 2019 and modified the FolderBrowser2.cs source script to add a few lines and updated the ShowDialog() to add another string argument, tested the directory provided if it was valid and now if we pass in a valid UNC or Directory path on the machine the PB app is run on the dialog is now opening to the directory desired.
Its really the best solution so far so I am just going to run with it.
Thanks for the suggestions guys I was just trying to avoid modifying the original sample dll but life is never as easy as that anyhow its done.
sample of the updated FolderBrowser2.cs that works to add the parm for setting the default folder:
using System;
using System.Runtime.InteropServices;
using System.IO;
namespace FolderBrowser2
{
public class FolderBrowser2
{
public string DirectoryPath { get; set; }
public int ShowDialog( ulong handle, string strStartPath){
IntPtr hwndOwner = (IntPtr)handle;
IFileOpenDialog dialog = (IFileOpenDialog)new FileOpenDialog();
try
{
IShellItem item;
if (!string.IsNullOrEmpty(strStartPath))
{
if (Directory.Exists(strStartPath))
{
DirectoryPath = strStartPath;
}
}
if (!string.IsNullOrEmpty(DirectoryPath))
{
IntPtr idl;
uint atts = 0;
if (SHILCreateFromPath(DirectoryPath, out idl, ref atts) == 0)
{
if (SHCreateShellItem(IntPtr.Zero, IntPtr.Zero, idl, out item) == 0)
{
dialog.SetFolder(item);
}
}
}
dialog.SetOptions(FOS.FOS_PICKFOLDERS | FOS.FOS_FORCEFILESYSTEM);
uint hr = dialog.Show(hwndOwner);
if (hr == ERROR_CANCELLED)
return FB2_CANCEL;
if (hr != 0)
return FB2_ERROR;
dialog.GetResult(out item);
string path;
item.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out path);
DirectoryPath = path;
return FB2_SUCCESS;
}
finally
{
Marshal.ReleaseComObject(dialog);
}
}
[DllImport("shell32.dll")]
private static extern int SHILCreateFromPath([MarshalAs(UnmanagedType.LPWStr)] string pszPath, out IntPtr ppIdl, ref uint rgflnOut);
[DllImport("shell32.dll")]
private static extern int SHCreateShellItem(IntPtr pidlParent, IntPtr psfParent, IntPtr pidl, out IShellItem ppsi);
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
private const uint ERROR_CANCELLED = 0x800704C7;
private const int FB2_SUCCESS = 1;
private const int FB2_CANCEL = 0;
private const int FB2_ERROR = -1;
[ComImport]
[Guid("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7")]
private class FileOpenDialog
{
}
[ComImport]
[Guid("42f85136-db7e-439c-85f1-e4075d135fc8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IFileOpenDialog
{
[PreserveSig]
uint Show([In] IntPtr parent); // IModalWindow
void SetFileTypes(); // not fully defined
void SetFileTypeIndex([In] uint iFileType);
void GetFileTypeIndex(out uint piFileType);
void Advise(); // not fully defined
void Unadvise();
void SetOptions([In] FOS fos);
void GetOptions(out FOS pfos);
void SetDefaultFolder(IShellItem psi);
void SetFolder(IShellItem psi);
void GetFolder(out IShellItem ppsi);
void GetCurrentSelection(out IShellItem ppsi);
void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName);
void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText);
void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
void GetResult(out IShellItem ppsi);
void AddPlace(IShellItem psi, int alignment);
void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
void Close(int hr);
void SetClientGuid(); // not fully defined
void ClearClientData();
void SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter);
void GetResults([MarshalAs(UnmanagedType.Interface)] out IntPtr ppenum); // not fully defined
void GetSelectedItems([MarshalAs(UnmanagedType.Interface)] out IntPtr ppsai); // not fully defined
}
[ComImport]
[Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellItem
{
void BindToHandler(); // not fully defined
void GetParent(); // not fully defined
void GetDisplayName([In] SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
void GetAttributes(); // not fully defined
void Compare(); // not fully defined
}
private enum SIGDN : uint
{
SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000,
SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,
SIGDN_FILESYSPATH = 0x80058000,
SIGDN_NORMALDISPLAY = 0,
SIGDN_PARENTRELATIVE = 0x80080001,
SIGDN_PARENTRELATIVEEDITING = 0x80031001,
SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001,
SIGDN_PARENTRELATIVEPARSING = 0x80018001,
SIGDN_URL = 0x80068000
}
[Flags]
private enum FOS
{
FOS_ALLNONSTORAGEITEMS = 0x80,
FOS_ALLOWMULTISELECT = 0x200,
FOS_CREATEPROMPT = 0x2000,
FOS_DEFAULTNOMINIMODE = 0x20000000,
FOS_DONTADDTORECENT = 0x2000000,
FOS_FILEMUSTEXIST = 0x1000,
FOS_FORCEFILESYSTEM = 0x40,
FOS_FORCESHOWHIDDEN = 0x10000000,
FOS_HIDEMRUPLACES = 0x20000,
FOS_HIDEPINNEDPLACES = 0x40000,
FOS_NOCHANGEDIR = 8,
FOS_NODEREFERENCELINKS = 0x100000,
FOS_NOREADONLYRETURN = 0x8000,
FOS_NOTESTFILECREATE = 0x10000,
FOS_NOVALIDATE = 0x100,
FOS_OVERWRITEPROMPT = 2,
FOS_PATHMUSTEXIST = 0x800,
FOS_PICKFOLDERS = 0x20,
FOS_SHAREAWARE = 0x4000,
FOS_STRICTFILETYPES = 4
}
}
}