Shell32.dll を覗き見して興味を持ったAPI関数をちらほらと動作確認してみた。以下のすべては Windows XP(SP2) または Windows 2003 Server 以降に追加された関数らしい。
以下はひとまず共通で使用するための関数。おなじみのNULL文字までの文字列を取得する関数である。
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:文字列を Chr$(0)[=vbNullChar] まで取得する ' 引 数:(in)SrcStr … 対象文字列 ' 返り値:編集された文字列 '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Private Function StrNullCut(ByVal SrcStr As String) As String Dim NullCharPos As Long NullCharPos = InStr(SrcStr, Chr$(0)) If NullCharPos = 0 Then StrNullCut = SrcStr Exit Function End If StrNullCut = Left$(SrcStr, NullCharPos - 1) End Function 以下より1つずつ列挙していく。API関数の別名 alias には一応、序数を指定しておいた。Windows Vista 以降で序数が変わっているかもしれないが、それは知ったこっちゃない。もし動かない場合は alias を削除してください。API関数 PathGetShortPath の引数がちょっと変わっているが、非常に合理的である。API関数 PathGetShortPath も同様の作りに出来たと思われるが…はて? あと Win32DeleteFile の作成者はせっかちなのであろうか? Kernel32.dll に DeleteFile がいるのにねぇ。
'序数:92 機能:長いファイルパスを短いファイルパスに変換する
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:長いファイルパスを短いファイルパスに変換する ' 引 数:(i)FileName … 長いファイル名(フルパス) ' 返り値:短いファイルパス ' 存在しないファイルが渡された場合は引数で渡されたFileNameの値が返る '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function ConvLongName2ShortName(ByVal FileName As String) Call PathGetShortPath(ByVal StrPtr(FileName)) ConvLongName2ShortName = StrNullCut(FileName) End Function
'序数:43 拡張子を見て実行ファイル系かどうか判定する
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:拡張子を見て実行ファイル系かどうか判定する ' 実行ファイルとみなされる拡張子:cmd, bat, pif, exe, com, scr 等 ' 引 数:(i)FileName … ファイル名 ' 返り値:True…実行ファイル系である False…実行ファイル系でない ' 備 考:引数のファイル名は存在しないファイルでも判定対象となる '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function IsExeSeriesFile(ByVal FileName As String) As Boolean IsExeSeriesFile = PathIsExe(ByVal StrPtr(FileName)) End Function
'序数:164 ファイルを削除する
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:ファイルを削除する ' 引 数:(i)FileName … ファイル名 ' 返り値:正常…True 異常…False ' 備 考:ディレクトリを削除することは出来ない '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function DeleteFile(ByVal FileName As String) As Boolean DeleteFile = Win32DeleteFile(StrPtr(FileName)) End Function
'序数:165 ディレクトリを作成する
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:ディレクトリを作成する ' 引 数:(i)hWnd … 呼び出しウィンドウのハンドル ' (i)TargetDir … 作成するディレクトリ(フルパス) ' 返り値:正常…True 異常…False ' 備 考:既にディレクトリが存在する場合はFalseを返す '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function CreateDirectory(ByVal hWnd As Long, ByVal TargetDir As String) As Boolean 'SHCreateDirectory は 正常時は-1、異常時は0を返す CreateDirectory = Not CBool(SHCreateDirectory(hWnd, StrPtr(TargetDir))) End Function
'序数:680 ログインユーザが管理者グループに属しているかを判定する
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:ログインユーザが管理者グループに属しているかを判定する ' 引 数:なし ' 返り値:ログインユーザが管理者グループである場合はTrue、そうでない場合はFalse '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function IsUserInAdminGroup() As Boolean IsUserInAdminGroup = CBool(IsUserAnAdmin) End Function
'序数:171 ファイルパスの使用不可能文字を取り除く Public Const PCS_REPLACEDCHARS As Long = &H1 '使用不可能文字を置換した → / があるとこれが返る Public Const PCS_REMOVEDCHARS As Long = &H2 '使用不可能文字を除去した → \:*?<>| があるとこれが返る Public Const PCS_SHORTENED As Long = &H4 '返されたパスを切り捨てた Public Const PCS_PATHTOOLONG As Long = &H8 '長ぇ〜よ Public Const PCS_FATAL As Long = &H8000000 '致命的エラー '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:ファイル名を洗浄する(ファイルパスではなく、ファイル名) ' 引 数:(i)InFileName … 汚いファイル名 ' (o)OutFileName … 綺麗なファイル名 ' 返り値:上記 PCS_XXX 定数の組み合わせが返る ' 備 考:返り値はシュールすぎてよう分からん ' ↓とりあえずすべての返り値を出してみた。色々と頑張ってみたが 8(=長ぇ〜よ) は出なかった ' Testあいう.txt → 0 が返る、綺麗にされて TESTあいう.TXT が返る(何故か大文字化される) ' CMyApp/File → 1 が返る、綺麗にされて CMyApp-File が返る ' C:\MyAppFile → 2 が返る、綺麗にされて CMyAppFile が返る ' C:\MyApp/File → 3 が返る、綺麗にされて CMyApp-File が返る ' MyApp@File.txt → 4 が返る、綺麗にされて MYAPP@FI.TXT が返る(何故か大文字化される) ' MyApp/File.txt → 5 が返る、綺麗にされて MYAPP-FI.TXT が返る(何故か大文字化される) ' MyApp@:File.txt → 6 が返る、綺麗にされて MYAPP@FI.TXT が返る(何故か大文字化される) ' MyApp@:File.txt.exe → 7 が返る、綺麗にされて MYAPP@FI.EXE が返る(何故か大文字化される) '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function CleanUpPath(ByVal InFileName As String, ByRef OutFileName As String) As Long CleanUpPath = PathCleanupSpec(StrPtr(InFileName), StrPtr(InFileName)) OutFileName = StrNullCut(InFileName) End Function
'序数:63 ファイルを開くコモンダイアログを表示する
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:ファイルを開くためのダイアログボックスを表示し、ファイルのフルパスを返す ' 引 数:(i)hWnd … 呼び出し側のウインドウハンドル ' (i)InitialDir … 初期ディレクトリ指定 (省略可能) ' (i)Filter … 拡張子設定のフィルタ (省略可能) ' (i)DialogTitle … ダイアログボックスのタイトル (省略可能) ' 返り値:選択されたファイルのフルパス '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function ShowOpenFileDialogEx(ByVal hWnd As Long, _ Optional ByVal InitialDir As String = "", _ Optional ByVal Filter As String = _ "すべてのファイル (*.*)" & vbNullChar & "*.*" & vbNullChar, _ Optional ByVal DialogTitle As String = "ファイルを開く") As String Dim FileName As String Dim FuncRet As Long '返り値変数初期化 FileName = String$(MAX_PATH, Chr$(0)) 'コモンダイアログ表示 FuncRet = GetFileNameFromBrowse(hWnd, StrPtr(FileName), MAX_PATH, _ StrPtr(InitialDir), 0&, StrPtr(Filter), StrPtr(DialogTitle)) If FuncRet Then ShowOpenFileDialogEx = StrNullCut(FileName) End If End Function
'序数:59 システム変更に伴うWindows終了ダイアログを表示する →[参照] Windows終了ダイアログを表示する画像 'RestartDialogの第3引数用列挙体 Public Enum RES_DLG_FLAG EWX_LOGOFF = 0 'ログオフ EWX_SHUTDOWN = 1 'シャットダウン EWX_REBOOT = 2 '再起動 EWX_FORCE = 4 '緊急用で何が何でも強制終了の場合に使用する 'WM_QUERYENDSESSIONとWM_ENDSESSION をシステムに送信しない EWX_POWEROFF = 8 'パワーオフ EWX_FORCEIFHUNG = 16 'WM_QUERYENDSESSIONとWM_ENDSESSION を送信し、応答が無くても終了する End Enum
'序数:62 アイコンの変更ダイアログを表示する →[参照] アイコンの変更ダイアログ画像
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:アイコンの変更ダイアログを表示する ' 引 数:(i)hWnd … 呼び出し元ウィンドウのハンドル ' (i/o)FileName … 選択前または選択後のアイコンを持つファイルの名前 ' (i/o)IconIndex … 選択前または選択後のアイコン位置(0〜) ' 返り値:正常…True 異常またはキャンセルされた…False '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function OpenIconDialog(ByVal hWnd As Long, ByRef FileName As String, ByRef IconIndex As Long) As Boolean Dim FuncRet As Long Dim FileNameB() As Byte '文字列→Byte配列変換 FileNameB = FileName '元の値を保持しつつ、Byte配列を再確保 ReDim Preserve FileNameB(MAX_PATH - 1) As Byte 'アイコンの変更ダイアログを表示する OpenIconDialog = PickIconDlg(hWnd, VarPtr(FileNameB(0)), MAX_PATH, IconIndex) 'Byte配列→文字列変換&NULL文字以降削除 FileName = StrNullCut(FileNameB) End Function [呼び出し方法] Private Sub Command1_Click() Dim FileName As String Dim IconIndex As Long Dim FuncRet As Boolean 'アイコンを含むファイルの名前 FileName = "C:\Windows\System32\shell32.dll" 'アイコン選択位置 IconIndex = 10 'アイコンの変更ダイアログを表示 FuncRet = OpenIconDialog(frmMain.hWnd, FileName, IconIndex) If FuncRet Then Debug.Print "? FileName : " & FileName Debug.Print "? IconIndex : " & IconIndex Else Debug.Print "キャンセルされました" End If End Sub
[関連] コントロールパネルの各プロパティを起動する、コントロールパネルウィンドウを起動する
'序数:161 コントロールパネルを開く
'序数:28、162 ディレクトリに対するpidを取得する
'-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:コントロールパネルを表示する ' 引 数:(i)hWnd … ウィンドウハンドル ' (i)OpenCpl … コンパネ文字列(フォーマット:コンパネ名,,タブ位置) ' 返り値:正常:True 異常:False ' 備 考:OpenCpl の指定が無い場合(=空文字の場合)はコントロールパネルが表示される '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Public Function OpenControlPanel(ByVal hWnd As Long, Optional ByVal OpenCol As String = "") As Boolean OpenControlPanel = SHRunControlPanel(StrPtr(OpenCol), hWnd) End Function '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ' 機 能:ディレクトリからpidを取得する ' 引 数:(i)TargetDir … 対象ディレクトリ ' 返り値:ipdが返る エラー時は 0 '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Private Function GetPidFromDir(ByVal TargetDir As String) As Long Dim Rgf As Long Dim lpTargetPath As Long Dim FuncRet As Long '文字列の先頭アドレスを取得 lpTargetPath = StrPtr(TargetDir) 'ディレクトリに対するpidを取得する FuncRet = SHILCreateFromPath(lpTargetPath, GetPidFromDir, Rgf) If FuncRet <> 0 Then 'エラー時の保険(実はどう処理をすれば良いか分からんのだよ) GetPidFromDir = SHSimpleDListFromPath(lpTargetPath) If GetPidFromDir = 0 Then Exit Function End If End Function[OpenControlPanel の第2引数に渡す値]
|