Using the Common Dialog Open/Save Boxes
The API method accesses the comdlg32.dll library directly, rather than via an ActiveX control. Normally it requires quite complicated code, but I have written a class which encompasses all of the features. The properties and methods are identical to the OCX, except that you don't need a form loaded to view the dialogs.
Using this class is as simple as creating the object in code, then replacing all the references to the Common Dialog Control with this Common Dialog Class:
Dim CmDlg As New clsOpenSave On Error Resume Next ' Set up error handler CmDlg.CancelError = True CmDlg.ShowOpen If Err.Number = cdlAPICancel Then MsgBox "You clicked cancel!" Err.Clear Else MsgBox "You chose: " & CmDlg.filename MsgBox "Filename: " & CmDlg.FileTitle MsgBox "Path: " & Left$(CmDlg.filename, _ Len(CmDlg.filename) - Len(CmDlg.FileTitle)) End If On Error GoTo 0 ' Turn off error handler
The API method using this class is the same as the control. However, you cannot use the OFN_SHOWHELP flag. To use this requires subclassing of the dialog, which can be achieved using the lpfnHook member of the OEPNFILENAME structure. If you pass the address of one of your procedures in a standard module, you can receive the windows messages. The parameters for the window function are the usual ones:
Public Function customwndproc(ByVal hwnd As Long, _ ByVal msg As Long, ByVal wparam As Long, ByVal _ lparam As Long) As Long End Function
If you decide to use a custom message handler, remember to save before testing, because if the are any unhandled error, VB is sure to crash. Using a message handler, you can hide the default controls on the dialog and create your own new ones. However, this requires very complicated methods, which are too much detail for this article.
Another member of the OPENFILENAME structure not covered in the class is the nFileOffset member. When the dialog is closed, this returns the length of the path in the filename string. Therefore to retrieve just the path, you would use:
strPath = Left$(Trim$(OFN.lpstrfile), OFN.nFileOffset)
Lastly, when setting the filter for the API method, you should separate each part with ASCII character 0 (vbNullchar) and terminate it with two nulls. This is done automatically by the class, so you can just pass the filter using the same way as the OCX, separating each item with a pipe ("|").
Page 4 of 5