OSDN Git Service

AppliStation-GUI,Windows7対応におけるtypoを修正
[applistation/AppliStation.git] / AppliStation / AppliStation.Util / NativeMethods.cs
index 2bd8d06..1aee2ca 100644 (file)
@@ -1,6 +1,9 @@
 // Vistaの効果を有効にするフラグ(不要の場合はコメントアウト)\r
 #define USE_VISTA_EFFECTS\r
 \r
+// Sevenの効果を有効にするフラグ(不要の場合はコメントアウト)\r
+#define USE_SEVEN_EFFECTS\r
+\r
 using System;\r
 using System.Runtime.InteropServices;\r
 using System.Windows.Forms;\r
@@ -20,23 +23,126 @@ namespace AppliStation.Util
                {\r
                }\r
 \r
+               #region 進捗の表示\r
+               \r
                /// <summary>\r
-               /// WindowsVista向け、プログレスバーステータス(色)を設定する\r
+               /// プログレスバーステータス(色)\r
+               /// </summary>\r
+               public enum ProgressBarState\r
+               {\r
+                       /// <summary>\r
+                       /// 通常の状態(PBST_NORMAL)。デフォルトの設定では緑色。\r
+                       /// </summary>\r
+                       Normal = 0,\r
+                       /// <summary>\r
+                       /// エラーの状態(PBST_ERROR)。デフォルトの設定では赤色。\r
+                       /// </summary>\r
+                       Error = 1,\r
+                       /// <summary>\r
+                       /// 停止の状態(PBST_PAUSED)。デフォルトの設定では黄色。\r
+                       /// </summary>\r
+                       Paused = 2,\r
+               }\r
+               \r
+               /// <summary>\r
+               /// WindowsVista以降向け、プログレスバーステータス(色)を設定する。\r
                /// </summary>\r
                /// <param name="progBar">対象のプログレスバー</param>\r
-               /// <param name="state">状態。(1:Normal,2:Error,3:Paused)</param>\r
-               public static void ProgressBar_SetState(ProgressBar progBar, uint state)\r
+               /// <param name="state">状態(色)</param>\r
+               public static void ProgressBar_SetState(ProgressBar progBar, ProgressBarState state)\r
                {\r
 #if USE_VISTA_EFFECTS\r
                        try {\r
-                               // status := (PBST_NORMAL | PBST_ERROR | PBST_PAUSED)\r
                                // SendMessage(progressBar.Handle, PBM_SETSTATE, state, 0);\r
-                               SendMessage(progBar.Handle, 0x410, new IntPtr(state), IntPtr.Zero);\r
+                               SendMessage(progBar.Handle, 0x410, new IntPtr((int) state), IntPtr.Zero);\r
                        } catch (Exception) {\r
                        }\r
 #endif\r
                }\r
                \r
