FolderBrowser via []CSE

General discussions related to using the C# Script Engine in APL+Win.

Moderators: Tech Support, phpbb_admin

FolderBrowser via []CSE

Postby Rex.Swain » August 28th, 2015, 2:40 pm

I am trying to use Eric's FolderBrowser function, in his CSEUTIL workspace, see User Contributed Files http://forum.apl2000.com/viewtopic.php?f=7&t=1017. It works. But I want to (1) change the caption of the "OK" button, and (2) provide a starting directory location. I thought these would be simple changes :-) But when I try to insert one or both of these lines into his script,
Code: Select all
    s,←⊂"            dialog.SetOKButtonLabel(""OK"");"
    s,←⊂"            dialog.SetDefaultFolder(""C:\\"");"

I get an error:
Code: Select all
CSE ERROR: (31,20): error CS1061: 'FolderBrowser.IFileOpenDialog' does not contain a definition for 'SetOKButtonLabel' and no extension method 'SetOKButtonLabel' accepting a first argument of type 'FolderBrowser.IFileOpenDialog' could be found (are you missing a using directive or an assembly reference?)

Anybody know how to get this to work?
Rex.Swain
 
Posts: 291
Joined: February 27th, 2007, 9:32 am
Location: Connecticut

Re: FolderBrowser via []CSE

Postby Ajay Askoolum » August 31st, 2015, 8:24 am

I have a solution. First, permit me to point out some issues:

1. APL+Win uses single and double quotes interchangeably. C# uses double quotes for strings and single quotes for char (single letter string). When using APL+Win to code C#, it is advisable to use single quotes for strings and double quotes for embedded strings. The existing FolderBrowser uses double quotes for strings and you need to use duplicated double quotes for embedded strings. I have changed this.

2. It is not advisable to SetDefaultFolder since this inherits the previously used path automatically; I have used SetFolder.

3. SetDefaultFolder and SetFolder have one argument of type IShellItem - not string as shown in your code; strings cannot be coerced into IShellItem.

4. The existing coding style of FolderBrowser does not permit you to use, say, the left-hand argument as the desired target folder name: Either re-factor the code OR use a variable to hold the desired target folder and have the code reference that variable.

Here's the code - I've broken the listing to highlight the changes & the line number of existing code beyond insertion points is different:
Code: Select all
    ∇ r←FolderBrowser hwnd;s;z;⎕cself
[1]   ⍝∇ r←FolderBrowser hwnd -- Allows to select a folder using a modern FolderBrowser dialog
[2]   ⍝∇ hwnd ←→ 0 or the parent APL+Win Form handle (hwnd property)
[3]   ⍝∇ r ←→ selected folder or " if Cancel
[4]   ⍝∇ Note:
[5]   ⍝∇ C# code borrowed from: [http://stackoverflow.com/questions/15368771/show-detailed-folder-browser-from-a-propertygrid] and then
       adapted
