Explorer Style of the Dialog generated with the GetOpenFileName Windows API

Posted on 2011-05-13
Last Modified: 2012-06-22
Attached is an image of my question.

The left hand image is what my code below generates.
The right hand image is what my PC shows when I open a dialog manually.

Can I make the right hand one with the GetOpenFileName Windows API?

(I have added this to the "C" zone as I am guessing that they will have an idea here, even though I am using Kindergarten Code (VBA))

Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias _
                        "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
Private Declare Function GetVersionEx Lib "kernel32" _
                        Alias "GetVersionExA" (lpVersionInformation As Any) As Long

Private Declare Function FindWindowEx Lib "user32" Alias _
            "FindWindowExA" (ByVal hWndParent As Long, _
                            ByVal hWndChildAfter As Long, _
                            ByVal lpClassName As String, _
                            ByVal lpWindowName As String) As Long

Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Function SendMessage Lib "user32" _
                         Alias "SendMessageA" _
                        (ByVal hwnd As Long, _
                         ByVal wMsg As Long, _
                         ByVal wParam As Long, _
                         lParam As Any) As Long

'var for exposed property
Private m_lvInitialView As Long

'windows messages & notifications etc
Private Const WM_COMMAND = &H111
Private Const WM_NOTIFY As Long = &H4E&
Private Const WM_INITDIALOG As Long = &H110
Private Const CDN_FIRST As Long = -601
Private Const CDN_INITDONE As Long = (CDN_FIRST - &H0&)
Private Const MAX_PATH As Long = 260

'openfilename constants
Private Const OFN_ENABLESIZING As Long = &H800000
Private Const OFN_EX_NOPLACESBAR As Long = &H1

Private Const OFN_ALLOWMULTISELECT As Long = &H200
Private Const OFN_CREATEPROMPT As Long = &H2000
Private Const OFN_ENABLEHOOK As Long = &H20
Private Const OFN_ENABLETEMPLATE As Long = &H40
Private Const OFN_EXPLORER As Long = &H80000
Private Const OFN_EXTENSIONDIFFERENT As Long = &H400
Private Const OFN_FILEMUSTEXIST As Long = &H1000
Private Const OFN_HIDEREADONLY As Long = &H4
Private Const OFN_LONGNAMES As Long = &H200000
Private Const OFN_NOCHANGEDIR As Long = &H8
Private Const OFN_NODEREFERENCELINKS As Long = &H100000
Private Const OFN_NOLONGNAMES As Long = &H40000
Private Const OFN_NONETWORKBUTTON As Long = &H20000
Private Const OFN_NOREADONLYRETURN As Long = &H8000& 'see comments
Private Const OFN_NOTESTFILECREATE As Long = &H10000
Private Const OFN_NOVALIDATE As Long = &H100
Private Const OFN_OVERWRITEPROMPT As Long = &H2
Private Const OFN_PATHMUSTEXIST As Long = &H800
Private Const OFN_READONLY As Long = &H1
Private Const OFN_SHAREAWARE As Long = &H4000
Private Const OFN_SHAREFALLTHROUGH As Long = 2
Private Const OFN_SHAREWARN As Long = 0
Private Const OFN_SHARENOWARN As Long = 1
Private Const OFN_SHOWHELP As Long = &H10
Private Const OFS_MAXPATHNAME As Long = 260

Private Const SHVIEW_ICON As Long = &H7029
Private Const SHVIEW_LIST As Long = &H702B
Private Const SHVIEW_REPORT As Long = &H702C
Private Const SHVIEW_THUMBNAIL As Long = &H702D
Private Const SHVIEW_TILE As Long = &H702E

Private Const OSVEX_LENGTH As Long = 88

  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
  'fnHook As Long
  lpTemplateName As String
End Type

Private Property Let OFN_SetInitialView(ByVal initview As Long)

   m_lvInitialView = initview

End Property

