- 題名: リストビューにファイルの種類を表示する。
- 日時: 2004/10/25 12:23:36
- ID: 6980
- この記事の返信元:
- (なし)
- この記事への返信:
- [6986] Re[1]: リストビューにファイルの種類を表示する。2004/10/25 20:50:22
- [7011] Re[1]: リストビューにファイルの種類を表示する。2004/10/27 4:03:37
- ツリーを表示
こんにちは 私もファイルタイプを取得したいと思ってAPIの SHGetFileInfo で試みたのですが どうやっても SHFILEINFO 構造体の szTypeName が空になって 取得できませんでしたので、取り敢えずレジストリで取得しました しかし、エクスプローラで見える日本語のファイルタイプは取れません・・・ もし英語表記でよかったらどうぞ では Private Function GetFileType(ByVal extension As String) As String 'extension には拡張子 例 ".txt" Dim regkey As RegistryKey = _ Registry.ClassesRoot.OpenSubKey(extension) Return CType(regkey.GetValue(""), String) End Function
ihcioyさんありがとうございます > この場合だとファイルタイプ(?)が返ってきていたような・・・。 > 取得したファイルタイプを使ってもう一度 > Registry.ClassesRoot.OpenSubKey(filetype).GetValue("") > を行えば種類(?)が返ってきました。 こんな感じで出来ました。 Private Function GetFileType(ByVal extension As String) As String Try Dim type As String = CType(Registry.ClassesRoot.OpenSubKey(extension).GetValue(""), String) Return CType(Registry.ClassesRoot.OpenSubKey(type).GetValue(""), String) Catch ex As Exception End Try End Function > ちなみにregkeyはNothingをチェックしないと例外エラーが > 発生します。 regkey.close regkey = Nothing ってことでしょうか?
深山さん返信ありがとうございます > No6986 でも触れているように、 SHGetFileInfo の引数には拡張子ではなく > ファイルのフルパスが必要になります。 > この点は大丈夫でしょうか? はい、確認しました > もしそのときのコードが残っているようでしたら、 > 問題が特定できるかも知れませんが。 お言葉に甘えて恐縮ですが、一応載せてみます 'Imports System.Runtime.InteropServices <StructLayout(LayoutKind.Sequential)> _ Declare Auto Function SHGetFileInfo Lib "Shell32" ( _ ByVal pszPath As String, _ ByVal dwFileAttributes As Integer, _ ByRef psfi As SHFILEINFO, _ ByVal cbFileInfo As Integer, _ ByVal uFlags As Integer) As IntPtr Public Structure SHFILEINFO Public Const NAMESIZE As Integer = 80 Public hIcon As IntPtr Public iIcon As Integer Public dwAttributes As UInt32 <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> _ Public szDisplayName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=NAMESIZE)> _ Public szTypeName As String End Structure Public Const SHGFI_USEFILEATTRIBUTES As Integer = &H10 Public Const FILE_ATTRIBUTE_NORMAL As Integer = &H80 Public Const SHGFI_TYPENAME As Integer = &H400 こんな感じでした よろしくお願いします
肝心のメソッドを書き忘れました Public Function GetTypeName(ByVal name As String) As String Dim shfi As New SHFILEINFO Dim flags As Integer = SHGFI_TYPENAME Or SHGFI_USEFILEATTRIBUTES SHGetFileInfo(name, FILE_ATTRIBUTE_NORMAL, shfi, Marshal.SizeOf(shfi), flags) Return shfi.szTypeName End Function です よろしくお願いします
> 'Imports System.Runtime.InteropServices > > <StructLayout(LayoutKind.Sequential)> _ > Declare Auto Function SHGetFileInfo Lib "Shell32" ( _ > ByVal pszPath As String, _ > ByVal dwFileAttributes As Integer, _ > ByRef psfi As SHFILEINFO, _ > ByVal cbFileInfo As Integer, _ > ByVal uFlags As Integer) As IntPtr > > Public Structure SHFILEINFO > Public Const NAMESIZE As Integer = 80 > Public hIcon As IntPtr > Public iIcon As Integer > Public dwAttributes As UInt32 > <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> _ > Public szDisplayName As String > <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=NAMESIZE)> _ > Public szTypeName As String > End Structure えっと、これではコンパイルを通らないようですが‥‥(^_^;) 取り敢えず、 ・StructLayout 属性は構造体の宣言に付いている ・MAX_PATH の定義もされている ものとして話を進めます。 #ただの転記ミスですよね? 実行したところ、確かに取得できませんでした。どうやら文字列のマーシャリングに失敗しているようです。 修正方法はいくつかありますが、 StructLayout 属性の CharSet フィールドを設定するのが一般的でしょうか。 > <StructLayout(LayoutKind.Sequential)> _ > Public Structure SHFILEINFO の箇所を <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ Public Structure SHFILEINFO としてみてください。 #この辺りの内容とあわせて Declare ステートメントの Ansi / Unicode / Auto に関する説明にも目を通しておくと良いかも知れません。 以下、本題とは直接関係ないのですが。 ファイルの種類だけ取得できれば良いのであって、ファイルの属性は必要ないのですよね? であれば、 FILE_ATTRIBUTE_NORMAL や SHGFI_USEFILEATTRIBUTES は必要ありませんよ。 > Dim flags As Integer = SHGFI_TYPENAME Or SHGFI_USEFILEATTRIBUTES > SHGetFileInfo(name, FILE_ATTRIBUTE_NORMAL, shfi, Marshal.SizeOf(shfi), flags) の部分は Dim flags As Integer = SHGFI_TYPENAME SHGetFileInfo(name, 0, shfi, Marshal.SizeOf(shfi), flags) でOKです。
深山さんありがとうございます > ・StructLayout 属性は構造体の宣言に付いている > ・MAX_PATH の定義もされている > ものとして話を進めます。 > #ただの転記ミスですよね? お手数かけて申し訳ございません、その通りです・・・ > <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ > Public Structure SHFILEINFO > としてみてください。 > #この辺りの内容とあわせて Declare ステートメントの > Ansi / Unicode / Auto に関する説明にも目を通しておくと良いかも知れません。 できるならなるべくマネージドでと思いこの当たりは避けてました・・・ がんばって勉強してみようと思います! 本題ですが、指摘頂いた部分を直しても、 (私の環境では?)取得はできませんでした。 結局 >Public Function GetTypeName(ByVal name As String) As String > Dim shfi As New SHFILEINFO の次に以下を追加したところ、成功しました! shfi.szTypeName = New String(Chr(0), 80) 一応完成しましたので、「Windows APIを使用したファイルタイプの取得」 コードを掲載します 'Windows APIを使用したファイルタイプの取得 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ Public Structure SHFILEINFO Public hIcon As IntPtr Public iIcon As Integer Public dwAttributes As Integer <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _ Public szDisplayName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _ Public szTypeName As String End Structure Private Declare Auto Function SHGetFileInfo Lib "shell32.dll" _ (ByVal pszPath As String, _ ByVal dwFileAttributes As Integer, _ ByRef psfi As SHFILEINFO, _ ByVal cbFileInfo As Integer, _ ByVal uFlags As Integer) As IntPtr Public Function GetTypeName(ByVal name As String) As String Dim shfi As New SHFILEINFO shfi.szDisplayName = New String(Chr(0), 260) shfi.szTypeName = New String(Chr(0), 80) SHGetFileInfo(name, 0, shfi, Marshal.SizeOf(shfi), &H400) Return shfi.szTypeName End Function また、ihcioyさんに指摘していただいた部分を修正した 「レジストリを使用したファイルタイプの取得」も合わせて掲載します 'レジストリを使用したファイルタイプの取得 Private Function GetFileType(ByVal extension As String) As String Try Dim regKey As RegistryKey = Registry.ClassesRoot.OpenSubKey(extension) If regKey Is Nothing Then Return Nothing Dim type As String = CType(regKey.GetValue(""), String) Return CType(Registry.ClassesRoot.OpenSubKey(type).GetValue(""), String) Catch ex As Exception End Try End Function 以上 長々と申し訳ございません 皆様いろいろありがとうございました
分類:[.NET]
こんにちわ。
VB初心者です。
リストビューにファイルを表示する際に、ファイルの種類の表示で、
”.txt”と、拡張子の表示でなく”テキストファイル”などというふ
うに表示したいのですがうまくいきません。
だれかよろしかったら教えてください。
お願いします。