[6]   ⍝∇ Examples:
[7]   ⍝∇       FolderBrowser 0
[8]   ⍝∇ or:
[9]   ⍝∇       'ff'⎕wi'*Create' 'Form'
[10]  ⍝∇       FolderBrowser'ff'⎕wi'*hwnd'
[11]  ⍝∇ Eric Lescasse 3nov14
[12]  ⍝∇ Ajay Askoolum: 31 August 2015 - (a) Change 'Select Folder' to 'OK' (b) allow the selection of target folder
[13]
[14]  :if~(⊂'csefb')∊'#'⎕cse'instances'
[15]      ⎕cself←'csefb'⎕cse'Init' 'System' 'System.Windows.Forms' 'System.Runtime.InteropServices'
[16]      z←⎕cse'returnonerror'1
[17]      s←''
[18]      s,←⊂'using System;'
[19]      s,←⊂'using System.Runtime.InteropServices;'
[20]      s,←⊂'using System.Windows.Forms;'
[21]      s,←⊂''
[22]      s,←⊂'public class FolderBrowser'
[23]      s,←⊂'{'
[24]      s,←⊂'   public string DirectoryPath { get; set; }'
[25]      s,←⊂''
First Insertion snippet:
Code: Select all
[26]      s,←⊂'   private IShellItem GetShellItemForPath(string path)'
[27]      s,←⊂'       {'
[28]      s,←⊂'         IShellItem item = null;'
[29]      s,←⊂'         IntPtr pidl = IntPtr.Zero;'
[30]      s,←⊂'         uint zero = 0;'
[31]      s,←⊂'         if (0 <= SHILCreateFromPath(path, out pidl, ref zero))'
[32]      s,←⊂'            {'
[33]      s,←⊂'              if (0 <= SHCreateShellItem('
[34]      s,←⊂'                       IntPtr.Zero,' ⍝ //No parent specified .. alternatively, you can specify '#' ⎕wi 'hwndmain'
[35]      s,←⊂'                       IntPtr.Zero,'
[36]      s,←⊂'                       pidl,'
[37]      s,←⊂'                       out item))'
[38]      s,←⊂'                 {'
[39]      s,←⊂'                   return item;'
[40]      s,←⊂'                 }'
[41]      s,←⊂'             }'
[42]      s,←⊂'              throw new System.IO.FileNotFoundException();'
[43]      s,←⊂'            }'
Existing code:
Code: Select all
[44]      s,←⊂''
[45]      s,←⊂'    public int ShowDialog(int hwnd)'
[46]      s,←⊂'    {'
[47]      s,←⊂'        IntPtr hwndOwner;'
[48]      s,←⊂'        if (hwnd == 0)'
[49]      s,←⊂'           hwndOwner = IntPtr.Zero;'
[50]      s,←⊂'        else'
[51]      s,←⊂'           hwndOwner = (IntPtr)hwnd;'
[52]      s,←⊂''
[53]      s,←⊂'        IFileOpenDialog dialog = (IFileOpenDialog)new FileOpenDialog();'
Next insertion snippet:
Code: Select all
[54]      s,←⊂'        dialog.SetOkButtonLabel("OK");'
[55]      s,←⊂'        dialog.SetFolder(GetShellItemForPath(@"C:\Ajay\POWER SQL\COLUMNS"));'
The rest of the code:
Code: Select all
[56]      s,←⊂'        try'
[57]      s,←⊂'        {'
[58]      s,←⊂'            IShellItem item;'
[59]      s,←⊂'            if (!string.IsNullOrEmpty(DirectoryPath))'
[60]      s,←⊂'            {'
[61]      s,←⊂'                IntPtr idl;'
[62]      s,←⊂'                uint atts = 0;'
[63]      s,←⊂'                if (SHILCreateFromPath(DirectoryPath, out idl, ref atts) == 0)'
[64]      s,←⊂'                {'
[65]      s,←⊂'                    if (SHCreateShellItem(IntPtr.Zero, IntPtr.Zero, idl, out item) == 0)'
[66]      s,←⊂'                    {'
[67]      s,←⊂'                        dialog.SetFolder(item);'
[68]      s,←⊂'                    }'
[69]      s,←⊂'                }'
[70]      s,←⊂'            }'
[71]      s,←⊂'            dialog.SetOptions(FOS.FOS_PICKFOLDERS ∣ FOS.FOS_FORCEFILESYSTEM);'
[72]      s,←⊂'            uint hr = dialog.Show(hwndOwner);'
[73]      s,←⊂'            if (hr == ERROR_CANCELLED)'
[74]      s,←⊂'                return (int)DialogResult.Cancel;'
[75]      s,←⊂''
[76]      s,←⊂'            if (hr != 0)'
[77]      s,←⊂'                return (int)DialogResult.Abort;'
[78]      s,←⊂''
[79]      s,←⊂'            dialog.GetResult(out item);'
[80]      s,←⊂'            string path;'
[81]      s,←⊂'            item.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out path);'
[82]      s,←⊂'            DirectoryPath = path;'
[83]      s,←⊂'            return (int)DialogResult.OK;'
[84]      s,←⊂'        }'
[85]      s,←⊂'        finally'
[86]      s,←⊂'        {'
[87]      s,←⊂'            Marshal.ReleaseComObject(dialog);'
[88]      s,←⊂'        }'
[89]      s,←⊂'    }'
[90]      s,←⊂''
[91]      s,←⊂'    [DllImport("shell32.dll")]'
[92]      s,←⊂'    private static extern int SHILCreateFromPath([MarshalAs(UnmanagedType.LPWStr)] string pszPath, out IntPtr ppIdl, ref
       uint rgflnOut);'
