【C#】アイコンイメージ取得する3つの方法【サンプルプログラム】


 

 

C#でアイコンを取得するときのスニペットです。

アイコンは、16,32の小さめのアイコンと、 48, 256サイズの大きめのアイコンの取得で大きく違います。
あと、パス変換が意外とクセモノですのでその対応も必要です。

サンプルプログラム(Visual Studio Desktop)

処理目的 メソッド名 補足
小さめのアイコン取得
(その1)
getIconToBMP //Marshal :
using System.Runtime.InteropServices;
大きめのアイコン取得
(その2)
getBigIconToBMP
アイコン取得(簡単だけどイマイチ)
(その3)
makeNewIconByPathSimple
各形式のパス文字列を処理して、上記アイコン取得メソッドを呼ぶ makeNewIcon
ショートカットパスの解消 resolveShortCut //プロジェクトに"Windows Script Host Object Model"の参照追加(COM)
//using IWshRuntimeLibrary;
環境パス補完 getEnvPath
薄いアイコン:透明イメージの生成 makeTransImage

※高解像度のアイコンイメージ(透明部分)が汚いのが気になるところ(私の力不足・・・)

		private Bitmap makeNewIcon(String path, int sizetype)
		{
			if (path == null || path.Length < 1)
				return null;

			//パスの整形
			//""除去
			if (path[0] == '"')
			{
				int ie = path.IndexOf('"', 1);
				if (ie != -1)
				{
					path = path.Substring(1, ie - 1);
				}
			}
			//環境変数変換
			Regex r = new Regex(@"(%[^%]+%)",
			RegexOptions.IgnoreCase	| RegexOptions.Singleline);
			MatchCollection mc = r.Matches(path);
			foreach (Match m in mc)
			{
				path = path.Replace(m.Groups[1].Value
					, Environment.ExpandEnvironmentVariables(m.Groups[1].Value));
			}
			//環境パス補完
			path = getEnvPath(path);
			//ショートカット対応
			String ext = Path.GetExtension(path);
			ext = ext.ToLower();
			if (ext.Equals(".lnk"))
			{
				path = resolveShortCut(path);
			}

			Bitmap bm;
			switch (sizetype) {
				case 1:
					bm = getIconToBMP(Win32.SHGFI_LARGEICON, path);
					break;
				case 2:
					bm = getBigIconToBMP(Win32.SHGFI_EXTRALARGE, path);
					break;
				case 3:
					bm = getBigIconToBMP(Win32.SHGFI_JUMBO, path);
					break;
				case 0:
				default:
					bm = getIconToBMP(Win32.SHGFI_SMALLICON, path);
					break;
			}

			if (bm == null && System.IO.Directory.Exists(path))
			{
				//フォルダアイコンをセット
				//bm = folderbmp;
			}
			if (bm == null)
			{
				//適当にデフォルトアイコンをセット
			}

			return bm;
		}

		//Marshal :		using System.Runtime.InteropServices;
		//https://support.microsoft.com/ja-jp/kb/319350


		private Bitmap getIconToBMP(uint type, string path)
		{
			SHFILEINFO shinfo = new SHFILEINFO();
			IntPtr hImg; //the handle to the system image list

			try
			{
				//Use this to get the small Icon
				hImg = Win32.SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | type);
				IntPtr hicon = IntPtr.Zero;
				if (shinfo.hIcon == IntPtr.Zero)
				{
					path = getEnvPath(path);
					hImg = Win32.SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | type);
					if (shinfo.hIcon == IntPtr.Zero)
					{
						return null;
					}
				}
				//The icon is returned in the hIcon member of the shinfo struct
				return (System.Drawing.Icon.FromHandle(shinfo.hIcon)).ToBitmap();
			}
			finally
			{
				DestroyIcon(shinfo.hIcon);
			}
		}
		private Bitmap getBigIconToBMP(uint type, string path)
		{
			SHFILEINFO shinfo = new SHFILEINFO();
			IntPtr hImg; //the handle to the system image list

			try
			{
				//Use this to get the small Icon
				hImg = Win32.SHGetFileInfo(path, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_SYSICONINDEX);

				Win32.IImageList imglist = null;
				int rsult = Win32.SHGetImageList(type, ref Win32.IID_IImageList, out imglist);

				IntPtr hicon = IntPtr.Zero;
				imglist.GetIcon(shinfo.iIcon, (int)Win32.ILD_TRANSPARENT, ref hicon);

				//The icon is returned in the hIcon member of the shinfo struct
				return (System.Drawing.Icon.FromHandle(hicon)).ToBitmap();
			}
			finally
			{
				DestroyIcon(shinfo.hIcon);
			}
		}
		private Icon makeNewIconByPathSimple(string pname)
		{
			if (pname.Length < 1)
				return null;

			Icon ico;

			try
			{
				ico = Icon.ExtractAssociatedIcon(pname);
			}
			catch (Exception)
			{
				ico = SystemIcons.Application;
			}

			//bitmap = ico.ToBitmap();
			return ico;
		}
		private Bitmap makeTransImage(Bitmap _bitmap)
		{
			if (_bitmap == null)
				return null;
			Bitmap _transBitmap = new Bitmap(_bitmap.Size.Width, _bitmap.Size.Height);

			//ImageオブジェクトのGraphicsオブジェクトを作成する
			Graphics g = Graphics.FromImage(_transBitmap);

			//ColorMatrixオブジェクトの作成
			System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix();
			//ColorMatrixの行列の値を変更して、アルファ値が0.5に変更されるようにする
			cm.Matrix00 = 1F;
			cm.Matrix11 = 1F;
			cm.Matrix22 = 1F;
			cm.Matrix33 = 0.32F;
			cm.Matrix44 = 1F;

			//ImageAttributesオブジェクトの作成
			System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes();
			//ColorMatrixを設定する
			ia.SetColorMatrix(cm);

			//ImageAttributesを使用して画像を描画
			g.DrawImage(_bitmap, new Rectangle(0, 0, _bitmap.Width, _bitmap.Height),
				0, 0, _bitmap.Width, _bitmap.Height, GraphicsUnit.Pixel, ia);
			g.Dispose();
			return _transBitmap;
		}

		//プロジェクトに"Windows Script Host Object Model"の参照追加(COM)
		//using IWshRuntimeLibrary;

		private string resolveShortCut(string path)
		{
			//IWshShell shell = new WshShellClass();// IWshRuntimeLibrary の相互運用を外す(False)か下記の方式で記載する。

			//WshShellを作成
			IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
			IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(path);

			return shortcut.TargetPath;
		}

		private string getEnvPath(string cmdpath)
		{
			// 環境変数の取得(PATH要素)
			string variable = System.Environment.GetEnvironmentVariable("Path", System.EnvironmentVariableTarget.Process);

			// パスの分割
			string[] list = variable.Split(';');

			foreach (var path in list)
			{
				// 実体の存在チェック
				if (System.IO.File.Exists(System.IO.Path.Combine(path, cmdpath)))
				{
					return System.IO.Path.Combine(path, cmdpath);
				}
			}
			return "";
		}

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		[return: MarshalAs(UnmanagedType.Bool)]
		static extern bool DestroyIcon(IntPtr hIcon);

	}

	[StructLayout(LayoutKind.Sequential)]
	public struct SHFILEINFO
	{
		public IntPtr hIcon;
		public int iIcon;
		public uint dwAttributes;
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
		public string szDisplayName;
		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
		public string szTypeName;
	};

	class Win32
	{
		public const uint SHGFI_ICON = 0x100;
		public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
		public const uint SHGFI_SMALLICON = 0x1; // 'Small icon
		public const uint SHGFI_EXTRALARGE = 0x2; // '  icon
		public const uint SHGFI_JUMBO = 0x4; // ' icon
		public const uint SHGFI_SYSICONINDEX = 0x000004000;

		public const int ILD_TRANSPARENT = 0x1;

		[StructLayout(LayoutKind.Sequential)]
		public struct IMAGELISTDRAWPARAMS
		{
			public int cbSize;
			public IntPtr himl;
			public int i;
			public IntPtr hdcDst;
			public int x;
			public int y;
			public int cx;
			public int cy;
			public int xBitmap;    // x offest from the upperleft of bitmap
			public int yBitmap;    // y offset from the upperleft of bitmap
			public int rgbBk;
			public int rgbFg;
			public int fStyle;
			public int dwRop;
			public int fState;
			public int Frame;
			public int crEffect;
		}



		//IMAGE LIST
		public static Guid IID_IImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");

		[DllImport("shell32.dll")]
		public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

		[DllImport("shell32.dll", EntryPoint = "#727")]
		public static extern int SHGetImageList(uint iImageList, ref Guid riid, out IImageList ppv);

		[ComImportAttribute()]
		[GuidAttribute("46EB5926-582E-4017-9FDF-E8998DAA0950")]
		[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
		public interface IImageList
		{
			[PreserveSig]
			int Add(IntPtr hbmImage, IntPtr hbmMask, ref int pi);

			[PreserveSig]
			int ReplaceIcon(int i, IntPtr hicon, ref int pi);

			[PreserveSig]
			int SetOverlayImage(int iImage, int iOverlay);

			[PreserveSig]
			int Replace(int i, IntPtr hbmImage, IntPtr hbmMask);

			[PreserveSig]
			int AddMasked(IntPtr hbmImage, int crMask, ref int pi);

			[PreserveSig]
			int Draw(ref IMAGELISTDRAWPARAMS pimldp);

			[PreserveSig]
			int Remove(int i);

			[PreserveSig]
			int GetIcon(int i, int flags, ref IntPtr picon);
		}
	}

 

関連ページリンク

メソッド作成時に手を抜く方法(メソッドが引数、無名メソッド)【C#】

アプリケーションの設定を保存しておく方法【C#】

デバッグや通知に便利なメッセージ通知方法の使い分け【C#】

座標操作のメソッドの使い分け【C#】

クリップボード操作方法の原則【C#】

キーエミュレート送信のまとめ【C#】【覚書メモ】

 

 

Delicious にシェア
Digg にシェア
reddit にシェア
LinkedIn にシェア
LINEで送る
email this
Pocket

2,322 views.



コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です