Private Function OFNHookProc(ByVal hwnd As Long, _
                            ByVal uMsg As Long, _
                            ByVal wParam As Long, _
                            ByVal lParam As Long) As Long

   Dim hWndParent As Long
   Dim hwndLv As Long
   Static bLvSetupDone As Boolean

   Select Case uMsg
        'Initdialog is set when the dialog
        'has been created and is ready to
        'be displayed, so set our flag
        'to prevent re-executing the code
        'in the wm_notify message. This is
        'required as the dialog receives a
        'number of WM_NOTIFY messages throughout
        'the life of the dialog. If this is not
        'done, and the user chooses a different
        'view, on the next WM_NOTIFY message
        'the listview would be reset to the
        'initial view, probably ticking off
        'the user. The variable is declared
        'static to preserve values between
        'calls; it will be automatically reset
        'on subsequent showing of the dialog.
         bLvSetupDone = False

        'other WM_INITDIALOG code here, such
        'as caption or button changing, or
        'centering the dialog.

      Case WM_NOTIFY

            If bLvSetupDone = False Then

             'hwnd is the handle to the dialog
             'hwndParent is the handle to the common control
             'hwndLv is the handle to the listview itself
               hWndParent = GetParent(hwnd)
               hwndLv = FindWindowEx(hWndParent, 0, "SHELLDLL_DefView", vbNullChar)

               If hwndLv > 0 Then
                  Call SendMessage(hwndLv, WM_COMMAND, ByVal m_lvInitialView, ByVal 0&)

                 'since we found the lv hwnd, assume the
                 'command was received and set the flag
                 'to prevent recalling this routine
                  bLvSetupDone = True
               End If  'hwndLv

            End If  'bLvSetupDone

         Case Else

   End Select

End Function

Public Function dabFileChooser(ByVal dbTitle As String, ByVal dbFilter As String, _
                                ByVal dbViewType As String, ByVal dbStartPath As String, _
                                ByVal dbMultiSelect As Boolean, ByRef obj_dbObject As DBDialog) As Boolean
On Error GoTo Err_dabFileChooser

Dim aFiles() As String
Dim aTemp() As String
Dim tempPath As String
Dim tempFileName As String

Dim dbflags As String
Dim buff As String

If dbMultiSelect Then
End If

Dim lReturn As Long
Dim sFilter As String

OFN_SetInitialView = dbViewType

'OpenFile.lStructSize = Len(OpenFile)
OpenFile.lStructSize = OSVEX_LENGTH
OpenFile.hwndOwner = ACCESS.hWndAccessApp
OpenFile.hInstance = ACCESS.hWndAccessApp
'sFilter = "Excel Files" & vbNullChar & "*.xls;*.xlsx" & vbNullChar & _
          "All Files" & vbNullChar & "*.*" & vbNullChar & vbNullChar

sFilter = dbFilter

OpenFile.lpstrFilter = sFilter
OpenFile.nFilterIndex = 1
OpenFile.lpstrFile = String(257, 0)
OpenFile.nMaxFile = Len(OpenFile.lpstrFile) - 1
OpenFile.lpstrFileTitle = OpenFile.lpstrFile
OpenFile.nMaxFileTitle = OpenFile.nMaxFile
OpenFile.lpstrInitialDir = dbStartPath
OpenFile.lpstrTitle = dbTitle
OpenFile.flags = dbflags
OpenFile.lpfnHook = FARPROC(AddressOf OFNHookProc)


lReturn = GetOpenFileName(OpenFile)

'there is someting there
If lReturn <> 0 Then

    dabFileChooser = True

    If dbMultiSelect Then
        'trim all the nulls from the end
        buff = TrimNull(OpenFile.lpstrFile)
        'split all values and add to the class  not being used now.
        'aTemp = Split(buff, Chr$(0))
        'obj_dbObject.FileNames = aTemp
        tempPath = StripDelimitedItem(buff, vbNullChar)
        obj_dbObject.MainPath = tempPath
        Do While Len(buff) > 3
            tempFileName = StripDelimitedItem(buff, vbNullChar)
            Call obj_dbObject.FileNamesAdd(tempFileName)
            Call obj_dbObject.FullFilePathsAdd(tempPath & tempFileName)

        dabFileChooser = True
        obj_dbObject.FullFilePath = Trim(OpenFile.lpstrFile)
    End If


    dabFileChooser = False