[93]      s,←⊂''
[94]      s,←⊂'    [DllImport("shell32.dll")]'
[95]      s,←⊂'    private static extern int SHCreateShellItem(IntPtr pidlParent, IntPtr psfParent, IntPtr pidl, out IShellItem ppsi);'
[96]      s,←⊂''
[97]      s,←⊂'    [DllImport("user32.dll")]'
[98]      s,←⊂'    private static extern IntPtr GetActiveWindow();'
[99]      s,←⊂''
[100]     s,←⊂'    private const uint ERROR_CANCELLED = 0x800704C7;'
[101]     s,←⊂''
[102]     s,←⊂'    [ComImport]'
[103]     s,←⊂'    [Guid("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7")]'
[104]     s,←⊂'    private class FileOpenDialog'
[105]     s,←⊂'    {'
[106]     s,←⊂'    }'
[107]     s,←⊂''
[108]     s,←⊂'    [ComImport]'
[109]     s,←⊂'    [Guid("42f85136-db7e-439c-85f1-e4075d135fc8")]'
[110]     s,←⊂'    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]'
[111]     s,←⊂'    private interface IFileOpenDialog'
[112]     s,←⊂'    {'
[113]     s,←⊂'        [PreserveSig]'
[114]     s,←⊂'        uint Show([In] IntPtr parent); // IModalWindow'
[115]     s,←⊂'        void SetFileTypes();  // not fully defined'
[116]     s,←⊂'        void SetFileTypeIndex([In] uint iFileType);'
[117]     s,←⊂'        void GetFileTypeIndex(out uint piFileType);'
[118]     s,←⊂'        void Advise(); // not fully defined'
[119]     s,←⊂'        void Unadvise();'
[120]     s,←⊂'        void SetOptions([In] FOS fos);'
[121]     s,←⊂'        void GetOptions(out FOS pfos);'
[122]     s,←⊂'        void SetDefaultFolder(IShellItem psi);'
[123]     s,←⊂'        void SetFolder(IShellItem psi);'
[124]     s,←⊂'        void GetFolder(out IShellItem ppsi);'
[125]     s,←⊂'        void GetCurrentSelection(out IShellItem ppsi);'
[126]     s,←⊂'        void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName);'
[127]     s,←⊂'        void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);'
[128]     s,←⊂'        void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle);'
[129]     s,←⊂'        void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText);'
[130]     s,←⊂'        void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);'
[131]     s,←⊂'        void GetResult(out IShellItem ppsi);'
[132]     s,←⊂'        void AddPlace(IShellItem psi, int alignment);'
[133]     s,←⊂'        void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);'
[134]     s,←⊂'        void Close(int hr);'
[135]     s,←⊂'        void SetClientGuid();  // not fully defined'
[136]     s,←⊂'        void ClearClientData();'
[137]     s,←⊂'        void SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter);'
[138]     s,←⊂'        void GetResults([MarshalAs(UnmanagedType.Interface)] out IntPtr ppenum); // not fully defined'
[139]     s,←⊂'        void GetSelectedItems([MarshalAs(UnmanagedType.Interface)] out IntPtr ppsai); // not fully defined'
[140]     s,←⊂'    }'
[141]     s,←⊂''
[142]     s,←⊂'    [ComImport]'
[143]     s,←⊂'    [Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")]'
[144]     s,←⊂'    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]'
[145]     s,←⊂'    private interface IShellItem'
[146]     s,←⊂'    {'
[147]     s,←⊂'        void BindToHandler(); // not fully defined'
[148]     s,←⊂'        void GetParent(); // not fully defined'
[149]     s,←⊂'        void GetDisplayName([In] SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);'
[150]     s,←⊂'        void GetAttributes();  // not fully defined'
[151]     s,←⊂'        void Compare();  // not fully defined'
[152]     s,←⊂'    }'
[153]     s,←⊂''
[154]     s,←⊂'    private enum SIGDN : uint'
[155]     s,←⊂'    {'
[156]     s,←⊂'        SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000,'
[157]     s,←⊂'        SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,'
[158]     s,←⊂'        SIGDN_FILESYSPATH = 0x80058000,'
[159]     s,←⊂'        SIGDN_NORMALDISPLAY = 0,'
[160]     s,←⊂'        SIGDN_PARENTRELATIVE = 0x80080001,'
[161]     s,←⊂'        SIGDN_PARENTRELATIVEEDITING = 0x80031001,'
[162]     s,←⊂'        SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001,'
[163]     s,←⊂'        SIGDN_PARENTRELATIVEPARSING = 0x80018001,'
[164]     s,←⊂'        SIGDN_URL = 0x80068000'
[165]     s,←⊂'    }'
[166]     s,←⊂''
[167]     s,←⊂'    [Flags]'
[168]     s,←⊂'    private enum FOS'
[169]     s,←⊂'    {'
[170]     s,←⊂'        FOS_ALLNONSTORAGEITEMS = 0x80,'
[171]     s,←⊂'        FOS_ALLOWMULTISELECT = 0x200,'
[172]     s,←⊂'        FOS_CREATEPROMPT = 0x2000,'
[173]     s,←⊂'        FOS_DEFAULTNOMINIMODE = 0x20000000,'
[174]     s,←⊂'        FOS_DONTADDTORECENT = 0x2000000,'
[175]     s,←⊂'        FOS_FILEMUSTEXIST = 0x1000,'
[176]     s,←⊂'        FOS_FORCEFILESYSTEM = 0x40,'
[177]     s,←⊂'        FOS_FORCESHOWHIDDEN = 0x10000000,'
[178]     s,←⊂'        FOS_HIDEMRUPLACES = 0x20000,'
[179]     s,←⊂'        FOS_HIDEPINNEDPLACES = 0x40000,'
[180]     s,←⊂'        FOS_NOCHANGEDIR = 8,'
[181]     s,←⊂'        FOS_NODEREFERENCELINKS = 0x100000,'
[182]     s,←⊂'        FOS_NOREADONLYRETURN = 0x8000,'
[183]     s,←⊂'        FOS_NOTESTFILECREATE = 0x10000,'
[184]     s,←⊂'        FOS_NOVALIDATE = 0x100,'
[185]     s,←⊂'        FOS_OVERWRITEPROMPT = 2,'
[186]     s,←⊂'        FOS_PATHMUSTEXIST = 0x800,'
[187]     s,←⊂'        FOS_PICKFOLDERS = 0x20,'
[188]     s,←⊂'        FOS_SHAREAWARE = 0x4000,'
[189]     s,←⊂'        FOS_STRICTFILETYPES = 4'
[190]     s,←⊂'    }'
[191]     s,←⊂'}'
[192]     s,←⊂''
[193]     z←⎕cse'Exec'(⊃s)
[194] :endif
[195] z←⎕cse'ExecStmt' 'FolderBrowser fb = new FolderBrowser();'
[196] z←⎕cse'ExecStmt' 'int result = fb.ShowDialog({0});'hwnd
[197] r←⎕cse'GetValue' 'fb.DirectoryPath'
    ∇
