- 締切済み
C#でウィンドウのアイコン取得する方法
タスクマネージャのアプリケーションタブに 起動しているアプリケーション名とアイコンが一覧で表示されている部分のように 小さいアイコンを取得したいんですがなかなかうまくいきません。 ファイルに紐付くアイコンと解釈していただいても構いません。 とりあえず、下記のWin32 APIの処理を利用してみましたが SHGetFileInfoだけしかうまくいきませんでした。 しかし、SHGetFileInfoも、アイコンは取得できますがこれはファイルに紐付くアイコンではなく 実行体(EXE)に紐付くアイコンで表示されてしまいました。 開いているウィンドウ情報からだと実行プロセスのEXEのパスしか分からないからです。 ★質問★: ファイルに紐付く小さいアイコンの取得方法を教えてください!できればサンプルソース込みだと助かります。 #region 小さいアイコンを取得するためのWin32 API(ファイルパスから) // SHGetFileInfo関数 [DllImport("shell32.dll")] private static extern IntPtr SHGetFileInfo( string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); // SHGetFileInfo関数で使用するフラグ private const uint SHGFI_ICON = 0x100; // アイコン・リソースの取得 private const uint SHGFI_LARGEICON = 0x0; // 大きいアイコン private const uint SHGFI_SMALLICON = 0x1; // 小さいアイコン private const uint SHGFI_TYPENAME = 0x400;//ファイルの種類 // SHGetFileInfo関数で使用する構造体 private struct SHFILEINFO { public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; #endregion #region 小さいアイコンを取得するためのWin32 API(ウィンドウハンドルからその1) [DllImport("user32.dll", EntryPoint = "GetClassLong")] public static extern IntPtr GetClassLongPtr32(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetClassLongPtr")] public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); const int GCL_HICON = (-14); const int GCL_HICONSM = (-34); #endregion #region 小さいアイコンを取得するためのWin32 API(ウィンドウハンドルからその2) [DllImport("User32.dll", EntryPoint = "SendMessage")] public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); public const int WM_GETICON = 0x7F; public const int WM_SETICON = 0x80; public const int ICON_SMALL = 0; public const int ICON_BIG = 1; #endregion
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- sean9
- ベストアンサー率86% (26/30)
こんにちは。時間が立っているので解決してるかも知れませんね。 2つ用意しました。 1. 大きいアイコンを取得して小さくする方法 Image = Icon.ExtractAssociatedIcon(ファイルパス).ToBitmap(); Imageのサイズを変更する 2. 小さいアイコンを取得する方法 Image = IconUtility.FileAssociatedImage(ファイルパス, false); using System; using System.IO; using System.Runtime.InteropServices; using System.Drawing; namespace GetIcon { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] struct SHFILEINFO { public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; } public class IconUtility { const uint SHGFI_LARGEICON = 0x00000000; const uint SHGFI_SMALLICON = 0x00000001; const uint SHGFI_USEFILEATTRIBUTES = 0x00000010; const uint SHGFI_ICON = 0x00000100; [DllImport("shell32.dll", CharSet = CharSet.Auto)] static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags); [DllImport("user32.dll", CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool DestroyIcon(IntPtr hIcon); /// <summary> /// 指定したファイルパスに関連付けされたアイコンイメージを示す /// </summary> /// <param name="path"ファイルパス</param> /// <param name="isLarge">true:大きいアイコン false:小さいアイコン</param> /// <returns>アイコンのイメージ</returns> public static Image FileAssociatedImage(string path, bool isLarge) { return FileAssociatedImage(path, isLarge, File.Exists(path)); } /// <summary> /// 指定したファイルパスに関連付けされたアイコンイメージを示す /// </summary> /// <param name="isExist"> /// true:ファイルが実在するときだけ動作 false:実在しなくて動作させるとき /// </param> /// <returns>アイコンのイメージ</returns> public static Image FileAssociatedImage(string path, bool isLarge, bool isExist) { SHFILEINFO fileInfo = new SHFILEINFO(); uint flags = SHGFI_ICON; if (!isLarge) flags |= SHGFI_SMALLICON; if (!isExist) flags |= SHGFI_USEFILEATTRIBUTES; try { SHGetFileInfo(path, 0, ref fileInfo, (uint)Marshal.SizeOf(fileInfo), flags); if (fileInfo.hIcon == IntPtr.Zero) return null; else return Icon.FromHandle(fileInfo.hIcon).ToBitmap(); } finally { if (fileInfo.hIcon != IntPtr.Zero) DestroyIcon(fileInfo.hIcon); } } } }
お礼
頂いた回答ですと私が試しているSHGetFileInfoと同じ結果です。SHGetFileInfoを使うとタスクマネージャーで表示されているものとはアイコンが異なるものが取得されてしまいます。 例えばフォルダのアイコンとかが違います。 私はサクラエディタを別アイコンを設定しているのですが そちらも、元のアイコンが取得されてしまい、 私が設定したアイコンは取得できませんでした。 窓替えというフリーツールではちゃんと取得出来ているので 実現は確実にできるはずですが、その術が分かりません…