OSDN Git Service

Merge branch 'master' of git.sourceforge.jp:/gitroot/applistation/AppliStation.git
[applistation/AppliStation.git] / AppliStation / AppliStation.Util / GUIUtils.cs
index 7e235d6..bd2a8ff 100644 (file)
@@ -1,7 +1,9 @@
 using System;\r
 using System.IO;\r
+using System.Runtime.InteropServices;\r
 using System.Drawing;\r
 using System.Drawing.Imaging;\r
+using System.Windows.Forms;\r
 using NaGet.Packages;\r
 using NaGet.Packages.Install;\r
 \r
@@ -12,6 +14,42 @@ namespace AppliStation.Util
        /// </summary>\r
        public sealed class GUIUtils\r
        {\r
+               #region アイコン関連\r
+               \r
+               #region ExtraIcon関連\r
+               \r
+               /// <summary>\r
+               /// アイコンファイル(実行ファイル・DLL)を開いてアイコンを作る\r
+               /// </summary>\r
+               /// <param name="form">ハンドラ</param>\r
+               /// <param name="lpszExeFileNameAndIndex">対象ファイルとアイコンインデックスの文字列表現</param>\r
+               /// <returns>生成されたアイコン。</returns>\r
+               public static Icon ExtractIcon(Form form, string lpszExeFileNameAndIndex)\r
+               {\r
+                       int index = lpszExeFileNameAndIndex.LastIndexOf(',');\r
+                       if (index >= 0) {\r
+                               uint nIconIndex = uint.Parse(lpszExeFileNameAndIndex.Substring(index+1));\r
+                               return NativeMethods.ExtractIcon(form, lpszExeFileNameAndIndex.Substring(0, index), nIconIndex);\r
+                       } else {\r
+                               return Icon.ExtractAssociatedIcon(lpszExeFileNameAndIndex);\r
+                       }\r
+               }\r
+               \r
+               /// <summary>\r
+               /// シェルからフォルダーアイコンを生成して返す\r
+               /// </summary>\r
+               /// <returns>フォルダーアイコン</returns>\r
+               public static Icon ShellIconForFolder\r
+               {\r
+                       get {\r
+                               // Vista以降ならば、SHGetStockIconInfo(SIID_FOLDER, SHGSI_ICON, &sInfo); をP/Invoke呼び出しするのが王道かと\r
+                               string windir = Environment.GetEnvironmentVariable("windir");\r
+                               return NativeMethods.ExtractIcon(null, Path.Combine(windir, @"system32\shell32.dll"), 3);\r
+                       }\r
+               }\r
+               \r
+               #endregion\r
+               \r
                /// <summary>\r
                /// パッケージに対応するアイコンを返す\r
                /// </summary>\r
@@ -19,29 +57,31 @@ namespace AppliStation.Util
                /// <returns>対応するアイコン。検出できなかった場合はnull。</returns>\r
                public static Icon GetIconForPackage(InstalledPackage pkg)\r
                {\r
-                       string iconPath = pkg.UninstallInfo.IconPath;\r
-                       if (! string.IsNullOrEmpty(iconPath)) {\r
-                               if (iconPath.EndsWith(",0") || iconPath.EndsWith(",-0")) {\r
-                                       iconPath = iconPath.Substring(0, iconPath.LastIndexOf(','));\r
-                               }\r
-                               if (File.Exists(iconPath)) {\r
-                                       return Icon.ExtractAssociatedIcon(iconPath);\r
-                               }\r
-                       } else if (pkg.Type == InstallerType.ARCHIVE) {\r
-                               string progGrp = Path.Combine(NaGet.Env.ArchiveProgramGroup, pkg.Name);\r
-                               if (Directory.Exists(progGrp)) {\r
-                                       string[] lnkFiles = Directory.GetFiles(progGrp, "*.lnk");\r
-                                       \r
-                                       if (lnkFiles.Length >= 1) {\r
-                                               using (NaGet.InteropServices.ShellLink link = new NaGet.InteropServices.ShellLink(lnkFiles[0])) {\r
-                                                       if (File.Exists(link.GetPath(0))) {\r
-                                                               return Icon.ExtractAssociatedIcon(link.GetPath(0));\r
+                       Icon ico = null;\r
+                       try {\r
+                               string iconPath = pkg.UninstallInfo.IconPath;\r
+                               if (! string.IsNullOrEmpty(iconPath)) {\r
+                                       ico = ExtractIcon(null, iconPath);\r
+                               } else if ((pkg.Type == InstallerType.ARCHIVE)\r
+                                          ||(pkg.Type == InstallerType.ITSELF)) {\r
+                                       string progGrp = Path.Combine(NaGet.Env.ArchiveProgramGroup, pkg.Name);\r
+                                       if (Directory.Exists(progGrp)) {\r
+                                               string[] lnkFiles = Directory.GetFiles(progGrp, "*.lnk");\r
+                                               \r
+                                               if (lnkFiles.Length >= 1) {\r
+                                                       using (NaGet.InteropServices.ShellLink link = new NaGet.InteropServices.ShellLink(lnkFiles[0])) {\r
+                                                               if (File.Exists(link.GetPath(0))) {\r
+                                                                       ico = Icon.ExtractAssociatedIcon(link.GetPath(0));\r
+                                                               }\r
                                                        }\r
                                                }\r
                                        }\r
                                }\r
+                       } catch (System.Runtime.InteropServices.COMException) {\r
+                               // ShellLinkのオープンあるいは、リンク先解決に失敗した場合\r
+                       } catch (Exception) {\r
                        }\r
-                       return null;\r
+                       return ico;\r
                }\r
                \r
                /// <summary>\r
@@ -57,11 +97,11 @@ namespace AppliStation.Util
                        const float b = 0.114478f;\r
                        \r
                        ColorMatrix cm = new ColorMatrix(new float[][]{\r
-                               new float[]{r, r, r, 0, 0},\r
-                               new float[]{g, g, g, 0, 0},\r
-                               new float[]{b, b, b, 0, 0},\r
+                               new float[]{r, r, r,     0, 0},\r
+                               new float[]{g, g, g,     0, 0},\r
+                               new float[]{b, b, b,     0, 0},\r
                                new float[]{0, 0, 0, alpha, 0},\r
-                               new float[]{0, 0, 0, 0, 1},\r
+                               new float[]{0, 0, 0,     0, 1},\r
                         });\r
                        ImageAttributes ia = new ImageAttributes();\r
                        ia.SetColorMatrix(cm);\r
@@ -69,6 +109,13 @@ namespace AppliStation.Util
                        return ia;\r
                }\r
                \r
+               /// <summary>\r
+               /// 画像を指定領域の真中に描く\r
+               /// </summary>\r
+               /// <param name="g">描画対象のグラフィックス</param>\r
+               /// <param name="img">画像</param>\r
+               /// <param name="b">指定領域</param>\r
+               /// <param name="ia">ImageAttributes。nullでもかまわない</param>\r
                public static void Graphics_DrawCenterImage(Graphics g, Image img, Rectangle b, ImageAttributes ia)\r
                {\r
                        int x = b.Left + (b.Width  - img.Width ) / 2;\r
@@ -79,5 +126,30 @@ namespace AppliStation.Util
                                    0, 0, img.Width, img.Height,\r
                                    GraphicsUnit.Pixel, ia);\r
                }\r
+               \r
+               #endregion\r
+               \r
+               #region CheckedListBox関連\r
+               \r
+               /// <summary>\r
+               /// チェックリストボックスのアイテムをスワップする\r
+               /// </summary>\r
+               /// <param name="checkedListBox">操作対象のCheckedListBox</param>\r
+               /// <param name="indexA">アイテムインデックス</param>\r
+               /// <param name="indexB">アイテムインデックス</param>\r
+               /// <remarks>インデックス値のチェックは本メソッドでは行っていない</remarks>\r
+               public static void CheckedListBox_SwapItems(CheckedListBox checkedListBox, int indexA, int indexB) {\r
+                       int itemCount = checkedListBox.Items.Count;\r
+                       object tempItem          = checkedListBox.Items[indexA];\r
+                       CheckState tempState = checkedListBox.GetItemCheckState(indexA);\r
+                       \r
+                       checkedListBox.Items[indexA] = checkedListBox.Items[indexB];\r
+                       checkedListBox.SetItemCheckState(indexA, checkedListBox.GetItemCheckState(indexB));\r
+                       \r
+                       checkedListBox.Items[indexB] = tempItem;\r
+                       checkedListBox.SetItemCheckState(indexB, tempState);\r
+               }\r
+               \r
+               #endregion\r
        }\r
 }\r