Here's the result:
Attachments
folderbrowser.png
folderbrowser.png (55.67 KiB) Viewed 18127 times
Ajay Askoolum
 
Posts: 884
Joined: February 22nd, 2007, 2:16 am
Location: United Kingdom

Re: FolderBrowser via []CSE

Postby Rex.Swain » August 31st, 2015, 11:37 am

Your function works perfectly, Ajay.

You did not mention one of the mistakes I made, which was to use dialog.SetOKButtonLabel when I should have used dialog.SetOkButtonLabel. What a difference a letter can make!

Thank you VERY much for your help.
Rex.Swain
 
Posts: 291
Joined: February 27th, 2007, 9:32 am
Location: Connecticut

Re: FolderBrowser via []CSE

Postby Ajay Askoolum » August 31st, 2015, 12:06 pm

Hi Rex, thank you for confirming that it works for you.

It is really odd that you should mention the mistake! What you can read is what I posted on the second attempt. First time round, Internet Explorer froze when I was ready to click Submit. Two things failed to get into the version posted, namely, (i) that it is Ok and not OK and (ii) that I have recreated your error. The latter is very important for me in that it provides valuable insight into the problem and, in a perverse sort of way, leads to the solution.
Ajay Askoolum
 
Posts: 884
Joined: February 22nd, 2007, 2:16 am
Location: United Kingdom


Return to APL+Win & The C# Script Engine

Who is online

Users browsing this forum: No registered users and 18 guests

cron