none
Visual Basic  フォルダのアイコンを取得したい RRS feed

  • 質問

  • 環境はWindows10です。Visual Basic 2013 でプログラムを書いています。

    簡単なプログラムで、ボタン押したら、bitmapに指定したディレクトリアドレスのアイコンのイメージを貼るプログラムを書いています

    現状はアプリケーションのアイコンの取得までできてはいます。
    フォルダや、デスクトップなどのアイコン取得ができなくて、教えてほしいです。

    Imports System.Runtime.InteropServices

    Public Class Form1

    #Region "アイコン取得用のWin32 API"

        ' SHGetFileInfo関数
        Private Declare Ansi 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

        ' SHGetFileInfo関数で使用するフラグ
        Private Const SHGFI_ICON As Integer = &H100 ' アイコン・リソースの取得
        Private Const SHGFI_LARGEICON As Integer = &H0 ' 大きいアイコン
        Private Const SHGFI_SMALLICON As Integer = &H1 ' 小さいアイコン
        Private Const SHGFI_TYPENAME As Integer = &H400 ' ファイルの種類
        Private Const SHGFI_USEFILEATTRIBUTES As Integer = &H10 '

        ' SHGetFileInfo関数で使用する構造体
        Private Structure SHFILEINFO
            Public hIcon As IntPtr
            Public iIcon As IntPtr
            Public dwAttributes As Integer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)> _
            Public szDisplayName As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)> _
            Public szTypeName As String
        End Structure


        Public Function GetTypeName(ByVal name As String) As String
            ' アプリケーション・アイコンを取得
            Dim shinfo As New SHFILEINFO()

            shinfo.szDisplayName = New String(Chr(0), 260)
            shinfo.szTypeName = New String(Chr(0), 80)
            Dim hSuccess As IntPtr = SHGetFileInfo(name, 0, shinfo, Marshal.SizeOf(shinfo), _
                SHGFI_ICON Or SHGFI_LARGEICON Or SHGFI_TYPENAME)

            Return shinfo.szTypeName

        End Function

    #End Region

        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

            Dim mydocument As String = "C:\Users\wishflower\Desktop"


            ' アプリケーション・アイコンを取得
            Dim shinfo As New SHFILEINFO()
            Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_LARGEICON Or SHGFI_USEFILEATTRIBUTES)
            If hSuccess.Equals(IntPtr.Zero) = False Then
                Dim appIcon As Icon = Icon.FromHandle(shinfo.hIcon)
                PictureBox1.Image = appIcon.ToBitmap
            End If

        End Sub
    End Class


    2020年9月18日 2:27

回答

  • SHGFI_USEFILEATTRIBUTESは不要では?

    Dim mydocument As String = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop)
    
    ' アプリケーション・アイコンを取得
    Dim shinfo As New SHFILEINFO()
    Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    'Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_LARGEICON)
    'Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_LARGEICON)

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年9月18日 8:57
  • SHGetFileInfoをキーワードにしてインターネット検索するとmicrosoft.のサイトが見つかります。
    ただし英語の情報になっているので、ブラウザの翻訳機能か翻訳サイトで日本語にしてやります。

    SHGFI_USEFILEATTRIBUTES (0x00000010)
    関数がpszPathで指定されたファイルにアクセスしないようにすることを示します。代わりに、pszPathで指定されたファイルがdwFileAttributesで渡されたファイル属性を持つ場合と同じ動作をする必要があります。このフラグは、 SHGFI_ATTRIBUTES、 SHGFI_EXETYPE、またはSHGFI_PIDLフラグと組み合わせることはできません。

    SHGFI_USEFILEATTRIBUTESを指定していると、第一引数のファイルパスを使わないと読めます。
    あとは実際に指定せずに実行してやればアイコンが取れることが確認できました。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年9月18日 11:52

すべての返信

  • 前スレッドで参考に引用された https://www.codeproject.com/Articles/13097/An-quot-Explorer-Style-quot-TreeView-Control では、
    フォルダや特殊フォルダもアイコン表示されていますね。

    古い時代のサンプルコードなので、今、動くか否かは検証していませんが、
    ソースコードを入手して追えば、参考になるでしょう。

    • 編集済み ShiroYuki_Mot 2020年9月18日 7:57 前スレッドをリンク化
    2020年9月18日 7:53
  • SHGFI_USEFILEATTRIBUTESは不要では?

    Dim mydocument As String = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop)
    
    ' アプリケーション・アイコンを取得
    Dim shinfo As New SHFILEINFO()
    Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    'Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_LARGEICON)
    'Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_LARGEICON)

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年9月18日 8:57
  • SHGFI_USEFILEATTRIBUTESは不要では?

    Dim mydocument As String = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop)
    
    ' アプリケーション・アイコンを取得
    Dim shinfo As New SHFILEINFO()
    Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON)
    'Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_LARGEICON)
    'Dim hSuccess As IntPtr = SHGetFileInfo(mydocument, 0, shinfo, Marshal.SizeOf(shinfo), SHGFI_ICON Or SHGFI_SMALLICON Or SHGFI_LARGEICON)

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    ありがとうございます。

    すみません、一応、どうやって調べたか教えてもらえないでしょうか(´・ω・`)

    次に生かしたくすみません。


    2020年9月18日 11:10
  • SHGetFileInfoをキーワードにしてインターネット検索するとmicrosoft.のサイトが見つかります。
    ただし英語の情報になっているので、ブラウザの翻訳機能か翻訳サイトで日本語にしてやります。

    SHGFI_USEFILEATTRIBUTES (0x00000010)
    関数がpszPathで指定されたファイルにアクセスしないようにすることを示します。代わりに、pszPathで指定されたファイルがdwFileAttributesで渡されたファイル属性を持つ場合と同じ動作をする必要があります。このフラグは、 SHGFI_ATTRIBUTES、 SHGFI_EXETYPE、またはSHGFI_PIDLフラグと組み合わせることはできません。

    SHGFI_USEFILEATTRIBUTESを指定していると、第一引数のファイルパスを使わないと読めます。
    あとは実際に指定せずに実行してやればアイコンが取れることが確認できました。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年9月18日 11:52