Visual Basic Common Dialog Routines
GetOpenFileName: File Open/Save Common Dialog API - Overview
     
Posted:   Friday December 27, 1996
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB4-32, Windows 95
Revised with:   VB6, Windows NT4
OS restrictions:   None
Author:   VBnet - Randy Birch
     
Related:   GetSaveFileName: File Save Common Dialog Basics
GetOpenFileName: File Open Common Dialog Basics
GetOpenFileName: File Dialog Centering using a Callback
GetOpenFileName: Advanced Dialog Centering using a Callback
GetOpenFileName: Set an Open/Save Dialog's Initial Listview View
GetOpenFileName: Customize File Open/Save Common Dialog Controls
     
 Prerequisites
  
None.

This page details the descriptions of Windows' GetOpenFileName and GetSaveFileName API methods. The related demo code pages show how to call the APIs, as well as demonstrating how to retrieve the constituent parts of the file string returned.

To access both of the file common dialogs the OPENFILENAME structure is used. Prior to Windows 2000 this UDT was 76 bytes long, with sTemplateName as the last member. With the introduction of Windows XP and the Shell version 5 common dialogs, the OPENFILENAME structure added three new members increasing the size of the UDT to 88 bytes:

Public Type OPENFILENAME
  nStructSize       As Long
  hWndOwner         As Long
  hInstance         As Long
  sFilter           As String
  sCustomFilter     As String
  nMaxCustFilter    As Long
  nFilterIndex      As Long
  sFile             As String
  nMaxFile          As Long
  sFileTitle        As String
  nMaxTitle         As Long
  sInitialDir       As String
  sDialogTitle      As String
  flags             As Long
  nFileOffset       As Integer
  nFileExtension    As Integer
  sDefFileExt       As String
  nCustData         As Long
  fnHook            As Long
  sTemplateName     As String
  pvReserved        As Long  'new in Windows 2000 and later
  dwReserved        As Long  'new in Windows 2000 and later
  flagsEx           As Long  'new in Windows 2000 and later
End Type

Many of the members in the type are recognizable from the similar properties exposed by the VB file common control. To assist in understanding the following code, a lengthy discussion of each member is below. Following that is a discussion on using this UDT in applications running on pre-Windows 2000 machines.

nStructSize is common among many Windows UDTs. As more features are added to Windows controls, the number of members of a structure often change. For example, the definition of the OPENFILENAME structure during Windows 9x through Windows NT4 did not contain the last three members. Windows 2000 and later use the three additional parameters added to the end of the type to provide additional functionality. This type is also required on Windows 2000 and later when utilizing a hook to maintain the places bar in the explorer style. By providing the UDT with a nStructSize member, the receiving API can determine which version of the structure is being used thus whether to ignore any members beyond the size passed. See below for a further discussion.

hWndOwner is also common, and specifies the window owner the dialog, and therefore receives messages from the control or its error messages.

hInstance - If the OFN_ENABLETEMPLATEHANDLE flag is set in the Flags member, hInstance is a handle to a memory object containing a dialog box template. If the OFN_ENABLETEMPLATE flag is set, hInstance is a handle to a module that contains a dialog box template named by the sTemplate member. If neither flag is set, this member is ignored. If the OFN_EXPLORER flag is set, the system uses the specified template to create a dialog box that is a child of the default Explorer-style dialog box. If the OFN_EXPLORER flag is not set, the system uses the template to create an old-style dialog box that replaces the default dialog box.

sFilter - buffer containing pairs of null-terminated filter strings. The last string in the buffer must be terminated by two NULL characters. The first string in each pair is a display string that describes the filter (for example, "Text Files"), and the second string specifies the filter pattern (for example, "*.TXT"). To specify multiple filter patterns for a single display string, use a semicolon to separate the patterns (for example, "*.TXT;*.DOC;*.BAK"). A pattern string can be a combination of valid file name characters and the asterisk (*) wildcard character. Do not include spaces in the pattern string. The system does not change the order of the filters. It displays them in the File Types combo box in the order specified in sFilter.

nFilterIndex specifies an index into the buffer pointed to by sFilter. The system uses the index value to obtain a pair of strings to use as the initial filter description and filter pattern for the dialog box. The first pair of strings has an index value of 1. When the user closes the dialog box, the system copies the index of the selected filter strings into this location.

