Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Folder Browser Dialog for LISP

  1. #1
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,106
    Login to Give a bone
    0

    Default Folder Browser Dialog for LISP

    Hey Group,

    One function that is exposed in the shell.application is browseforfolder.

    Code:
    ; LISP syntax (browseforfolder "Select Folder" "C:\\acad")
    (defun BrowseForFolder (strMessage 
                             strRootFolder 
                             / 
                             lstObjects 
                             objShellApp 
                             objFolder 
                             objParentFolder 
                             strPath
                            )
     (and
      (setq objShellApp (vla-getInterfaceObject 
                         (vlax-get-acad-object) 
                         "Shell.Application" 
                        )
      )  
      (setq lstObjects (list objShellApp))
      (setq objFolder   (vlax-invoke objShellApp
                                    'BrowseForFolder  
                                    0
                                    strMessage
                                    0
                                    strRootFolder
                       )
      )
      (setq lstObjects (cons objFolder lstObjects))
      (setq strTitle          (vlax-get    objFolder       "Title"))
      (setq objParentFolder   (vlax-get    objFolder       'ParentFolder))
      (setq lstObjects (cons objParentFolder lstObjects))
      (setq strPath (vlax-get (vlax-invoke objParentFolder "Parsename" strTitle) "Path"))
     )
     (mapcar 'vlax-release-object lstObjects)
     strPath
    )
    But it does not allow you to pre select a selectedfolder.

    .NET has a browsefolderdialog that gives you more options including the ability to selectfolder.

    See next post.
    Last edited by peter; 2014-02-11 at 07:10 AM.
    AutomateCAD

  2. #2
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,106
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    This is the code.

    It has several options for the lisp function and you may want to modify it to add maybe the root folder etc...

    You can view its functionality on Youtube to see if is something you like.

    http://www.youtube.com/watch?v=Ug0k5...ature=youtu.be

    Code:
    Imports Autodesk.AutoCAD.Runtime
    Imports Autodesk.AutoCAD.DatabaseServices
    Imports System.Windows.Forms
    ''' <summary>
    ''' Folder Class to create a LISP Function to display the Folder Browser Dialog
    ''' In the System.Windows.Forms Class 
    ''' </summary>
    
    Public Class FolderClass
        ''' <summary>
        ''' LISP Function to display the Folder Browser Dialog
        ''' </summary>
        ''' <param name="rbfArguments"></param>
        ''' 
        ''' <remarks>LISP Syntax 
        ''' (folder)                           Default Selected Path is C:\\
        ''' (folder "C:\\")                    Sets the Selected Path to C:\\
        ''' (folder "C:\\" "Select Folder")    Sets Description to "Select Folder"
        ''' (folder "C:\\" "Select Folder" T)  Displays New Folder Button 
        ''' </remarks>
    
        <LispFunction("Folder")> _
        Public Function Folder(ByVal rbfArguments As ResultBuffer)
    
            Try
                If rbfArguments Is Nothing Then Return Folder("C:\")
    
                Dim arrArguments As TypedValue() = rbfArguments.AsArray()
    
                Select Case arrArguments.Length
                    Case 0
                        Return Folder("C:\")
                    Case 1
                        Return Folder(arrArguments(0).Value.ToString)
                    Case 2
                        Return Folder(arrArguments(0).Value.ToString, arrArguments(1).Value.ToString)
                    Case 3
                        Return Folder(arrArguments(0).Value.ToString, arrArguments(1).Value.ToString, True)
                End Select
    
            Catch ex As System.Exception
    
            End Try
            Return Nothing
        End Function
        ''' <summary>
        ''' .NET Function to display Folder Browser Dialog
        ''' </summary>
        ''' <param name="strSelectedPath"></param>
        ''' <param name="strDescription"></param>
        ''' <param name="blnNewFolderShow"></param>
        ''' <returns>Selected folder as string</returns>
    
        Public Function Folder(Optional ByVal strSelectedPath As String = "", _
                               Optional ByVal strDescription As String = "", _
                               Optional ByVal blnNewFolderShow As Boolean = False)
            Try
                If strSelectedPath IsNot Nothing Then
    
                    Dim folderBrowserDialog As New FolderBrowserDialog
    
                    folderBrowserDialog.RootFolder = Environment.SpecialFolder.MyComputer
    
                    folderBrowserDialog.SelectedPath = strSelectedPath
    
                    folderBrowserDialog.Description = strDescription
    
                    folderBrowserDialog.ShowNewFolderButton = blnNewFolderShow
    
                    folderBrowserDialog.ShowDialog()
    
                    Return folderBrowserDialog.SelectedPath
    
                End If
            Catch ex As System.Exception
    
            End Try
            Return Nothing
        End Function
    
    End Class
    AutomateCAD

  3. #3
    Administrator rkmcswain's Avatar
    Join Date
    2004-09
    Location
    Earth
    Posts
    9,803
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    Quote Originally Posted by peter View Post
    Hey Group,

    One function that is exposed in the shell.application is browseforfolder.
    Very nice. Thanks.
    R.K. McSwain | CAD Panacea |

  4. #4
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    Quote Originally Posted by peter View Post
    Hey Group,

    One function that is exposed in the shell.application is browseforfolder.
    I too am a fan of BrowseForFolder... My old BatchFindSurface routine for Civil 3D comes to mind for this specific topic, and includes some other goodies.

    Cheers
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  5. #5
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    BTW, Shell.Application (an external object) is never released.
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  6. #6
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    Here's a slightly different adaptation of the LISP code posted above that may prove useful... Please note the allowed parameter combinations shown in the commented examples:

    Code:
    (vl-load-com)
    
    (defun _BrowseForFolder	(msg path / *error* acApp oShell oFolder)
      ;; Examples:
      ;; (_BrowseForFolder "Select a Folder" nil)
      ;; (_BrowseForFolder nil nil)
      ;; (_BrowseForFolder nil "C:\\users")
      (defun *error* (msg)
        (if	oShell (vlax-release-object oShell))
        (cond ((not msg))							; Normal exit
    	  ((member msg '("Function cancelled" "quit / exit abort")))	; <esc> or (quit)
    	  ((princ (strcat "\n** Error: " msg " ** ")))			; Fatal error, display it
        )
        (if	oFolder path nil)
      )
    
      (and
        (or
          (and (= 'STR (type path)) (findfile path))
          (setq path (+ 1 64 256))
        )
        (or (= 'STR (type msg)) (setq msg "Select a Folder to Search"))
        (setq acApp (vlax-get-acad-object))
        (setq oShell (vla-getinterfaceobject acApp "Shell.Application"))
        (setq oFolder
    	   (vlax-invoke
    	     oShell
    	     'BrowseForFolder
    	     (vla-get-hwnd acApp)
    	     msg
    	     0
    	     path
    	   )
        )
        (setq path (vlax-get-property
    		 (vlax-get-property oFolder 'Self)
    		 'Path
    	       )
        )
      )
      (*error* nil)
    )
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  7. #7
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,106
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    Quote Originally Posted by BlackBox View Post
    BTW, Shell.Application (an external object) is never released.
    I have thought about that, in my original code I had the release expressions, but when I checked, because of the localized variable, LISP releases it automatically.

    I could never find any documentation on whether the release statement is or is not required for a localized variable.

    Do you know of any?

    Peter
    AutomateCAD

  8. #8
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    Quote Originally Posted by peter View Post
    I have thought about that, in my original code I had the release expressions, but when I checked, because of the localized variable, LISP releases it automatically.
    As I understand it.... While localisation clears the variable (symbol) value from being accessed once the Defun's scope has ended, this unfortunately does not account for releasing the object instance itself, which could result in multiple instances lingering for repeated code, and can cause other application, or even OS issues down the line.

    This principle applies to any external object, be it an AutoCAD-based object like the legacy Land Desktop (external) Database, today's Civil 3D COM Objects, or Shell.Application Object, Scripting.FileSystemObject Object, and ADsSecurityUtility Object, etc. as some other examples.



    Quote Originally Posted by peter View Post
    I could never find any documentation on whether the release statement is or is not required for a localized variable.

    Do you know of any?
    Especially if you're using 2012-2013 the ActiveX documentation is a bit cumbersome to use, IMO. 2014 is a little better, but you may want to install the offline help depending on bandwidth limitation, etc.

    Straight from the ActiveX Developer Documentation within VLIDE:

    vlax-Release-Object

    When an AutoLISP routine no longer uses an object outside AutoCAD, such as a Microsoft Excel object, call the (vlax-release-object) function to make sure that the associated application closes properly. Objects released with (vlax-release-object...) may not be released immediately. The actual release may not happen until the next automatic garbage collection occurs.

    ...
    HTH
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  9. #9
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,106
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    I added them back into the example at the top.

    Although the thread was more about how to do that with .net and not with the shell application.

    p=
    AutomateCAD

  10. #10
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,714
    Login to Give a bone
    0

    Default Re: Folder Browser Dialog for LISP

    Quote Originally Posted by peter View Post
    I added them back into the example at the top.
    What happens in the event of an error?

    Quote Originally Posted by peter View Post
    Although the thread was more about how to do that with .net and not with the shell application.
    Fair enough; here's an alternative that provides some native 'invalid argument' handling:

    Code:
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.DatabaseServices;
    using Autodesk.AutoCAD.Runtime;
    
    using acApp = Autodesk.AutoCAD.ApplicationServices.Application;
    
    using System;
    using System.IO;
    using System.Windows.Forms;
    
    [assembly: CommandClass(typeof(BlackBox.AutoCAD.FolderBrowser.Commands))]
    
    namespace BlackBox.AutoCAD.FolderBrowser
    {
        public class Commands
        {
            private bool showNewFolderButton;
            private DocumentCollection acDocs = acApp.DocumentManager;
            private string selectedPath;
            private string description;
    
            private object Browse()
            {
                FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
                folderBrowserDialog.Description = description;
                folderBrowserDialog.RootFolder = Environment.SpecialFolder.MyComputer;
                folderBrowserDialog.SelectedPath = selectedPath;
                folderBrowserDialog.ShowNewFolderButton = showNewFolderButton;
    
                if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
                    return null;
    
                return folderBrowserDialog.SelectedPath;
            }
            [LispFunction("FolderBrowser")]
            public object FolderBrowser(ResultBuffer resbuf)
            {
                showNewFolderButton = false;
                selectedPath = "C:\\";
                description = "";
                
                try
                {
                    if (resbuf == null)
                        return Browse();
    
                    TypedValue[] args = resbuf.AsArray();
                    int i = args.Length;
    
                    if (args[0].TypeCode != (int)LispDataType.Text)
                        throw new ArgumentTypeException("stringp", args[0]);
    
                    selectedPath = (string)args[0].Value;
    
                    if (!Directory.Exists(selectedPath))
                        throw new DirectoryDoesNotExistException();
    
                    if (i >= 2)
                    {
                        if (args[1].TypeCode != (int)LispDataType.Text)
                            throw new ArgumentTypeException("stringp", args[1]);
    
                        description = (string)args[1].Value;
                    }
    
                    if (i == 3 && args[2].TypeCode != (int)LispDataType.Nil)
                        showNewFolderButton = true;
    
                    return Browse();
                }
                catch (LispException ex)
                {
                    acDocs.MdiActiveDocument.Editor.WriteMessage(
                        "\n; error: LispException: " + ex.Message + "\n");
    
                    return null;
                }
                catch (System.Exception ex)
                {
                    acDocs.MdiActiveDocument.Editor.WriteMessage(
                        "\n; error: System.Exception: " + ex.Message + "\n");
    
                    return null;
                }
            }
        }
    
        /// <summary>
        /// Special thanks to Gile for his LispException classes:
        /// </summary>
        class LispException : System.Exception
        {
            public LispException(string msg) : base(msg) { }
        }
        class TooFewArgsException : LispException
        {
            public TooFewArgsException() : base("too few arguments") { }
        }
        class TooManyArgsException : LispException
        {
            public TooManyArgsException() : base("too many arguments") { }
        }
        class ArgumentTypeException : LispException
        {
            public ArgumentTypeException(string s, TypedValue tv)
                : base(string.Format(
               "invalid argument type: {0}: {1}",
               s, tv.TypeCode == (int)LispDataType.Nil ? "nil" : tv.Value))
            { }
        }
        // Added by BlackBox 
        class DirectoryDoesNotExistException : LispException
        {
            public DirectoryDoesNotExistException() : base("directory does not exist") { }
        }
    }
    Cheers
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

Page 1 of 2 12 LastLast

Similar Threads

  1. File Multi Selection Dialog (and Folder Select)
    By peter in forum Bridging the Gap: LISP -> .NET -> LISP
    Replies: 1
    Last Post: 2014-02-18, 04:46 PM
  2. 2013: New Folder from dialog
    By dgodfather in forum AutoCAD LT - General
    Replies: 8
    Last Post: 2013-01-16, 09:39 PM
  3. allow floating origin folder in the browser bar
    By Wish List System in forum Inventor Wish List
    Replies: 0
    Last Post: 2011-11-18, 10:05 AM
  4. Folder Dialog Option
    By bdthomas02 in forum VBA/COM Interop
    Replies: 3
    Last Post: 2008-07-22, 07:44 PM
  5. Open File Dialog Folder Addition
    By barathd in forum Revit Architecture - Tips & Tricks
    Replies: 0
    Last Post: 2005-02-07, 04:44 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •