Windows Open Dialog

Discussion in 'AutoCAD' started by James Wedding, Mar 2, 2005.

  1. Do I need a full copy of VB to get access to Windows dialogs? I want to
    allow a user to pick a text file that I can then search through, but haven't
    been able to get the Windows reference to work correctly. I get a licensing
    error it seems.

    Thanks in advance.

    --
    James Wedding, P.E.
    Technology Manager &
    Associate
    Jones & Boyd, Inc.
    Dallas, TX
    XP/2 on P4-3.4/1G
    LDT2005SP1 & C3D2005SP1
     
    James Wedding, Mar 2, 2005
    #1
  2. James Wedding

    MP Guest

    the hip way is with the standard api calls
    one of the hundreds of versions floating around the web, this one by
    randall rath if i'm not mistaken
    a google search will turn up many more.
    (this is set up to be used in a class module)
    Option Explicit

    '//The Win32 API Functions///
    Private Declare Function GetSaveFileName Lib _
    "comdlg32.dll" Alias "GetSaveFileNameA" _
    (pOpenfilename As OPENFILENAME) As Long

    Private Declare Function GetOpenFileName Lib _
    "comdlg32.dll" Alias "GetOpenFileNameA" _
    (pOpenfilename As OPENFILENAME) As Long

    '//A few of the available Flags///
    Private Const OFN_HIDEREADONLY = &H4
    '//The Structure
    Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
    End Type

    Private lngHwnd As Long
    Private strFilter As String
    Private strTitle As String
    Private strDir As String
    Private blnHideReadOnly As Boolean

    Private Sub Class_Initialize()
    'Set default values when
    'class is first created
    strDir = CurDir
    strTitle = "Llamas Rule"
    strFilter = "All Files" _
    & Chr$(0) & "*.*" & Chr$(0)
    lngHwnd = &O0 'Desktop
    End Sub

    Public Property Let OwnerHwnd(WindowHandle As Long)
    '//FOR YOU TODO//
    'Use the API to validate this handle
    lngHwnd = WindowHandle
    'R14 users who just want to use this code:
    'Simple, don't set this property! the default
    'of &0 will work fine for most of yor needs
    End Property

    Public Property Get OwnerHwnd() As Long
    OwnerHwnd = lngHwnd
    End Property

    Public Property Let Title(Caption As String)
    'don't allow null strings
    If Not Caption = vbNullString Then
    strTitle = Caption
    End If
    End Property

    Public Property Get Title() As String
    Title = strTitle
    End Property

    Public Property Let Filter(ByVal FilterString As String)
    'Filters change the type of files that are
    'displayed in the dialog. I have designed this
    'validation to use the same filter format the
    'Common dialog OCX uses:
    '"All Files (*.*)|*.*"
    Dim intPos As Integer
    Do While InStr(FilterString, "|") > 0
    intPos = InStr(FilterString, "|")
    If intPos > 0 Then
    FilterString = Left$(FilterString, intPos - 1) _
    & Chr$(0) & Right$(FilterString, _
    Len(FilterString) - intPos)
    End If
    Loop
    If Right$(FilterString, 2) <> Chr$(0) & Chr$(0) Then
    FilterString = FilterString & Chr$(0)
    End If
    strFilter = FilterString
    End Property


    Public Property Get Filter() As String
    'Here we reverse the process and return
    'the Filter in the same format the it was
    'entered
    Dim intPos As Integer
    Dim strTemp As String
    strTemp = strFilter
    Do While InStr(strTemp, Chr$(0)) > 0
    intPos = InStr(strTemp, Chr$(0))
    If intPos > 0 Then
    strTemp = Left$(strTemp, intPos - 1) _
    & "|" & Right$(strTemp, _
    Len(strTemp) - intPos)
    End If
    Loop
    If Right$(strTemp, 1) = "|" Then
    strTemp = Left$(strTemp, Len(strTemp) - 1)
    End If
    Filter = strTemp
    End Property

    Public Property Let HideReadOnly(blnVal As Boolean)
    'Simple one
    blnHideReadOnly = blnVal
    End Property

    Public Property Get HideReadOnly() As Boolean
    HideReadOnly = blnHideReadOnly
    End Property

    '@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@
    ' Display and use the File open dialog
    '@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@
    Public Function ShowOpen() As String
    Dim strTemp As String
    Dim udtStruct As OPENFILENAME
    udtStruct.lStructSize = Len(udtStruct)
    'Use our private variable
    udtStruct.hwndOwner = lngHwnd
    'Use our private variable
    udtStruct.lpstrFilter = strFilter
    udtStruct.lpstrFile = Space$(254)
    udtStruct.nMaxFile = 255
    udtStruct.lpstrFileTitle = Space$(254)
    udtStruct.nMaxFileTitle = 255
    'Use our private variable
    udtStruct.lpstrInitialDir = strDir
    'Use our private variable
    udtStruct.lpstrTitle = strTitle
    'Ok, here we test our boolean to
    'set the flag
    If blnHideReadOnly Then
    udtStruct.flags = OFN_HIDEREADONLY
    Else
    udtStruct.flags = 0
    End If
    If GetOpenFileName(udtStruct) Then
    strTemp = (Trim(udtStruct.lpstrFile))
    ShowOpen = Mid(strTemp, 1, Len(strTemp) - 1)
    End If
    End Function

    '@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@
    ' Display and use the File Save dialog
    '@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@
    Public Function ShowSave() As String
    Dim strTemp As String
    Dim udtStruct As OPENFILENAME
    udtStruct.lStructSize = Len(udtStruct)
    'Use our private variable
    udtStruct.hwndOwner = lngHwnd
    'Use our private variable
    udtStruct.lpstrFilter = strFilter
    udtStruct.lpstrFile = Space$(254)
    udtStruct.nMaxFile = 255
    udtStruct.lpstrFileTitle = Space$(254)
    udtStruct.nMaxFileTitle = 255
    'Use our private variable
    udtStruct.lpstrInitialDir = strDir
    'Use our private variable
    udtStruct.lpstrTitle = strTitle
    'Ok, here we test our flag
    If blnHideReadOnly Then
    udtStruct.flags = OFN_HIDEREADONLY
    Else
    udtStruct.flags = 0
    End If
    If GetSaveFileName(udtStruct) Then
    strTemp = (Trim(udtStruct.lpstrFile))
    ShowSave = Mid(strTemp, 1, Len(strTemp) - 1)
    End If
    End Function
     
    MP, Mar 2, 2005
    #2
  3. Hi James,

    You aren't able to legally use the VB DLL in VBA, so even if you had it and
    could, it is not a good solution.

    I found Randall's code close enough to incomprehensible and gave up before
    succeeding in finding which variables he used to filter the displayed files,
    and the displayed filters.

    If you know the files are always in a fixed directory, it's very easy to use
    the DIR command based on your own filter into a list box to display the
    files from that directory.

    It's also possible to find dozens of alternatives on the web.


    --

    Regards,


    Laurie Comerford
    www.cadapps.com.au
     
    Laurie Comerford, Mar 2, 2005
    #3
  4. You need a full copy of VB to do any serious development,
    and expect it to be taken seriously by your peers :)
     
    Tony Tanzillo, Mar 2, 2005
    #4
  5. James Wedding

    Matt W Guest

    I like Frank O's CommonDialog class.
    Pretty straight-forward and I can post a copy of it if you'd like.
    It includes access to the Open and Save dialog boxes.
     
    Matt W, Mar 2, 2005
    #5
  6. James Wedding

    MP Guest


    Laurie,
    If you're talking about the code I posted last night....
    if you want to test it....
    1 start a new vba project
    2 insert a class module
    3 copy paste the code into that class module
    4 name the class module FileDialog
    5 paste the following code into the ThisDrawing module
    6 hit f5
    7 browse to a folder containing lisp files

    '---this is all the code you need to use the class file as posted----
    Sub LauriesFiles()
    Dim fd As FileDialog
    Set fd = New FileDialog
    fd.Title = "Lauries Files"
    fd.Filter = "Lisp Files (*.lsp)|*.lsp"
    fd.ShowOpen
    Set fd = Nothing
    End Sub
    '---end of code using filedialog class

    if you want to filter for other file types, change the line
    fd.Filter = "Lisp Files (*.lsp)|*.lsp"
    to
    fd.Filter = "Text Files (*.txt)|*.txt"
    or
    fd.Filter = "Dwg Files (*.dwg)|*.dwg"


    in fact you can ignore the title and filter and get it down to the minimum

    Sub LauriesFiles2()
    Dim fd As FileDialog
    Set fd = New FileDialog
    fd.ShowOpen
    Set fd = Nothing
    End Sub




    This is just my beginners understanding of api calls so forgive all
    mis-statements and omissions

    When you first start looking at api calls the amount of code there is
    overwhelming.
    The good thing about it is you're only going to put it in a class somewhere
    (encapsulate it) and then forget about it....
    Simply insert the class into project you want to use it in (not the best way
    to reuse code but the simplest to explain and generally for us
    "non-programmer autocad users" in our initial forrays into vba imho I think
    it's acceptable)
    Then in our actual project code we just use the class as in the above
    sample - whose code I think you will admit is fairly simple and uncluttered.
    Api calls can of course also go in bas files - just depends on what you're
    doing and the specifics of the project.
    In this case using a class simplifies the access to the title and filter
    settings - nothing more.

    In general all api calls will follow the format
    1 Declare SomeFunction (located in some windows file)
    2 Define Types required by SomeFunction
    3 Write BodyOfFunctionCall

    what makes it look confusing is that
    -Declare SomeFunction
    can take up two or three lines with word wrap

    -Define Types required by SomeFunction
    can take up many lines depending on which type we're talking about

    -Write BodyOfFunctionCall
    again can take up many lines depending

    so the total gob of code can run several pages just to define one stupid
    little function
    :)

    the beauty of them is that once all that dirty work is done
    (usually by two clicks of Ctl-C and Ctl-V)-not actually too hard once you
    get it down :)
    then using the function is as simple as

    Sub MyUsingSub()
    SomeFunction arg1, arg2..., argn
    End sub


    hth
    Mark
     
    MP, Mar 2, 2005
    #6
  7.  
    Paul Richardson, Mar 2, 2005
    #7
  8. You need a full copy of VB to do any serious development,
    so your saying we can be taken seriously
    with VB? Not just C? ;-) Did VB.Net entice
    you over form the darkside? 0-)
     
    Paul Richardson, Mar 2, 2005
    #8
  9. Glad to see you haven't grown any more likable over the years. Thanks for
    the input.

    --
    James Wedding, P.E.
    Technology Manager &
    Associate
    Jones & Boyd, Inc.
    Dallas, TX
    XP/2 on P4-3.4/1G
    LDT2005SP1 & C3D2005SP1
     
    James Wedding, Mar 2, 2005
    #9
  10. That would be great. I'm simply trying to let the user navigate to a file,
    nothing complicated. Thank you.

    --
    James Wedding, P.E.
    Technology Manager &
    Associate
    Jones & Boyd, Inc.
    Dallas, TX
    XP/2 on P4-3.4/1G
    LDT2005SP1 & C3D2005SP1
     
    James Wedding, Mar 2, 2005
    #10
  11. James Wedding

    VBA Guest

    James,

    Take a look at "AutoCAD 2004 VBA Programmers Reference" by Joe Sutphin. It
    has a chapter dedicated to the Windows API which may help address your
    issue.
     
    VBA, Mar 2, 2005
    #11
  12. Hi,

    Thanks for that.

    I was referring to code I got from Randall years ago. Whether it is the
    same as you posted, I don't know.

    The equivalent of the line "fd.Filter = "Lisp Files (*.lsp)|*.lsp"" was
    the one I couldn't get going.

    I would presume it can be extended to:

    fd.Filter = "Menu Files (*mnl,*.mnu.)|*.mnl,*,mnu"


    With your advice, next time I wish to do this, I'll revisit Randall's work.

    --


    Laurie Comerford
    CADApps
    www.cadapps.com.au
     
    Laurie Comerford, Mar 2, 2005
    #12
  13. I'm saying that Microsoft deliberately limits what you
    can do with VBA, mainly because it sells VB for $$$$.

    If you use the redistributable tools that come with
    VB, then yes, I think users of your software will take
    your work more seriously.

    The bigger question is what is the big deal about
    plopping down a few hundred bucks for something
    that has most of what you need?
     
    Tony Tanzillo, Mar 2, 2005
    #13
  14. just a joke;;-)
     
    Paul Richardson, Mar 4, 2005
    #14
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.