● ファイルを開くダイアログ ●

OCXを使用すると必ず、画面左上に表示されてしまい困ってしまう。つ〜か、そんなの使いたくない…。

ファイルを開くダイアログを表示するには、OPENFILENAME 構造体のメンバにしかるべき値を設定し、 GetOpenFileName 関数の引数として渡してやればよろしい。その OPENFILENAME 構造体 と GetOpenFileName 関数は以下の通り。

なお Windows XP(SP2) または Windows 2003 Server 以降の OS であれば、GetFileNameFromBrowse というAPI関数も利用できる。
それについてはShell32.dllに生息する妙なAPI関数達を参照。

Private Type OPENFILENAME
    lStructSize As Long          '構造体のサイズ
    hWndOwner As Long            '0を指定すると表示位置は左上となる
    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                'OFN_XXX、フラグ
    nFileOffset As Integer       'フルパスのファイル名までのオフセット
    nFileExtension As Integer    '拡張子までのオフセット
    lpstrDefExt As String        'デフォルトの拡張子
    lCustData As Long            '???
    lpfnHook As Long             'フック関数へのポインタ
    lpTemplateName As String     'ダイアログのタイトル名
End Type

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

余談であるが、次のようなものもある。こちらは、GIF や MIDI 等のメディアファイルを選択すると、プレビュー画面が表示されるというもである。使用用途に応じて使い分けよう。

Private Declare Function GetOpenFileNamePreview Lib "msvfw32.dll" Alias "GetOpenFileNamePreviewA" (ByRef pOpenfilename As OPENFILENAME) As Long

じゃ、定数をば。

Private Const MAX_PATH = 260
Private Const OFN_READONLY = &H1            '[読み取り専用] のチェック ボックスをオンにした状態で表示する
Private Const OFN_OVERWRITEPROMPT = &H2     '既存のファイル名がある場合メッセージボックスを表示
Private Const OFN_HIDEREADONLY = &H4        '[読み取り専用] チェック ボックスを非表示にする
Private Const OFN_NOCHANGEDIR = &H8         '他のサブディレクトリから選択不可能
Private Const OFN_SHOWHELP = &H10           'ヘルプボタンを表示する
Private Const OFN_ENABLEHOOK = &H20
Private Const OFN_ENABLETEMPLATE = &H40
Private Const OFN_ENABLETEMPLATEHANDLE = &H80
Private Const OFN_NOVALIDATE = &H100        'ファイル名の有効性をチェックしない
Private Const OFN_ALLOWMULTISELECT = &H200  '複数ファイルを選択可能にする
Private Const OFN_EXTENSIONDIFFERENT = &H400
Private Const OFN_PATHMUSTEXIST = &H800     '有効なパス名だけだけを受け取る
Private Const OFN_FILEMUSTEXIST = &H1000    '指定したファイル名は必ず存在しなければならない
Private Const OFN_CREATEPROMPT = &H2000     'ファイル名の指定がないときメッセージボックスを表示
Private Const OFN_SHAREAWARE = &H4000       '共有違反のエラーを無視する
Private Const OFN_NOREADONLYRETURN = &H8000 'Read Onlyファイルと上書き禁止ファイルディレクトリからの選択不可能
Private Const OFN_NOTESTFILECREATE = &H10000
Private Const OFN_NONETWORKBUTTON = &H20000
Private Const OFN_NOLONGNAMES = &H40000    '長いファイル名を使用しない
Private Const OFN_EXPLORER = &H80000       'Windows 95の[ファイルを開く]ダイアログボックスのテンプレート
Private Const OFN_NODEREFERENCELINKS = &H100000  'ショートカットを使用しない
Private Const OFN_LONGNAMES = &H200000     '長いファイル名を使用する

これらの定数を 'Or' で結合して OPENFILENAME 構造体のメンバ "flags" にセットする。
じゃあ、関数を書いてみましょう。

'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
' 機  能:ファイルを開くためのダイアログボックスを表示し、ファイル名、または
'         ファイルのフルパスを返す
' 引  数:(i) hWnd     … 呼び出す側のウインドウハンドル
'         (i) RetMode  … 0:ファイルのフルパスを返す
'                         1:ファイル名を返す
'         (i) Filter   … 拡張子設定のフィルタ  (省略可能)
'         (i) InitialDir  … ディレクトリ指定  (省略可能)
'         (i) DialogTitle … ダイアログボックスのタイトル  (省略可能)
' 返り値:ファイル名、またはファイルのフルパス  キャンセル:空文字
'=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Public Function GetOpenFilePath(ByVal hwnd As Long, _
                                ByVal RetMode As Long, _
                                Optional ByVal Filter As String = "すべてのファイル (*.*)" & vbNullChar & "*.*" & vbNullChar, _
                                Optional ByVal InitialDir As String = "", _
                                Optional ByVal DialogTitle As String = "ファイルを開く") As String

    Dim udtOpenFile As OPENFILENAME
    Dim FuncRet As Long

    With udtOpenFile
        .lStructSize = Len(udtOpenFile)         '構造体のサイズ
        .hWndOwner = hwnd                       'オーナーハンドルを指定
        .hInstance = App.hInstance              'インスタンス指定
        .flags = OFN_PATHMUSTEXIST Or OFN_FILEMUSTEXIST Or _
                 OFN_HIDEREADONLY               'フラグを指定する
        .lpstrFile = String$(MAX_PATH, Chr$(0))      'ファイル名を格納するバッファを設定
        .nMaxFile = MAX_PATH                         'ファイル名を格納するバッファサイズ
        .lpstrFileTitle = String$(MAX_PATH, Chr$(0)) 'ファイルのフルパスを格納するバッファ
        .nMaxFileTitle = MAX_PATH                    'ファイルのフルパスを格納するバッファサイズ
        .lpstrInitialDir = InitialDir                '初期ディレクトリ指定
        .lpstrFilter = Filter                        'フィルターの設定
        .nFilterIndex = 1                            'フィルターインデックスを指定
        .lpstrTitle = DialogTitle                    'ダイアログボックスの名前を指定
    End With

    FuncRet = GetOpenFileName(udtOpenFile)

    If FuncRet <> 0 Then
        Select Case RetMode
            Case 0      'ファイルのフルパスを返す
                GetOpenFilePath = StrNullCut(udtOpenFile.lpstrFile)
            Case Else   'ファイル名を返す
                GetOpenFilePath = StrNullCut(udtOpenFile.lpstrFileTitle)
        End Select
    End If

End Function

で、以下がサンプル。

Private Sub Command1_Click()

    Dim ReturnString As String
    Dim Filter As String

    Filter = "Text Files (*.txt)" & Chr$(0) & "*.txt" & Chr$(0) & _
            "HTML Files (*.htm *.html)" & Chr$(0) & "*.htm;*.html" & Chr$(0) & _
            "ALL Files (*.*)" & Chr$(0) & "*.*" & Chr$(0)

    ReturnString = GetOpenFilePath(Form1.hwnd, 0, Filter, , "ファイルを開く")

    If ReturnString <> "" Then
        Debug.Print ReturnString
    Else
        Debug.Print "キャンセルが押されました"
    End If

End Sub

戻る