OSDN Git Service

na-get-lib,パフォーマンスチューニングなど(動作変更なし)
[applistation/AppliStation.git] / AppliStation / AppliStation.Util / GUIUtils.cs
1 using System;\r
2 using System.IO;\r
3 using System.Runtime.InteropServices;\r
4 using System.Drawing;\r
5 using System.Drawing.Imaging;\r
6 using System.Windows.Forms;\r
7 using NaGet.Packages;\r
8 using NaGet.Packages.Install;\r
9 \r
10 namespace AppliStation.Util\r
11 {\r
12         /// <summary>\r
13         /// GUIに関する雑多な関数\r
14         /// </summary>\r
15         public sealed class GUIUtils\r
16         {\r
17                 #region アイコン関連\r
18                 \r
19                 #region ExtraIcon関連\r
20                 \r
21                 [DllImport("shell32.dll")]\r
22                 private static extern IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex);\r
23                 \r
24                 [DllImport("user32.dll", SetLastError=true)]\r
25                 [return: MarshalAs(UnmanagedType.Bool)]\r
26                 private static extern bool DestroyIcon(IntPtr hIcon);\r
27                 \r
28                 /// <summary>\r
29                 /// アイコンファイル(実行ファイル・DLL)を開いてアイコンを作る\r
30                 /// </summary>\r
31                 /// <remarks>内部でコピーされるのでWin32APIのDestroyIconを使わないでいいが、やや遅い動作</remarks>\r
32                 /// <param name="form">ハンドラ</param>\r
33                 /// <param name="lpszExeFileName">対象ファイル</param>\r
34                 /// <param name="nIconIndex">アイコンインデックス</param>\r
35                 /// <returns>生成されたアイコン</returns>\r
36                 public static Icon ExtractIcon(Form form, string lpszExeFileName, uint nIconIndex)\r
37                 {\r
38                         Icon ico = null;\r
39                         \r
40                         if (! File.Exists(lpszExeFileName)) {\r
41                                 ico = Icon.ExtractAssociatedIcon(lpszExeFileName); // ExtractAssociatedIconに例外を吐いてもらう\r
42                         } else {\r
43                                 IntPtr hInst = (form != null)? form.Handle : IntPtr.Zero;\r
44                                 IntPtr hIcon = IntPtr.Zero;\r
45                                 \r
46                                 try {\r
47                                         hIcon = ExtractIcon(hInst, lpszExeFileName, (int) nIconIndex);\r
48                                         if ((hIcon != IntPtr.Zero) && (hIcon.ToInt32() != 2)) {\r
49                                                 ico = (Icon) Icon.FromHandle(hIcon).Clone();\r
50                                                 DestroyIcon(hIcon);\r
51                                         }\r
52                                 } catch (System.Runtime.InteropServices.COMException) {\r
53                                         // ExtraIconのP/Invoke失敗時用\r
54                                 }\r
55                         }\r
56                         return ico;\r
57                 }\r
58                 \r
59                 /// <summary>\r
60                 /// アイコンファイル(実行ファイル・DLL)を開いてアイコンを作る\r
61                 /// </summary>\r
62                 /// <param name="form">ハンドラ</param>\r
63                 /// <param name="lpszExeFileNameAndIndex">対象ファイルとアイコンインデックスの文字列表現</param>\r
64                 /// <returns>生成されたアイコン。</returns>\r
65                 public static Icon ExtractIcon(Form form, string lpszExeFileNameAndIndex)\r
66                 {\r
67                         int index = lpszExeFileNameAndIndex.LastIndexOf(',');\r
68                         if (index >= 0) {\r
69                                 uint nIconIndex = uint.Parse(lpszExeFileNameAndIndex.Substring(index+1));\r
70                                 return ExtractIcon(form, lpszExeFileNameAndIndex.Substring(0, index), nIconIndex);\r
71                         } else {\r
72                                 return Icon.ExtractAssociatedIcon(lpszExeFileNameAndIndex);\r
73                         }\r
74                 }\r
75                 \r
76                 /// <summary>\r
77                 /// シェルからフォルダアイコンを生成して返す\r
78                 /// </summary>\r
79                 /// <returns>フォルダアイコン</returns>\r
80                 public static Icon GetShellIconForFolder()\r
81                 {\r
82                         // Vista以降ならば、SHGetStockIconInfo(SIID_FOLDER, SHGSI_ICON, &sInfo); をP/Invoke呼び出しするのが王道かと\r
83                         string windir = Environment.GetEnvironmentVariable("windir");\r
84                         return ExtractIcon(null, Path.Combine(windir, @"system32\shell32.dll"), 3);\r
85                 }\r
86                 \r
87                 #endregion\r
88                 \r
89                 /// <summary>\r
90                 /// パッケージに対応するアイコンを返す\r
91                 /// </summary>\r
92                 /// <param name="pkg">パッケージ</param>\r
93                 /// <returns>対応するアイコン。検出できなかった場合はnull。</returns>\r
94                 public static Icon GetIconForPackage(InstalledPackage pkg)\r
95                 {\r
96                         Icon ico = null;\r
97                         string iconPath = pkg.UninstallInfo.IconPath;\r
98                         if (! string.IsNullOrEmpty(iconPath)) {\r
99                                 try {\r
100                                         ico = ExtractIcon(null, iconPath);\r
101                                 } catch (FileNotFoundException) {\r
102                                         ico = null;\r
103                                 }\r
104                         } else if ((pkg.Type == InstallerType.ARCHIVE)\r
105                                    ||(pkg.Type == InstallerType.ITSELF)) {\r
106                                 string progGrp = Path.Combine(NaGet.Env.ArchiveProgramGroup, pkg.Name);\r
107                                 if (Directory.Exists(progGrp)) {\r
108                                         string[] lnkFiles = Directory.GetFiles(progGrp, "*.lnk");\r
109                                         \r
110                                         if (lnkFiles.Length >= 1) {\r
111                                                 try {\r
112                                                         using (NaGet.InteropServices.ShellLink link = new NaGet.InteropServices.ShellLink(lnkFiles[0])) {\r
113                                                                 if (File.Exists(link.GetPath(0))) {\r
114                                                                         ico = Icon.ExtractAssociatedIcon(link.GetPath(0));\r
115                                                                 }\r
116                                                         }\r
117                                                 } catch (System.Runtime.InteropServices.COMException) {\r
118                                                         // ShellLinkのオープンあるいは、リンク先解決に失敗した場合\r
119                                                 }\r
120                                         }\r
121                                 }\r
122                         }\r
123                         return ico;\r
124                 }\r
125                 \r
126                 /// <summary>\r
127                 /// グレーアウトアイコンを作るための ImageAttributes を作って返す。\r
128                 /// </summary>\r
129                 /// <param name="alpha">透明度。(1.0が不透明、0.0が完全透明)</param>\r
130                 /// <returns>生成されたImageAttributes</returns>\r
131                 public static ImageAttributes GetImageAttributeToGrayOut(float alpha)\r
132                 {\r
133                         // RGB比率として、YIQカラーモデルの値を採用する\r
134                         const float r = 0.298912f;\r
135                         const float g = 0.586611f;\r
136                         const float b = 0.114478f;\r
137                         \r
138                         ColorMatrix cm = new ColorMatrix(new float[][]{\r
139                                 new float[]{r, r, r,     0, 0},\r
140                                 new float[]{g, g, g,     0, 0},\r
141                                 new float[]{b, b, b,     0, 0},\r
142                                 new float[]{0, 0, 0, alpha, 0},\r
143                                 new float[]{0, 0, 0,     0, 1},\r
144                          });\r
145                         ImageAttributes ia = new ImageAttributes();\r
146                         ia.SetColorMatrix(cm);\r
147                         \r
148                         return ia;\r
149                 }\r
150                 \r
151                 /// <summary>\r
152                 /// 画像を指定領域の真中に描く\r
153                 /// </summary>\r
154                 /// <param name="g">描画対象のグラフィックス</param>\r
155                 /// <param name="img">画像</param>\r
156                 /// <param name="b">指定領域</param>\r
157                 /// <param name="ia">ImageAttributes。nullでもかまわない</param>\r
158                 public static void Graphics_DrawCenterImage(Graphics g, Image img, Rectangle b, ImageAttributes ia)\r
159                 {\r
160                         int x = b.Left + (b.Width  - img.Width ) / 2;\r
161                         int y = b.Top  + (b.Height - img.Height) / 2;\r
162                         \r
163                         g.DrawImage(img,\r
164                                     new Rectangle(x, y, img.Width, img.Height),\r
165                                     0, 0, img.Width, img.Height,\r
166                                     GraphicsUnit.Pixel, ia);\r
167                 }\r
168 \r
169                 #endregion\r
170                 \r
171                 #region CheckedListBox関連\r
172                 \r
173                 /// <summary>\r
174                 /// チェックリストボックスのアイテムをスワップする\r
175                 /// </summary>\r
176                 /// <param name="checkedListBox">操作対象のCheckedListBox</param>\r
177                 /// <param name="indexA">アイテムインデックス</param>\r
178                 /// <param name="indexB">アイテムインデックス</param>\r
179                 /// <remarks>インデックス値のチェックは本メソッドでは行っていない</remarks>\r
180                 public static void CheckedListBox_SwapItems(CheckedListBox checkedListBox, int indexA, int indexB) {\r
181                         int itemCount = checkedListBox.Items.Count;\r
182                         object tempItem          = checkedListBox.Items[indexA];\r
183                         CheckState tempState = checkedListBox.GetItemCheckState(indexA);\r
184                         \r
185                         checkedListBox.Items[indexA] = checkedListBox.Items[indexB];\r
186                         checkedListBox.SetItemCheckState(indexA, checkedListBox.GetItemCheckState(indexB));\r
187                         \r
188                         checkedListBox.Items[indexB] = tempItem;\r
189                         checkedListBox.SetItemCheckState(indexB, tempState);\r
190                 }\r
191                 \r
192                 #endregion\r
193         }\r
194 }\r