sFile points to a buffer that contains a filename used to initialize the File Name edit control. The first character of this buffer must be vbNullChar if initialization is not necessary. When the GetOpenFileName or GetSaveFileName function returns, this buffer contains the drive designator, path, filename, and extension of the selected file(s). The demo code below passes "Untitled.bas" as the initial filename, along with a buffer of an additional 1024 chrs for the return selection.

sFileTitle points to a buffer that receives the file name and extension (without path information) of the selected file. If this member is vbNullChar, the function does not copy the file name.

Assuming a buffer is passed for both sFile and sFileTitle, the difference between the these two members can be seen when a multiple file selection dialog is used (flag OFN_ALLOWMULTISELECT). In a single selection, both sFile and sFileTitle return the same data. But when multiple files are selected, sFileTitle returns empty, while sFile contains a null-separated string containing the users selection (up to the max chrs passed in the sFile buffer).

nMaxFile - the size of the buffer pointed to by sFile. The buffer must be large enough to store the path and file name string or strings, including the terminating null character. GetOpenFileName and GetSaveFileName return False if the buffer is too small to contain the file selected information. The buffer should be at least 260 characters long.

nMaxTitle - the size, of the buffer pointed to by sFileTitle. This member is ignored if sFileTitle is vbNullChr.

sInitialDir is a pointer to a null terminated string that can specify the initial directory. The algorithm for selecting the initial directory varies on different platforms (taken from the MSDN).

  • Windows 2000/Windows XP:
  • If sFile contains a path, that path is the initial directory.
  • Otherwise, sInitialDir specifies the initial directory.
  • If sInitialDir is NULL and the current directory contains any files of the specified filter types, the initial directory is the current directory.
  • Otherwise, if the application has used an Open or Save As dialog box in the past, the path most recently used is selected as the initial directory. However, if an application is not run for a long time, its saved selected path will be discarded.
  • Otherwise, the initial directory is the personal files directory of the current user.
  • Otherwise, the initial directory is the Desktop folder
  • Windows 98:
  • sInitialDir specifies the initial directory.
  • If sInitialDir is NULL and sFile contains a path, that path is the initial directory.
  • Otherwise, if the current directory contains any files of the specified filter types, the initial directory is the current directory.
  • Otherwise, the initial directory is the personal files directory of the current user.
  • Earlier versions of Windows and Windows NT/ 2000:
  • sInitialDir specifies the initial directory.
  • If sInitialDir is NULL and sFile contains a path, that path is the initial directory.
  • Otherwise, the initial directory is the current directory.

flags - bit flags you can use to initialize the dialog box. When the dialog box returns, it sets these flags to indicate the user's input. This member can be a combination of the following flags (within the bounds of the target OS). This is an abbreviated version of the same listing in the MSDN:

Flag Meaning
OFN_ALLOWMULTISELECT Specifies that the File Name list box allows multiple selections.

If the user selects more than one file, the sFile buffer returns the path to the current directory followed by the file names of the selected files. The nFileOffset member is the offset, in bytes or characters, to the first file name, and the nFileExtension member is not used. For Explorer-style dialog boxes, the directory and file name strings are NULL separated, with an extra NULL character after the last file name. This format enables the Explorer-style dialog boxes to return long file names that include spaces.