End If

    Exit Function

    MsgBox Err.Number & " " & Err.Description & " dabFileChooser", vbCritical, "LuTTool Error"
    Resume Exit_dabFileChooser
End Function

Public Function FARPROC(pfn As Long) As Long

  'A dummy procedure that receives and returns
  'the return value of the AddressOf operator.

  'Obtain and set the address of the callback
  'This workaround is needed as you can't assign
  'AddressOf directly to a member of a user-
  'defined type, but you can assign it to another
  'long and use that (as returned here)

  FARPROC = pfn

End Function

Open in new window

Question by:darbid73
    LVL 119

    Expert Comment

    by:Rey Obrero
    try this simple command

    followhyperlink "C:\"
    LVL 19

    Author Comment

    Hi capricorn1

    That method shows the one on the right.  I did throw that into the API as the path, but it did not change anything.
    LVL 119

    Expert Comment

    by:Rey Obrero
    dim strPath
    strPath="C:\Documents and Settings"

    followhyperlink strPath

    should take you to the folder C:\Documents and Settings
    LVL 19

    Author Comment

    using that path with the MSAccess application method "followhyperlink" works fine yes.

    But I am not following you otherwise.
    LVL 56

    Expert Comment

    by:Jim Dettman (Microsoft MVP/ EE MVE)
    <<using that path with the MSAccess application method "followhyperlink" works fine yes.>>

      That gives him an explorer window, but it's not going to return a file name.

    <<The right hand image is what my PC shows when I open a dialog manually.>>

      I don't know any way of getting the explorer style window that your getting (not sure how your starting it) with the Windows common dialog call.


    LVL 19

    Author Comment

    <I don't know any way of getting the explorer style window that your getting ................ with the Windows common dialog call.>

    That was my conclusion before asking the question too.

    If that tool bar and the folder view could be added to the common dialog it would have to be a message in the OFNHookProc.

    <(not sure how your starting it)>

    I have tried to find out how the hell my Windows XP box is set up to get this manually but I am not sure how I did this.
    LVL 56

    Expert Comment

    by:Jim Dettman (Microsoft MVP/ EE MVE)
    <<If that tool bar and the folder view could be added to the common dialog it would have to be a message in the OFNHookProc.>>

      Actually I think it was the OFN_EXPLORER flag if I remember right.  But I just tried it and I get the same style dialog with that flag included or not.

      One other thing; I notice in your code that your using the flags property when setting that.  Should be OpenFlags.   Flags was left for compatibility with the old Active-x dialog control.  Don't think it will make a difference though.

    LVL 19

    Author Comment

    Yeh all the material I can find including ad MSDN says that this is the "new style", if you make the old style it is amazing. I have never see it before.  If you remove OFN_EXPLORER then you get a dinosaur.

    I am still of the opinion that while windows is building the view it needs "help" on how to do it. ie OFNHookProc but I just cannot find anything on it.
    LVL 56

    Accepted Solution


     I see what you mean now.  I found this:

      which describes what your talking about, but no examples.  I'm not sure how far you can go with customizing the dialog with the child window, but the style interface your looking for looks like it is not just a simple flag supplied to the open dialog, but rather something you would need to create.

      I'm trying to think when I've seen the style of interface your looking for as a result of doing an open file and I can't think of any.

    LVL 19

    Author Comment

    The only other idea I have is that one needs to use the OFN_ENABLETEMPLATE flag to create it.
    LVL 19

    Assisted Solution

    I am unable to work out why I have this kind of dialog and thus am unable to reproduce it with the Windows API.

    For anyone coming to this thread I think the key is to do it yourself with OFN_ENABLETEMPLATE which allows you to make your own template.

    LVL 19

    Author Closing Comment

    I dont think that we got an answer to my question, but I have a feeling there is no answer.  Certainly the solutions added helped me to make this conclusion.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Top 6 Sources for Identifying Threat Actor TTPs

    Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

    I originally created this report in Crystal Reports 2008 where there is an option to underlay sections. I initially came across the problem in Access Reports where I was unable to run my border lines down through the entire page as I was using the P…
    Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
    The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
    The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    12 Experts available now in Live!

    Get 1:1 Help Now