OSDN Git Service

AppliStation-GUI,Windows7対応におけるtypoを修正
[applistation/AppliStation.git] / AppliStation / AppliStation.Util / NativeMethods.cs
1 // Vistaの効果を有効にするフラグ(不要の場合はコメントアウト)\r
2 #define USE_VISTA_EFFECTS\r
3 \r
4 // Sevenの効果を有効にするフラグ(不要の場合はコメントアウト)\r
5 #define USE_SEVEN_EFFECTS\r
6 \r
7 using System;\r
8 using System.Runtime.InteropServices;\r
9 using System.Windows.Forms;\r
10 using System.Drawing;\r
11 \r
12 namespace AppliStation.Util\r
13 {\r
14         /// <summary>\r
15         /// Win32ネイティブメソッドを叩いてGUI操作するための関数群のクラス\r
16         /// </summary>\r
17         public sealed class NativeMethods\r
18         {\r
19                 /// <summary>\r
20                 /// 呼び出し禁止\r
21                 /// </summary>\r
22                 private NativeMethods()\r
23                 {\r
24                 }\r
25 \r
26                 #region 進捗の表示\r
27                 \r
28                 /// <summary>\r
29                 /// プログレスバーステータス(色)\r
30                 /// </summary>\r
31                 public enum ProgressBarState\r
32                 {\r
33                         /// <summary>\r
34                         /// 通常の状態(PBST_NORMAL)。デフォルトの設定では緑色。\r
35                         /// </summary>\r
36                         Normal = 0,\r
37                         /// <summary>\r
38                         /// エラーの状態(PBST_ERROR)。デフォルトの設定では赤色。\r
39                         /// </summary>\r
40                         Error = 1,\r
41                         /// <summary>\r
42                         /// 停止の状態(PBST_PAUSED)。デフォルトの設定では黄色。\r
43                         /// </summary>\r
44                         Paused = 2,\r
45                 }\r
46                 \r
47                 /// <summary>\r
48                 /// WindowsVista以降向け、プログレスバーステータス(色)を設定する。\r
49                 /// </summary>\r
50                 /// <param name="progBar">対象のプログレスバー</param>\r
51                 /// <param name="state">状態(色)</param>\r
52                 public static void ProgressBar_SetState(ProgressBar progBar, ProgressBarState state)\r
53                 {\r
54 #if USE_VISTA_EFFECTS\r
55                         try {\r
56                                 // SendMessage(progressBar.Handle, PBM_SETSTATE, state, 0);\r
57                                 SendMessage(progBar.Handle, 0x410, new IntPtr((int) state), IntPtr.Zero);\r
58                         } catch (Exception) {\r
59                         }\r
60 #endif\r
61                 }\r
62                 \r
63                 #region タスクバー上の進捗表示のためのP/Invoke\r
64                         \r
65                 internal enum TBPFLAG\r
66                 {\r
67                         TBPF_NOPROGRESS = 0,\r
68                         TBPF_INDETERMINATE = 0x1,\r
69                         TBPF_NORMAL = 0x2,\r
70                         TBPF_ERROR = 0x4,\r
71                         TBPF_PAUSED = 0x8,\r
72                 }\r
73                 \r
74                 [ComImport()]\r
75                 [Guid("EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF")]\r
76                 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\r
77                 internal interface ITaskList3\r
78                 {\r
79                         void HrInit();\r
80                         void AddTab(IntPtr hWnd);\r
81                         void DeleteTab(IntPtr hWnd);\r
82                         void ActivateTab(IntPtr hWnd);\r
83                         void SetActiveAlt(IntPtr hWnd);\r
84                         void MarkFullscreenWindow(IntPtr hWnd, int fFullscreen);\r
85                         void SetProgressValue(IntPtr hWnd, ulong ullCompleted, ulong ullTotal);\r
86                         void SetProgressState(IntPtr hWnd, TBPFLAG tbpFlags);\r
87                         // more functions follows, but we do not need these.\r
88                 }\r
89                 \r
90                 [ComImport()]\r
91                 [Guid("56FDF344-FD6D-11d0-958A-006097C9A090")]\r
92                 [ClassInterface(ClassInterfaceType.None)]\r
93                 internal class CTaskbarList\r
94                 {\r
95                 }\r
96                 \r
97                 #endregion\r
98                 \r
99                 /// <summary>\r
100                 /// タスクバに進捗を設定する。\r
101                 /// </summary>\r
102                 /// <param name="form">対象フォーム</param>\r
103                 /// <param name="style">表示スタイル</param>\r
104                 /// <param name="state">ステータス(色)</param>\r
105                 /// <param name="val">プログレスバーの値。0を指定すると進捗表示をしない</param>\r
106                 /// <param name="maximum">プログレスバーの最大値。</param>\r
107                 public static void Form_SetTaskbarProgressParams(Form form, ProgressBarStyle style, ProgressBarState state, ulong val, ulong maximum)\r
108                 {\r
109 #if USE_VISTA_EFFECTS\r
110 #if USE_SEVEN_EFFECTS\r
111                         ITaskList3 tasklist = null;\r
112                         \r
113                         try {\r
114                                 TBPFLAG tbpFlag = TBPFLAG.TBPF_NOPROGRESS;\r
115                                 \r
116                                 if (style == ProgressBarStyle.Marquee) {\r
117                                         tbpFlag |= TBPFLAG.TBPF_INDETERMINATE;\r
118                                 } else if (val > 0 && maximum > 0) {\r
119                                         tbpFlag |= TBPFLAG.TBPF_NORMAL;\r
120                                 }\r
121                                 \r
122                                 if (state == ProgressBarState.Error) {\r
123                                         tbpFlag |= TBPFLAG.TBPF_ERROR;\r
124                                 }\r
125                                 if (state == ProgressBarState.Paused) {\r
126                                         tbpFlag |= TBPFLAG.TBPF_PAUSED;\r
127                                 }\r
128                                 \r
129                                 tasklist = (ITaskList3) new CTaskbarList();\r
130                                 tasklist.HrInit();\r
131                                 \r
132                                 tasklist.SetProgressState(form.Handle, tbpFlag);\r
133                                 tasklist.SetProgressValue(form.Handle, val, maximum);\r
134                         } finally {\r
135                                 if (tasklist != null) {\r
136                                         Marshal.ReleaseComObject(tasklist);\r
137                                         tasklist = null;\r
138                                 }\r
139                         }\r
140 #endif\r
141 #endif\r
142                 }\r
143                 \r
144                 #endregion\r
145                         \r
146                 #region タスクバーおよびタイトルバーのフラッシュ\r
147                 \r
148                 /// <summary>\r
149                 /// タスクバーおよびタイトルバーボタンのフラッシュの設定フラグ\r
150                 /// </summary>\r
151                 public enum FlashFlag : uint {\r
152                         /// <summary>\r
153                         /// 点滅の停止\r
154                         /// </summary>\r
155                         Stop = 0,\r
156                         /// <summary>\r
157                         /// タイトルバーを点滅\r
158                         /// </summary>\r
159                         Caption = 1,\r
160                         /// <summary>\r
161                         /// タスクバーボタンを点滅\r
162                         /// </summary>\r
163                         Tray = 2,\r
164                         /// <summary>\r
165                         /// タイトルバーとタスクバーボタンを点滅\r
166                         /// </summary>\r
167                         All = 3,\r
168                         /// <summary>\r
169                         /// Stopが設定されるまで点滅する\r
170                         /// </summary>\r
171                         Timer = 4,\r
172                         /// <summary>\r
173                         /// フォアグラウンドの状態になるまで点滅\r
174                         /// </summary>\r
175                         TimerNoFG = 12,\r
176                 }\r
177                 \r
178                 [StructLayout(LayoutKind.Sequential)]\r
179                 struct FLASHWINFO\r
180                 {\r
181                     public int cbSize;\r
182                     public IntPtr hWnd;\r
183                     public FlashFlag dwFlags;\r
184                     public uint uCount;\r
185                     public uint dwTimeout;\r
186                 }\r
187                 \r
188                 /// <summary>\r
189                 /// タスクバーおよびタイトルバーボタンを点滅させる\r
190                 /// </summary>\r
191                 /// <param name="form">対象フォーム</param>\r
192                 /// <param name="flag">点滅パラメータフラグ</param>\r
193                 /// <param name="count">点滅回数</param>\r
194                 /// <param name="timeout">点滅の間隔(ミリ秒)</param>\r
195                 /// <returns></returns>\r
196                 public static bool Form_FlashWindow(Form form, FlashFlag flag, uint count, uint timeout)\r
197                 {\r
198                         try {\r
199                                 FLASHWINFO info = new FLASHWINFO();\r
200                                 info.cbSize = Marshal.SizeOf(typeof(FLASHWINFO));\r
201                                 info.hWnd = form.Handle;\r
202                                 info.dwFlags = flag;\r
203                                 info.uCount = count;\r
204                                 info.dwTimeout = timeout;\r
205                                 \r
206                                 return FlashWindowEx(ref info) == 0;\r
207                         } catch (Exception) {\r
208                                 return false;\r
209                         }\r
210                 }\r
211                 \r
212                 [DllImport("user32.dll")]\r
213                 static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi);\r
214                 \r
215                 #endregion\r
216                 \r
217                 #region ListView関連\r
218                 \r
219                 /// <summary>\r
220                 /// リストビューにダブルバッファでの描画をするか否かを設定する\r
221                 /// </summary>\r
222                 /// <remarks>マウスでの選択に半透明ツールを採用するか否かもこの設定に依存</remarks>\r
223                 /// <param name="listView">対象のリストビュー</param>\r
224                 /// <param name="bEnable">ダブルバッファでの描画をするとき<code>true</code></param>\r
225                 public static void ListView_SetDoubleBuffer(ListView listView, bool bEnable)\r
226                 {\r
227                         try {\r
228                                 // SendMessage(listView.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_DOUBLEBUFFER, bEnable? LVS_EX_DOUBLEBUFFER:0);\r
229                                 SendMessage(listView.Handle, 0x1036, new IntPtr(0x00010000), new IntPtr((bEnable)? 0x00010000u:0x0u));\r
230                         } catch (Exception) {\r
231                         }\r
232                 }\r
233                 \r
234                 /// <summary>\r
235                 /// 選択されたアイテムの部分の背景にグラデーションがかかった感じになる、\r
236                 /// Vista以降でのエクスプローラの見た目をListViewに反映させる。\r
237                 /// </summary>\r
238                 /// <remarks>Vista未満のバージョンでは何もしない。</remarks>\r
239                 /// <param name="listView">対象のListView</param>\r
240                 public static void ListView_EnableVistaExplorerTheme(ListView listView)\r
241                 {\r
242 #if USE_VISTA_EFFECTS\r
243                         // Vista未満はなにもしない\r
244                         OperatingSystem os = Environment.OSVersion;\r
245                         if (os.Platform != PlatformID.Win32NT || os.Version.Major < 6) return;\r
246                         \r
247                         try {\r
248                                 SetWindowTheme(listView.Handle, "explorer", null);\r
249                         } catch (Exception) {\r
250                         }\r
251 #endif\r
252                 }\r
253                 \r
254                 /// <summary>\r
255                 /// ヘッダに"すべて選択"に似たチェックボックスを作るか否かを指定する\r
256                 /// </summary>\r
257                 /// <remarks>このオプションを設定するとVistaエクスプローラでの「チェックボックスを使用して項目を選択する」と同様の動作になる</remarks>\r
258                 /// <param name="listView">対象のListBox</param>\r
259                 /// <param name="bAutoCheckSelect">チェックボックスを使用して項目を選択するとき<code>true</code></param>\r
260                 public static void ListView_SetAutoCheckSelect(ListView listView, bool bAutoCheckSelect)\r
261                 {\r
262 #if USE_VISTA_EFFECTS\r
263                         try {\r
264                                 // SendMessage(listView.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_AUTOCHECKSELECT, bAutoCheckSelect?LVS_EX_AUTOCHECKSELECT:0);\r
265                                 SendMessage(listView.Handle, 0x1036, new IntPtr(0x08000000), new IntPtr((bAutoCheckSelect)?0x08000000u:0x0u));\r
266                         } catch (Exception) {\r
267                         }\r
268 #endif\r
269                 }\r
270                 \r
271                 #region ColumnHeaderのソートの三角印用\r
272                 \r
273                 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]\r
274                 private struct HD_ITEM\r
275                 {\r
276                         public uint    mask;\r
277                         public int     cxy;\r
278                         [MarshalAs(UnmanagedType.LPTStr)]public string   pszText;\r
279                         public IntPtr   hbm;\r
280                         public int     cchTextMax;\r
281                         public int     fmt;\r
282                         [MarshalAs(UnmanagedType.LPTStr)]public string  lParam;\r
283                         public int     iImage;        // index of bitmap in ImageList\r
284                         public int     iOrder;\r
285                 }\r
286                 \r
287                 /// <summary>\r
288                 /// WinXP以降、ソートの矢印を表示\r
289                 /// </summary>\r
290                 /// <param name="listView">対象のListView</param>\r
291                 /// <param name="column">表示する矢印のヘッダ</param>\r
292                 /// <param name="order">ソートの昇順・降順</param>\r
293                 public static void ColumnHeader_SetSortState(ListView listView, int column, SortOrder order)\r
294                 {\r
295                         try {\r
296                                 // SendMessage(hWnd, LVM_GETHEADER, NULL, NULL);\r
297                                 IntPtr hWnd = SendMessage(listView.Handle, 0x101F, IntPtr.Zero, IntPtr.Zero);\r
298                                 \r
299                                 HD_ITEM hdi = new HD_ITEM();\r
300                                 hdi.mask = 0x0004; // HDI_FORMAT;\r
301                                 for (int i = 0; i < listView.Columns.Count; i++) {\r
302                                         // SendMessage(hWnd, HDM_GETITEMW, i, &hdi);\r
303                                         SendMessage(hWnd, 0x120b, new IntPtr(i), ref hdi);\r
304                                         \r
305                                         const int HDF_SORTUP = 0x400;\r
306                                         const int HDF_SORTDOWN = 0x200;\r
307                                         \r
308                                         if (i != column || order == SortOrder.None) {\r
309                                                 hdi.fmt = hdi.fmt & ~(HDF_SORTUP | HDF_SORTDOWN);\r
310                                         } else if (order == SortOrder.Ascending) { // 昇順\r
311                                                 hdi.fmt = hdi.fmt & ~HDF_SORTDOWN | HDF_SORTUP;\r
312                                         } else if (order == SortOrder.Descending) { // 降順\r
313                                                 hdi.fmt = hdi.fmt & ~HDF_SORTUP | HDF_SORTDOWN;\r
314                                         }\r
315                                         \r
316                                         // SendMessage(hWnd, HDM_SETITEMW, i, &hdi);\r
317                                         SendMessage(hWnd, 0x120c, new IntPtr(i), ref hdi);\r
318                                 }\r
319                         } catch (Exception) {\r
320                         }\r
321                 }\r
322                 \r
323                 /// <summary>\r
324                 /// ヘッダ部のサイズを返す\r
325                 /// </summary>\r
326                 /// <param name="listView">ListView</param>\r
327                 /// <returns>ヘッダ部のクライアントサイズ</returns>\r
328                 public static Size ColumnHeader_GetSize(ListView listView)\r
329                 {\r
330                         LRECT lrect;\r
331                         \r
332                         try {\r
333                                 // SendMessage(hWnd, LVM_GETHEADER, NULL, NULL);\r
334                                 IntPtr hWnd = SendMessage(listView.Handle, 0x101F, IntPtr.Zero, IntPtr.Zero);\r
335                                 GetClientRect(hWnd, out lrect);\r
336                         } catch {\r
337                                 lrect.Left = lrect.Right = lrect.Top = lrect.Bottom = 0;\r
338                         }\r
339                         \r
340                         Size size = new Size(lrect.Right - lrect.Left,\r
341                                         lrect.Bottom - lrect.Top);\r
342                         return size;\r
343                 }\r
344                 \r
345                 #endregion\r
346                 \r
347                 #endregion\r
348                 \r
349                 #region EnableWindow(コメントアウト)\r
350 //              /// <summary>\r
351 //              /// 指定されたコントロール(ウィンドウ)への、\r
352 //              /// キーボード入力およびマウス入力を有効化または無効化\r
353 //              /// </summary>\r
354 //              /// <param name="control">対象のコントロールのハンドラ</param>\r
355 //              /// <param name="bEnable">有効にするか無効にするかを指定</param>\r
356 //              /// <returns>直前にウィンドウが無効状態だった場合はtrueを返す</returns>\r
357 //              public static bool Control_EnableWindow(Control ctrl, bool bEnable)\r
358 //              {\r
359 //                      try {\r
360 //                              return EnableWindow(ctrl.Handle, bEnable);\r
361 //                      } catch {\r
362 //                              ctrl.Enabled = bEnable;\r
363 //                              return true;\r
364 //                      }\r
365 //              }\r
366 //              \r
367 //              /// <summary>\r
368 //              /// 指定されたコントロール(ウィンドウ)への、\r
369 //              /// キーボード入力およびマウス入力を有効化または無効化\r
370 //              /// </summary>\r
371 //              /// <param name="control">対象のコントロールのハンドラ</param>\r
372 //              /// <param name="bEnable">有効にするか無効にするかを指定</param>\r
373 //              /// <returns>直前にウィンドウが無効状態だった場合はtrueを返す</returns>\r
374 //              [DllImport("user32.dll")]\r
375 //              public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);\r
376                 #endregion\r
377                 \r
378                 #region RichTextBox関連\r
379                 \r
380                 [StructLayout(LayoutKind.Sequential)]\r
381                 private struct CHARFORMAT2\r
382                 {\r
383                         public int cbSize;\r
384                         public uint dwMask;\r
385                         public uint dwEffects;\r
386                         public int yHeight;\r
387                         public int yOffset;\r
388                         public int crTextColor;\r
389                         public byte bCharSet;\r
390                         public byte bPitchAndFamily;\r
391                         [MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]\r
392                         public char[] szFaceName;\r
393                         public short wWeight;\r
394                         public short sSpacing;\r
395                         public int crBackColor;\r
396                         public int LCID;\r
397                         public uint dwReserved;\r
398                         public short sStyle;\r
399                         public short wKerning;\r
400                         public byte bUnderlineType;\r
401                         public byte bAnimation;\r
402                         public byte bRevAuthor;\r
403                         public byte bReserved1;\r
404                 }\r
405                 \r
406                 /// <summary>\r
407                 /// リッチテキストの選択部分に文字フォーマット効果を与える\r
408                 /// </summary>\r
409                 /// <param name="richTextBox">対象のリッチテキストボックス</param>\r
410                 /// <param name="dwMask">有効な文字フォーマット効果</param>\r
411                 /// <param name="dwEffect">文字フォーマット効果のフラグ</param>\r
412                 public static void RichTextBox_SetSelectionFormat(RichTextBox richTextBox, uint dwMask, uint dwEffect)\r
413                 {\r
414                         CHARFORMAT2 cfmt = new CHARFORMAT2();\r
415                         cfmt.cbSize = Marshal.SizeOf(typeof(CHARFORMAT2));\r
416                         cfmt.dwMask = dwMask;\r
417                         cfmt.dwEffects = dwEffect;\r
418                         \r
419                         //SendMessage(richTextBox.Handle, EM_SETCHARFORMAT, SCF_SELECTION, ref cfmt);\r
420                         SendMessage(richTextBox.Handle, 0x0444, new IntPtr(0x0001), ref cfmt);\r
421                 }\r
422                 /// <summary>\r
423                 /// リッチテキストにテキストリンクを追加する\r
424                 /// </summary>\r
425                 /// <param name="richTextBox">対象のリッチテキストボックス</param>\r
426                 /// <param name="text">追加するテキスト</param>\r
427                 public static void RichTextBox_AddTextLink(RichTextBox richTextBox, string text)\r
428                 {\r
429                         int pos = richTextBox.TextLength;\r
430                         richTextBox.Select(pos,0);\r
431                         richTextBox.SelectedText = text;\r
432                         richTextBox.Select(pos, text.Length);\r
433                         \r
434                         // RichTextBox_SetSelectionFormat(richTextBox, CFM_LINK, CFE_LINK);\r
435                         RichTextBox_SetSelectionFormat(richTextBox, 0x00000020, 0x0020);\r
436                         \r
437                         richTextBox.Select(richTextBox.TextLength, 0);\r
438                 }\r
439                 \r
440                 #endregion\r
441                 \r
442                 #region アイコン関連\r
443                 \r
444                 [DllImport("shell32.dll")]\r
445                 private static extern IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex);\r
446                 \r
447                 [DllImport("user32.dll", SetLastError=true)]\r
448                 [return: MarshalAs(UnmanagedType.Bool)]\r
449                 private static extern bool DestroyIcon(IntPtr hIcon);\r
450                 \r
451                 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]\r
452                 private struct SHSTOCKICONINFO\r
453                 {\r
454                         public Int32 cbSize;\r
455                         public IntPtr hIcon;\r
456                         public Int32 iSysImageIndex;\r
457                         public Int32 iIcon;\r
458                         [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] public string path;\r
459                 }\r
460                 \r
461                 [DllImport("shell32.dll", CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]\r
462                 private static extern void SHGetStockIconInfo(uint siid, uint uFlags, ref SHSTOCKICONINFO sii);\r
463                 \r
464                 /// <summary>\r
465                 /// アイコンファイル(実行ファイル・DLL)を開いてアイコンを作る\r
466                 /// </summary>\r
467                 /// <remarks>内部でコピーされるのでWin32APIのDestroyIconを使わないでいいが、やや遅い動作</remarks>\r
468                 /// <param name="form">ハンドラ</param>\r
469                 /// <param name="lpszExeFileName">対象ファイル</param>\r
470                 /// <param name="nIconIndex">アイコンインデックス</param>\r
471                 /// <returns>生成されたアイコン</returns>\r
472                 public static Icon ExtractIcon(Form form, string lpszExeFileName, uint nIconIndex)\r
473                 {\r
474                         Icon ico = null;\r
475                         \r
476                         if (! System.IO.File.Exists(lpszExeFileName)) {\r
477                                 ico = Icon.ExtractAssociatedIcon(lpszExeFileName); // ExtractAssociatedIconに例外を吐いてもらう\r
478                         } else {\r
479                                 IntPtr hInst = (form != null)? form.Handle : IntPtr.Zero;\r
480                                 IntPtr hIcon = IntPtr.Zero;\r
481                                 \r
482                                 try {\r
483                                         hIcon = ExtractIcon(hInst, lpszExeFileName, (int) nIconIndex);\r
484                                         if ((hIcon != IntPtr.Zero) && (hIcon.ToInt32() != 2)) {\r
485                                                 ico = (Icon) Icon.FromHandle(hIcon).Clone();\r
486                                                 DestroyIcon(hIcon);\r
487                                         }\r
488                                 } catch (System.Runtime.InteropServices.COMException) {\r
489                                         // ExtraIconのP/Invoke失敗時用\r
490                                 }\r
491                         }\r
492                         return ico;\r
493                 }\r
494                 \r
495                 /// <summary>\r
496                 /// ユーザ昇格が必要か設定し、設定必要なときシールドアイコンを表示する。\r
497                 /// </summary>\r
498                 /// <param name="button">対象のボタン</param>\r
499                 /// <param name="required">ユーザ昇格が必要か否か、すなわちシールドアイコンを表示するか</param>           \r
500                 public static void Button_SetElevationRequiredState(Button button, bool required)\r
501                 {\r
502 #if USE_VISTA_EFFECTS\r
503                         if (Environment.OSVersion.Version.Major >= 6) {\r
504                                 button.FlatStyle = FlatStyle.System;\r
505                                 // SendMessage(hWnd, BCM_SETSHIELD, 0, required);\r
506                                 SendMessage(button.Handle, 0x160C, IntPtr.Zero, new IntPtr((required)? 1u : 0u));\r
507                         } else { // Legacy OS\r
508 #endif\r
509                                 // FlatStyle.System に設定されている場合、Image プロパティに割り当てられているイメージは表示されない対策\r
510                                 if (button.FlatStyle == FlatStyle.System) {\r
511                                         button.FlatStyle = FlatStyle.Standard;\r
512                                 }\r
513                                 \r
514                                 button.TextImageRelation = TextImageRelation.ImageBeforeText;\r
515                                 if (required) {\r
516                                         button.ImageAlign = ContentAlignment.MiddleLeft;\r
517                                         using (Icon ico = new Icon(SystemIcons.Shield, 16, 16)) {\r
518                                                 button.Image = ico.ToBitmap();\r
519                                         }\r
520                                 } else {\r
521                                         button.Image = null;\r
522                                 }\r
523                                 button.AutoSize = true;\r
524 #if USE_VISTA_EFFECTS\r
525                         }\r
526 #endif\r
527                 }\r
528                 \r
529                 /// <summary>\r
530                 /// シェルのソトックアイコンのハンドラを取得する。\r
531                 /// </summary>\r
532                 /// <param name="siid">ストックID</param>\r
533                 /// <param name="isSmall">アイコンサイズは小さいのであればtrueを指定</param>\r
534                 /// <returns>アイコンのハンドラ。存在しない場合、null</returns>\r
535                 private static IntPtr SHGetStockIconHandle(uint siid, bool isSmall)\r
536                 {\r
537 #if USE_VISTA_EFFECTS\r
538                         try {\r
539                                 SHSTOCKICONINFO sii = new SHSTOCKICONINFO();\r
540                                 sii.cbSize = Marshal.SizeOf(typeof(SHSTOCKICONINFO));\r
541                                 sii.hIcon = IntPtr.Zero;\r
542                                 \r
543                                 //SHGetStockIconInfo(siid, SHGFI_ICON | ((isSmall)? SHGFI_SMALLICON : SHGFI_LARGEICON), ref sii);\r
544                                 SHGetStockIconInfo(siid, 0x100u | ((isSmall)? 0x1u : 0x0u), ref sii);\r
545                                 \r
546                                 return sii.hIcon;\r
547                         } catch (Exception) {\r
548                                 return IntPtr.Zero;\r
549                         }\r
550 #else\r
551                         return IntPtr.Zero;\r
552 #endif\r
553                 }\r
554                 \r
555                 /// <summary>\r
556                 /// ユーザ昇格が必要か設定し、設定必要なときシールドアイコンを表示する。\r
557                 /// </summary>\r
558                 /// <param name="label">対象のリンクラベル</param>\r
559                 /// <param name="required">ユーザ昇格が必要か否か、すなわちシールドアイコンを表示するか</param>           \r
560                 public static void LinkLabel_SetElevationRequiredState(LinkLabel label, bool required)\r
561                 {\r
562                         if (required) {\r
563                                 IntPtr iconHandle = IntPtr.Zero;\r
564                                 \r
565                                 //SHGetStockIconHandle(SIID_SHIELD, true);\r
566                                 iconHandle = SHGetStockIconHandle(77, true);\r
567                                 if (iconHandle != IntPtr.Zero) {\r
568                                         label.Image = Bitmap.FromHicon(iconHandle);\r
569                                 } else {\r
570                                         using (Icon ico = new Icon(SystemIcons.Shield, 16, 16)) {\r
571                                                 label.Image = ico.ToBitmap();\r
572                                         }\r
573                                 }\r
574                                 \r
575                                 label.ImageAlign = ContentAlignment.MiddleLeft;\r
576                                 label.Padding = new Padding(label.Image.Width, label.Padding.Top, label.Padding.Right, label.Padding.Bottom);\r
577                         } else {\r
578                                 label.Image = null;\r
579                                 label.Padding = new Padding(0);\r
580                         }\r
581                 }\r
582                 \r
583                 #endregion\r
584                 \r
585                 [DllImport("user32.dll", CharSet = CharSet.Auto)]\r
586                 internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);\r
587                 \r
588                 [DllImport("user32.dll", CharSet=CharSet.Auto)]\r
589                 private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref HD_ITEM lParam);\r
590                 \r
591                 [DllImport("user32.dll", CharSet=CharSet.Auto)]\r
592                 private static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, ref CHARFORMAT2 lParam);\r
593 \r
594                 [DllImport("uxtheme.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]\r
595                 internal static extern int SetWindowTheme(IntPtr hWnd, String pszSubAppName, String pszSubIdList);\r
596                 \r
597                 [Serializable]\r
598                 [StructLayout(LayoutKind.Sequential)]\r
599                 private struct LRECT {\r
600                         public int Left;\r
601                         public int Top;\r
602                         public int Right;\r
603                         public int Bottom;\r
604                 }\r
605                 \r
606                 [DllImport("user32.dll")]\r
607                 private static extern bool GetClientRect(IntPtr hWnd, out LRECT lpRect);\r
608         }\r
609 }\r