+               #region タスクバー上の進捗表示のためのP/Invoke\r
+                       \r
+               internal enum TBPFLAG\r
+               {\r
+                       TBPF_NOPROGRESS = 0,\r
+                       TBPF_INDETERMINATE = 0x1,\r
+                       TBPF_NORMAL = 0x2,\r
+                       TBPF_ERROR = 0x4,\r
+                       TBPF_PAUSED = 0x8,\r
+               }\r
+               \r
+               [ComImport()]\r
+               [Guid("EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF")]\r
+               [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\r
+               internal interface ITaskList3\r
+               {\r
+                       void HrInit();\r
+                       void AddTab(IntPtr hWnd);\r
+                       void DeleteTab(IntPtr hWnd);\r
+                       void ActivateTab(IntPtr hWnd);\r
+                       void SetActiveAlt(IntPtr hWnd);\r
+                       void MarkFullscreenWindow(IntPtr hWnd, int fFullscreen);\r
+                       void SetProgressValue(IntPtr hWnd, ulong ullCompleted, ulong ullTotal);\r
+                       void SetProgressState(IntPtr hWnd, TBPFLAG tbpFlags);\r
+                       // more functions follows, but we do not need these.\r
+               }\r
+               \r
+               [ComImport()]\r
+               [Guid("56FDF344-FD6D-11d0-958A-006097C9A090")]\r
+               [ClassInterface(ClassInterfaceType.None)]\r
+               internal class CTaskbarList\r
+               {\r
+               }\r
+               \r
+               #endregion\r
+               \r
+               /// <summary>\r
+               /// タスクバに進捗を設定する。\r
+               /// </summary>\r
+               /// <param name="form">対象フォーム</param>\r
+               /// <param name="style">表示スタイル</param>\r
+               /// <param name="state">ステータス(色)</param>\r
+               /// <param name="val">プログレスバーの値。0を指定すると進捗表示をしない</param>\r
+               /// <param name="maximum">プログレスバーの最大値。</param>\r
+               public static void Form_SetTaskbarProgressParams(Form form, ProgressBarStyle style, ProgressBarState state, ulong val, ulong maximum)\r
+               {\r
+#if USE_VISTA_EFFECTS\r
+#if USE_SEVEN_EFFECTS\r
+                       ITaskList3 tasklist = null;\r
+                       \r
+                       try {\r
+                               TBPFLAG tbpFlag = TBPFLAG.TBPF_NOPROGRESS;\r
+                               \r
+                               if (style == ProgressBarStyle.Marquee) {\r
+                                       tbpFlag |= TBPFLAG.TBPF_INDETERMINATE;\r
+                               } else if (val > 0 && maximum > 0) {\r
+                                       tbpFlag |= TBPFLAG.TBPF_NORMAL;\r
+                               }\r
+                               \r
+                               if (state == ProgressBarState.Error) {\r
+                                       tbpFlag |= TBPFLAG.TBPF_ERROR;\r
+                               }\r
+                               if (state == ProgressBarState.Paused) {\r
+                                       tbpFlag |= TBPFLAG.TBPF_PAUSED;\r
+                               }\r
+                               \r
+                               tasklist = (ITaskList3) new CTaskbarList();\r
+                               tasklist.HrInit();\r
+                               \r
+                               tasklist.SetProgressState(form.Handle, tbpFlag);\r
+                               tasklist.SetProgressValue(form.Handle, val, maximum);\r
+                       } finally {\r
+                               if (tasklist != null) {\r
+                                       Marshal.ReleaseComObject(tasklist);\r
+                                       tasklist = null;\r
+                               }\r
+                       }\r
+#endif\r
+#endif\r
+               }\r
+               \r
+               #endregion\r
+                       \r
                #region タスクバーおよびタイトルバーのフラッシュ\r
                \r
                /// <summary>\r
@@ -342,6 +448,18 @@ namespace AppliStation.Util
                [return: MarshalAs(UnmanagedType.Bool)]\r
                private static extern bool DestroyIcon(IntPtr hIcon);\r
                \r
+               [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]\r
+               private struct SHSTOCKICONINFO\r
+               {\r
+                       public Int32 cbSize;\r
+                       public IntPtr hIcon;\r
+                       public Int32 iSysImageIndex;\r
+                       public Int32 iIcon;\r
+                       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] public string path;\r
+               }\r
+               \r
+               [DllImport("shell32.dll", CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]\r
+               private static extern void SHGetStockIconInfo(uint siid, uint uFlags, ref SHSTOCKICONINFO sii);\r
                \r
                /// <summary>\r
                /// アイコンファイル(実行ファイル・DLL)を開いてアイコンを作る\r
@@ -381,11 +499,13 @@ namespace AppliStation.Util
                /// <param name="required">ユーザ昇格が必要か否か、すなわちシールドアイコンを表示するか</param>           \r
                public static void Button_SetElevationRequiredState(Button button, bool required)\r
                {\r
+#if USE_VISTA_EFFECTS\r
                        if (Environment.OSVersion.Version.Major >= 6) {\r
                                button.FlatStyle = FlatStyle.System;\r
                                // SendMessage(hWnd, BCM_SETSHIELD, 0, required);\r
                                SendMessage(button.Handle, 0x160C, IntPtr.Zero, new IntPtr((required)? 1u : 0u));\r
                        } else { // Legacy OS\r
+#endif\r
                                // FlatStyle.System に設定されている場合、Image プロパティに割り当てられているイメージは表示されない対策\r
                                if (button.FlatStyle == FlatStyle.System) {\r
                                        button.FlatStyle = FlatStyle.Standard;\r
@@ -401,6 +521,62 @@ namespace AppliStation.Util
                                        button.Image = null;\r
                                }\r
                                button.AutoSize = true;\r
+#if USE_VISTA_EFFECTS\r
+                       }\r
+#endif\r
+               }\r
+               \r
+               /// <summary>\r
+               /// シェルのソトックアイコンのハンドラを取得する。\r
+               /// </summary>\r
+               /// <param name="siid">ストックID</param>\r
+               /// <param name="isSmall">アイコンサイズは小さいのであればtrueを指定</param>\r
+               /// <returns>アイコンのハンドラ。存在しない場合、null</returns>\r
+               private static IntPtr SHGetStockIconHandle(uint siid, bool isSmall)\r
+               {\r
+#if USE_VISTA_EFFECTS\r
+                       try {\r
+                               SHSTOCKICONINFO sii = new SHSTOCKICONINFO();\r
+                               sii.cbSize = Marshal.SizeOf(typeof(SHSTOCKICONINFO));\r
+                               sii.hIcon = IntPtr.Zero;\r
+                               \r
+                               //SHGetStockIconInfo(siid, SHGFI_ICON | ((isSmall)? SHGFI_SMALLICON : SHGFI_LARGEICON), ref sii);\r
+                               SHGetStockIconInfo(siid, 0x100u | ((isSmall)? 0x1u : 0x0u), ref sii);\r
+                               \r
+                               return sii.hIcon;\r
+                       } catch (Exception) {\r
+                               return IntPtr.Zero;\r
+                       }\r
+#else\r
+                       return IntPtr.Zero;\r
+#endif\r
+               }\r
+               \r
+               /// <summary>\r
+               /// ユーザ昇格が必要か設定し、設定必要なときシールドアイコンを表示する。\r
+               /// </summary>\r
+               /// <param name="label">対象のリンクラベル</param>\r
+               /// <param name="required">ユーザ昇格が必要か否か、すなわちシールドアイコンを表示するか</param>           \r
+               public static void LinkLabel_SetElevationRequiredState(LinkLabel label, bool required)\r
+               {\r
+                       if (required) {\r
+                               IntPtr iconHandle = IntPtr.Zero;\r
+                               \r
+                               //SHGetStockIconHandle(SIID_SHIELD, true);\r
+                               iconHandle = SHGetStockIconHandle(77, true);\r
+                               if (iconHandle != IntPtr.Zero) {\r
+                                       label.Image = Bitmap.FromHicon(iconHandle);\r
+                               } else {\r
+                                       using (Icon ico = new Icon(SystemIcons.Shield, 16, 16)) {\r
+                                               label.Image = ico.ToBitmap();\r
+                                       }\r
+                               }\r
+                               \r
+                               label.ImageAlign = ContentAlignment.MiddleLeft;\r
+                               label.Padding = new Padding(label.Image.Width, label.Padding.Top, label.Padding.Right, label.Padding.Bottom);\r
+                       } else {\r
+                               label.Image = null;\r
+                               label.Padding = new Padding(0);\r
                        }\r
                }\r
                \r