OFN_CREATEPROMPT If the user specifies a file that does not exist, this flag causes the dialog box to prompt the user for permission to create the file. If the user chooses to create the file, the dialog box closes and the function returns the specified name; otherwise, the dialog box remains open. If you use this flag with the OFN_ALLOWMULTISELECT flag, the dialog box allows the user to specify only one nonexistent file.
OFN_ENABLETEMPLATE Indicates that the sTemplateName member is a pointer to the name of a dialog template resource in the module identified by the hInstance member.
OFN_ENABLETEMPLATEHANDLE Indicates that the hInstance member identifies a data block that contains a preloaded dialog box template. The system ignores the sTemplateName if this flag is specified.
OFN_EXPLORER Indicates that any customizations made to the Open or Save As dialog box use the new Explorer-style customization methods. By default, the Open and Save As dialog boxes use the Explorer-style user interface regardless of whether this flag is set. This flag is necessary only if you provide a hook procedure or custom template, or set the OFN_ALLOWMULTISELECT flag.
OFN_EXTENSIONDIFFERENT Specifies that the user typed a file name extension that differs from the extension specified by sDefFileExt. The function does not use this flag if sDefFileExt is NULL.
OFN_FILEMUSTEXIST Specifies that the user can type only names of existing files in the File Name entry field. If this flag is specified and the user enters an invalid name, the dialog box procedure displays a warning in a message box. If this flag is specified, the OFN_PATHMUSTEXIST flag is also used.
OFN_HIDEREADONLY Hides the Read Only check box.
OFN_LONGNAMES For old-style dialog boxes, this flag causes the dialog box to use long file names. If this flag is not specified, or if the OFN_ALLOWMULTISELECT flag is also set, old-style dialog boxes use short file names (8.3 format) for file names with spaces. Explorer-style dialog boxes ignore this flag and always display long file names.
OFN_NOCHANGEDIR Restores the current directory to its original value if the user changed the directory while searching for files.
OFN_NODEREFERENCELINKS Directs the dialog box to return the path and file name of the selected shortcut (.LNK) file. If this value is not specified, the dialog box returns the path and file name of the file referenced by the shortcut.
OFN_NOLONGNAMES For old-style dialog boxes, this flag causes the dialog box to use short file names (8.3 format). Explorer-style dialog boxes ignore this flag and always display long file names.
OFN_NONETWORKBUTTON Hides and disables the Network button.
OFN_NOREADONLYRETURN Specifies that the returned file does not have the Read Only check box selected and is not in a write-protected directory, Important: This value is define in the header files as &H8000, which unfortunately is -32768 in VB.  The correct value required 32768, so an ampersand (&) must be appended to this value to force VB to cast this to a Long.  This is even true if the constant is defined As Long in the declare.  If you use this constant in your apps and the file dialog either does not appear or the app crashes without an error, check this value.
OFN_NOTESTFILECREATE Specifies that the file is not created before the dialog box is closed. This flag should be specified if the application saves the file on a create-non-modify network share. When an application specifies this flag, the library does not check for write protection, a full disk, an open drive door, or network protection. Applications using this flag must perform file operations carefully, because a file cannot be reopened once it is closed.
OFN_NOVALIDATE Specifies that the common dialog boxes allow invalid characters in the returned file name. Typically, the calling application uses a hook procedure that checks the file name by using the FILEOKSTRING message. If the text box in the edit control is empty or contains nothing but spaces, the lists of files and directories are updated. If the text box in the edit control contains anything else, nFileOffset and nFileExtension are set to values generated by parsing the text. No default extension is added to the text, nor is text copied to the buffer specified by sFileTitle.

If the value specified by nFileOffset is less than zero, the file name is invalid. Otherwise, the file name is valid, and nFileExtension and nFileOffset can be used as if the OFN_NOVALIDATE flag had not been specified.

OFN_OVERWRITEPROMPT Causes the Save As dialog box to generate a message box if the selected file already exists. The user must confirm whether to overwrite the file.
OFN_PATHMUSTEXIST Specifies that the user can type only valid paths and file names. If this flag is used and the user types an invalid path and file name in the File Name entry field, the dialog box function displays a warning in a message box.
OFN_READONLY Causes the Read Only check box to be selected initially when the dialog box is created. This flag indicates the state of the Read Only check box when the dialog box is closed.
OFN_SHAREAWARE Specifies that if a call to the OpenFile function fails because of a network sharing violation, the error is ignored and the dialog box returns the selected file name. If this flag is not set, the dialog box notifies your hook procedure when a network sharing violation occurs for the file name specified by the user. If you set the OFN_EXPLORER flag, the dialog box sends the CDN_SHAREVIOLATION message to the hook procedure. If you do not set OFN_EXPLORER, the dialog box sends the SHAREVISTRING registered message to the hook procedure.
OFN_SHAREFALLTHROUGH Used with a SHAREVISTRING notification sent to a hook procedure: Accept the file name
OFN_SHAREWARN Used with a SHAREVISTRING notification sent to a hook procedure: Reject the file name and displays a warning message (the same result as if there were no hook procedure).
OFN_SHARENOWARN Used with a SHAREVISTRING notification sent to a hook procedure: Reject the file name but do not warn the user. The application is responsible for displaying a warning message.
OFN_SHOWHELP Causes the dialog box to display the Help button. The hwndOwner member must specify the window to receive the HELPMSGSTRING registered messages that the dialog box sends when the user clicks the Help button. An Explorer-style dialog box sends a CDN_HELP notification message to your hook procedure when the user clicks the Help button.

 

Flag Meaning
OFN_DONTADDTORECENT Windows 2000/XP or later: Prevents the system from adding a link to the selected file in the file system directory that contains the user's most recently used documents. To retrieve the location of this directory, call the SHGetSpecialFolderLocation function with the CSIDL_RECENT flag.
OFN_ENABLEHOOK Enables the hook function specified in the fnHook member.
OFN_ENABLEINCLUDENOTIFY Windows 2000/XP or later: Causes the dialog box to send CDN_INCLUDEITEM notification messages to your OFNHookProc hook procedure when the user opens a folder. The dialog box sends a notification for each item in the newly opened folder. These messages enable you to control which items the dialog box displays in the folder's item list.
OFN_ENABLESIZING Windows 2000/XP or later, Windows 98: Enables the Explorer-style dialog box to be resized using either the mouse or the keyboard. By default, the Explorer-style Open and Save As dialog boxes allow the dialog box to be resized regardless of whether this flag is set. This flag is necessary only if you provide a hook procedure or custom template. The old-style dialog box does not permit resizing.
OFN_FORCESHOWHIDDEN Windows 2000/XP or later: Forces the showing of system and hidden files, thus overriding the user setting to show or not show hidden files. However, a file that is marked both system and hidden is not shown.

nFileOffset specifies the zero-based offset from the beginning of the path to the file name in the string pointed to by sFIle. For example, if sFIle points to the following string, "c:\dir1\dir2\file.ext", this member contains the value 13 to indicate the offset of the "file.ext" string. If the user selects more than one file, nFileOffset is the offset to the first file name.

nFileExtension specifies the zero-based offset in chrs from the beginning of the path to the file name extension in the string pointed to by sFIle. For example, if sFIle points to the following string, "c:\dir1\dir2\file.ext", this member contains the value 18. If the user did not type an extension and sDEfFileExt is NULL, this member specifies an offset to the terminating null character. If the user typed "." as the last character in the file name, this member specifies zero.

sDefFileExt is a pointer to a buffer that contains the default extension. GetOpenFileName and GetSaveFileName append this extension to the file name if the user fails to type an extension. This string can be any length, but only the first three characters are appended. The string should not contain a period. If this member is NULL and the user fails to type an extension, no extension is appended.x

fnHook - address to a hook (callback). This member is ignored unless the Flags member includes the OFN_ENABLEHOOK flag.

sCustomFilter, nMaxCustFilter, nCustData, sTemplateName are not covered in this demo. The MSDN has full information on these members.


API Return Values:

If the user specifies a file name and clicks the OK button, the return value is nonzero. The buffer pointed to by the sFIle member of the OPENFILENAME structure contains the full path and file name specified by the user. If the user cancels or closes the Open dialog box or an error occurs, the return value is zero.

Note too that the GetOpenFileName and GetSaveFileName dialogs only provide the means for the user to chose files. Although the File Save function may ask to overwrite an existing file, no actual overwriting will occur -- coding a file save method is the responsibility of the developer.

For a discussion on OPENFILENAME structure issues specific to Windows 2000/Windows XP, see GetOpenFileName: File Dialog Centering using a Callback.

With the descriptions out of the way, the code to implement the common dialogs is straightforward.

GetOpenFileName: File Open Common Dialog Basics

GetSaveFileName: File Save Common Dialog Basics


For a discussion on modifying the OPENFILENAME structure in order to display the new Windows 2000 or Windows XP-style Open and Save dialogs, please see the comments section in the page GetOpenFileName: File Dialog Centering using a Callback (note: a hook is not required to display this new-style dialog - it just so happens that page is the one I chose to explain this on.)


Windows' New Open and Save Dialog Style

Beginning with Windows 2000, the OPENFILENAME structure was extended to include three additional parameters specific to Windows 2000 and Windows XP. These additions change the size of the structure passed as the .nStructSize member which Windows uses to determine whether it should display the old or new-style dialogs. However, passing the new extended structure on a Win9x or NT4 system will result in the Open File or Save File dialog not being displayed at all.  Thankfully, because of the nStructSize parameter, you can go ahead and define the type with the new members regardless of the system, and then during the call identify the operating system in use and modify the value passed as the nStructSize parameter as appropriately.

To assure that the new dialog appears as expected, you must ensure that Len(OFN) is passed as the nStructSize parameter, and likewise to ensure the dialog appears on lower versions of windows, you can pass Len(OFN - 12) (12 = 3 longs of 4 bytes each). 

Probably the best way to ensure the correct value is passed is through declaration of three variables in your code:

Public OSV_VERSION_LENGTH as Long
Private Const OSV_LENGTH As Long = 76
Private Const OSVEX_LENGTH As Long = 88

Then use a routine to assign one of the two OSV length values to a variable and assign that to nStructSize.

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter